2 * Helpers for implementing a rapid-update counter display in Motif.
3 * Copyright © 2022 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 * A set of functions to implement a simple counter display with better support
21 * for rapid updates than regular XmLabel (and other Motif text display widgets).
23 * This is intended to avoid two specific practical problems with these widgets:
25 * (1) Any update to the text involves dynamic allocation of XmStrings
26 * (2) Updating the text causes the entire label to be redrawn.
28 * Point #2 can lead to annoying flicker on static portions of the label when
29 * updates are occurring continuously.
31 * These functions are intended for displaying strings that consist of non-
32 * changing static text with digits interspersed. Specifically, strings such
33 * as "The time is 12:30:57."
35 * Passing this string as the template argument to xcounter_init will pre-
36 * allocate an XmString values for each of the four maximal nondigit
37 * substrings. These nondigit parts cannot be changed.
39 * On a subsequent call to xcounter_update, a different string may be passed.
40 * The digits in this string are used to construct a sequence of XmString
41 * values that includes the precomputed static portions interspersed with
42 * digits. This new string is expected to be in the same format as the
43 * template although there are two possible exceptions:
45 * - The nondigit substrings do not need to match the template; they are
46 * used only to separate different groups of digits and otherwise have
47 * no effect on the output.
49 * - If the new string may be a prefix of the template, only that portion
50 * will be output. However it is still not possible to alter the static
51 * portions: they are either present in their entirety or omitted.
53 * The xcounter_redraw function can then be used to redraw only the portions of
54 * the string that have changed since the last redraw.
61 * Create xcounter based on template, which should be representative of
62 * the number of digits expected to preallocate a typical number of digits.
64 * Note that the provided template string will be modified by this function,
65 * but restored to its original value before returning.
67 struct xcounter *xcounter_init(Widget w, char *template);
70 * Update xcounter segments according to str.
72 * The nondigit sequences are assumed to match those from the original
75 void xcounter_update(Widget w, struct xcounter *xc, const char *str);
78 * Redraw the counter in response to an expose event.
80 void xcounter_expose(Widget w, struct xcounter *xc, XExposeEvent *e);
83 * Resize and expose callbacks that can be registered on a drawing area widget.
85 void xcounter_resize_cb(Widget w, void *data, void *cb_data);
86 void xcounter_expose_cb(Widget w, void *data, void *cb_data);
88 static inline void xcounter_simple_setup(Widget w, char *template)
90 struct xcounter *xc = xcounter_init(w, template);
92 XtVaSetValues(w, XmNuserData, (void *)xc, (char *)NULL);
93 XtAddCallback(w, XmNresizeCallback, xcounter_resize_cb, xc);
94 XtAddCallback(w, XmNexposeCallback, xcounter_expose_cb, xc);
97 static inline void xcounter_simple_update(Widget w, const char *str)
101 XtVaGetValues(w, XmNuserData, &xc, (char *)NULL);
102 xcounter_update(w, xc, str);