3 Copyright 1990, 1994, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 * Author: Jim Fulton, MIT X Consortium
27 * This widget is used for press-and-hold style buttons.
33 #include <X11/IntrinsicP.h>
34 #include <X11/StringDefs.h>
35 #include <X11/Xaw/RepeaterP.h>
36 #include <X11/Xaw/XawInit.h>
38 #define DO_CALLBACK(rw) \
39 XtCallCallbackList((Widget)rw, rw->command.callbacks, NULL)
41 #define ADD_TIMEOUT(rw, delay) \
42 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)rw), \
43 delay, tic, (XtPointer)rw)
45 #define CLEAR_TIMEOUT(rw) \
46 if ((rw)->repeater.timer) { \
47 XtRemoveTimeOut((rw)->repeater.timer); \
48 (rw)->repeater.timer = 0; \
54 static void XawRepeaterInitialize(Widget, Widget, ArgList, Cardinal*);
55 static void XawRepeaterDestroy(Widget);
56 static Boolean XawRepeaterSetValues(Widget, Widget, Widget,
62 static void tic(XtPointer, XtIntervalId*);
67 static void ActionStart(Widget, XEvent*, String*, Cardinal*);
68 static void ActionStop(Widget, XEvent*, String*, Cardinal*);
73 static char defaultTranslations[] =
74 "<Enter>:" "highlight()\n"
75 "<Leave>:" "unhighlight()\n"
76 "<Btn1Down>:" "set() start()\n"
77 "<Btn1Up>:" "stop() unset()\n"
80 static XtActionsRec actions[] = {
81 {"start", ActionStart},
85 #define offset(field) XtOffsetOf(RepeaterRec, repeater.field)
86 static XtResource resources[] = {
94 (XtPointer)REP_DEF_DECAY
101 offset(initial_delay),
103 (XtPointer)REP_DEF_INITIAL_DELAY
110 offset(minimum_delay),
112 (XtPointer)REP_DEF_MINIMUM_DELAY
119 offset(repeat_delay),
121 (XtPointer)REP_DEF_REPEAT_DELAY
137 offset(start_callbacks),
146 offset(stop_callbacks),
153 #define Superclass (&commandClassRec)
154 RepeaterClassRec repeaterClassRec = {
157 (WidgetClass)Superclass, /* superclass */
158 "Repeater", /* class_name */
159 sizeof(RepeaterRec), /* widget_size */
160 XawInitializeWidgetSet, /* class_initialize */
161 NULL, /* class_part_initialize */
162 False, /* class_inited */
163 XawRepeaterInitialize, /* initialize */
164 NULL, /* initialize_hook */
165 XtInheritRealize, /* realize */
166 actions, /* actions */
167 XtNumber(actions), /* num_actions */
168 resources, /* resources */
169 XtNumber(resources), /* num_resources */
170 NULLQUARK, /* xrm_class */
171 True, /* compress_motion */
172 True, /* compress_exposure */
173 True, /* compress_enterleave */
174 False, /* visible_interest */
175 XawRepeaterDestroy, /* destroy */
176 XtInheritResize, /* resize */
177 XtInheritExpose, /* expose */
178 XawRepeaterSetValues, /* set_values */
179 NULL, /* set_values_hook */
180 XtInheritSetValuesAlmost, /* set_values_almost */
181 NULL, /* get_values_hook */
182 NULL, /* accept_focus */
183 XtVersion, /* version */
184 NULL, /* callback_private */
185 defaultTranslations, /* tm_table */
186 XtInheritQueryGeometry, /* query_geometry */
187 XtInheritDisplayAccelerator, /* display_accelerator */
188 NULL, /* extension */
192 XtInheritChangeSensitive, /* change_sensitive */
196 NULL, /* extension */
200 NULL, /* extension */
204 NULL, /* extension */
208 WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
216 tic(XtPointer client_data, XtIntervalId *id)
218 RepeaterWidget rw = (RepeaterWidget)client_data;
220 rw->repeater.timer = 0; /* timer is removed */
221 if (rw->repeater.flash) {
222 Widget w = (Widget)rw;
224 XClearWindow(XtDisplay(w), XtWindow(w));
225 XtCallActionProc(w, "reset", NULL, NULL, 0);
226 XClearWindow(XtDisplay(w), XtWindow(w));
227 XtCallActionProc(w, "set", NULL, NULL, 0);
231 rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.next_delay);
233 if (rw->repeater.decay) {
234 rw->repeater.next_delay -= rw->repeater.decay;
235 if (rw->repeater.next_delay < rw->repeater.minimum_delay)
236 rw->repeater.next_delay = rw->repeater.minimum_delay;
242 XawRepeaterInitialize(Widget greq, Widget gnew,
243 ArgList args, Cardinal *num_args)
245 RepeaterWidget cnew = (RepeaterWidget)gnew;
247 if (cnew->repeater.minimum_delay < 0)
248 cnew->repeater.minimum_delay = 0;
249 cnew->repeater.timer = 0;
253 XawRepeaterDestroy(Widget gw)
255 CLEAR_TIMEOUT((RepeaterWidget)gw);
260 XawRepeaterSetValues(Widget gcur, Widget greq, Widget gnew,
261 ArgList args, Cardinal *num_args)
263 RepeaterWidget cur = (RepeaterWidget)gcur;
264 RepeaterWidget cnew = (RepeaterWidget)gnew;
266 if (cur->repeater.minimum_delay != cnew->repeater.minimum_delay) {
267 if (cnew->repeater.next_delay < cnew->repeater.minimum_delay)
268 cnew->repeater.next_delay = cnew->repeater.minimum_delay;
276 ActionStart(Widget gw, XEvent *event, String *params, Cardinal *num_params)
278 RepeaterWidget rw = (RepeaterWidget)gw;
281 if (rw->repeater.start_callbacks)
282 XtCallCallbackList(gw, rw->repeater.start_callbacks, NULL);
285 rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.initial_delay);
286 rw->repeater.next_delay = rw->repeater.repeat_delay;
291 ActionStop(Widget gw, XEvent *event, String *params, Cardinal *num_params)
293 RepeaterWidget rw = (RepeaterWidget)gw;
295 CLEAR_TIMEOUT((RepeaterWidget)gw);
296 if (rw->repeater.stop_callbacks)
297 XtCallCallbackList(gw, rw->repeater.stop_callbacks, NULL);