upload tizen2.0 source
[framework/uifw/xorg/lib/libxaw.git] / src / Repeater.c
1 /*
2  *
3 Copyright 1990, 1994, 1998  The Open Group
4
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
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
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.
20
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.
24  *
25  * Author:  Jim Fulton, MIT X Consortium
26  *
27  * This widget is used for press-and-hold style buttons.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 #include <X11/IntrinsicP.h>
34 #include <X11/StringDefs.h>
35 #include <X11/Xaw/RepeaterP.h>
36 #include <X11/Xaw/XawInit.h>
37
38 #define DO_CALLBACK(rw) \
39 XtCallCallbackList((Widget)rw, rw->command.callbacks, NULL)
40
41 #define ADD_TIMEOUT(rw, delay)                                  \
42 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)rw),       \
43                 delay, tic, (XtPointer)rw)
44
45 #define CLEAR_TIMEOUT(rw) \
46 if ((rw)->repeater.timer) {                     \
47     XtRemoveTimeOut((rw)->repeater.timer);      \
48     (rw)->repeater.timer = 0;                   \
49 }
50
51 /*
52  * Class Methods
53  */
54 static void XawRepeaterInitialize(Widget, Widget, ArgList, Cardinal*);
55 static void XawRepeaterDestroy(Widget);
56 static Boolean XawRepeaterSetValues(Widget, Widget, Widget,
57                                     ArgList, Cardinal*);
58
59 /*
60  * Prototypes
61  */
62 static void tic(XtPointer, XtIntervalId*);
63
64 /*
65  * Actions
66  */
67 static void ActionStart(Widget, XEvent*, String*, Cardinal*);
68 static void ActionStop(Widget, XEvent*, String*, Cardinal*);
69
70 /*
71  * Initialization
72  */
73 static char defaultTranslations[] =
74 "<Enter>:"      "highlight()\n"
75 "<Leave>:"      "unhighlight()\n"
76 "<Btn1Down>:"   "set() start()\n"
77 "<Btn1Up>:"     "stop() unset()\n"
78 ;
79
80 static XtActionsRec actions[] = {
81   {"start",     ActionStart},
82   {"stop",      ActionStop},
83 };
84
85 #define offset(field)   XtOffsetOf(RepeaterRec, repeater.field)
86 static XtResource resources[] = {
87   {
88     XtNdecay,
89     XtCDecay,
90     XtRInt,
91     sizeof(int),
92     offset(decay),
93     XtRImmediate,
94     (XtPointer)REP_DEF_DECAY
95   },
96   {
97     XtNinitialDelay,
98     XtCDelay,
99     XtRInt,
100     sizeof(int),
101     offset(initial_delay),
102     XtRImmediate,
103     (XtPointer)REP_DEF_INITIAL_DELAY
104   },
105   {
106     XtNminimumDelay,
107     XtCMinimumDelay,
108     XtRInt,
109     sizeof(int),
110     offset(minimum_delay),
111     XtRImmediate,
112     (XtPointer)REP_DEF_MINIMUM_DELAY
113   },
114   {
115     XtNrepeatDelay,
116     XtCDelay,
117     XtRInt,
118     sizeof(int),
119     offset(repeat_delay),
120     XtRImmediate,
121     (XtPointer)REP_DEF_REPEAT_DELAY
122   },
123   {
124     XtNflash,
125     XtCBoolean,
126     XtRBoolean,
127     sizeof(Boolean),
128     offset(flash),
129     XtRImmediate,
130     (XtPointer)False
131   },
132   {
133     XtNstartCallback,
134     XtCStartCallback,
135     XtRCallback,
136     sizeof(XtPointer),
137     offset(start_callbacks),
138     XtRImmediate,
139     NULL
140   },
141   {
142     XtNstopCallback,
143     XtCStopCallback,
144     XtRCallback,
145     sizeof(XtPointer),
146     offset(stop_callbacks),
147     XtRImmediate,
148     NULL
149   },
150 };
151 #undef offset
152
153 #define Superclass      (&commandClassRec)
154 RepeaterClassRec repeaterClassRec = {
155   /* core */
156   {
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 */
189   },
190   /* simple */
191   {
192     XtInheritChangeSensitive,           /* change_sensitive */
193   },
194   /* label */
195   {
196     NULL,                               /* extension */
197   },
198   /* command */
199   {
200     NULL,                               /* extension */
201   },
202   /* repeater */
203   {
204     NULL,                               /* extension */
205   },
206 };
207
208 WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
209
210
211 /*
212  * Implementation
213  */
214 /*ARGSUSED*/
215 static void
216 tic(XtPointer client_data, XtIntervalId *id)
217 {
218     RepeaterWidget rw = (RepeaterWidget)client_data;
219
220     rw->repeater.timer = 0;             /* timer is removed */
221     if (rw->repeater.flash) {
222         Widget w = (Widget)rw;
223
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);
228     }
229     DO_CALLBACK(rw);
230
231     rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.next_delay);
232
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;
237     }
238 }
239
240 /*ARGSUSED*/
241 static void
242 XawRepeaterInitialize(Widget greq, Widget gnew,
243                       ArgList args, Cardinal *num_args)
244 {
245     RepeaterWidget cnew = (RepeaterWidget)gnew;
246
247     if (cnew->repeater.minimum_delay < 0)
248         cnew->repeater.minimum_delay = 0;
249     cnew->repeater.timer = 0;
250 }
251
252 static void
253 XawRepeaterDestroy(Widget gw)
254 {
255     CLEAR_TIMEOUT((RepeaterWidget)gw);
256 }
257
258 /*ARGSUSED*/
259 static Boolean
260 XawRepeaterSetValues(Widget gcur, Widget greq, Widget gnew,
261                      ArgList args, Cardinal *num_args)
262 {
263     RepeaterWidget cur = (RepeaterWidget)gcur;
264     RepeaterWidget cnew = (RepeaterWidget)gnew;
265
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;
269     }
270
271     return (False);
272 }
273
274 /*ARGSUSED*/
275 static void
276 ActionStart(Widget gw, XEvent *event, String *params, Cardinal *num_params)
277 {
278     RepeaterWidget rw = (RepeaterWidget)gw;
279
280     CLEAR_TIMEOUT(rw);
281     if (rw->repeater.start_callbacks)
282         XtCallCallbackList(gw, rw->repeater.start_callbacks, NULL);
283
284     DO_CALLBACK(rw);
285     rw->repeater.timer = ADD_TIMEOUT(rw, rw->repeater.initial_delay);
286     rw->repeater.next_delay = rw->repeater.repeat_delay;
287 }
288
289 /*ARGSUSED*/
290 static void
291 ActionStop(Widget gw, XEvent *event, String *params, Cardinal *num_params)
292 {
293     RepeaterWidget rw = (RepeaterWidget)gw;
294
295     CLEAR_TIMEOUT((RepeaterWidget)gw);
296     if (rw->repeater.stop_callbacks)
297         XtCallCallbackList(gw, rw->repeater.stop_callbacks, NULL);
298 }