1 /***************************************************************************/
2 /* This code is part of X-toolkit widget library called Nws */
3 /* Copyright (c) 1997,1998,1999 Ondrejicka Stefan */
4 /* (ondrej@idata.sk) */
5 /* Distributed under GPL 2 or later */
6 /***************************************************************************/
7
8 #include <X11/IntrinsicP.h>
9 #include <X11/StringDefs.h>
10 #include <X11/Xlib.h>
11
12 #include "MwSButtonP.h"
13 #include "MwNws.h"
14
15 #define offset(field) XtOffsetOf(MwSButtonRec,sButton.field)
16
17 static XtResource resources [] = {
18 {
19 XtNcallback ,
20 XtCCallback ,
21 XtRCallback ,
22 sizeof(XtCallbackList) ,
23 offset(activate) ,
24 XtRCallback ,
25 (XtPointer) NULL
26 },
27 {
28 XtNswitch ,
29 XtCSwitch ,
30 XtRCallback ,
31 sizeof(XtCallbackList) ,
32 offset(switchcb) ,
33 XtRCallback ,
34 (XtPointer) NULL
35 },
36 {
37 XtNbuttonMode,
38 XtCButtonMode,
39 XtRButtonMode,
40 sizeof(int),
41 offset(mode),
42 XtRImmediate,
43 (XtPointer) XtCnormalMode,
44 },
45 {
46 XtNinitDelay,
47 XtCInitDelay,
48 XtRCardinal,
49 sizeof(Cardinal),
50 offset(init_delay),
51 XtRImmediate,
52 (XtPointer)500,
53 },
54 {
55 XtNrepeatDelay,
56 XtCRepeatDelay,
57 XtRCardinal,
58 sizeof(Cardinal),
59 offset(repeat_delay),
60 XtRImmediate,
61 (XtPointer)100,
62 },
63 {
64 XtNhighlight_on_enter ,
65 XtCHighlight_on_enter ,
66 XtRBoolean ,
67 sizeof(Boolean) ,
68 XtOffsetOf(MwSButtonRec,base.highlight_on_enter) ,
69 XtRImmediate ,
70 (XtPointer) True
71 },
72 {
73 XtNbox_type ,
74 XtCBox_type ,
75 XtRBox_type ,
76 sizeof(int) ,
77 XtOffsetOf(MwSButtonRec,base.box_type) ,
78 XtRImmediate ,
79 (XtPointer) XtCup_box
80 },
81 {
82 XtNon ,
83 XtCOn ,
84 XtRBoolean ,
85 sizeof(Boolean) ,
86 offset(on) ,
87 XtRImmediate ,
88 (XtPointer) False
89 },
90 };
91
92 #undef offset
93
94 static void ClassInitialize(void);
95 static void Initialize (Widget, Widget, ArgList, Cardinal *);
96
97 static void deactivate_t (Widget, XEvent *, String *, Cardinal *);
98 static void activate_t (Widget, XEvent *, String *, Cardinal *);
99 static void KBactivate (Widget, XEvent *, String *, Cardinal *);
100 static void timerCB (XtPointer, XtIntervalId *);
101 static void Enter_Leave (Widget, XEvent *, String *, Cardinal *);
102 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
103
104 static XtActionsRec action [] = {
105 {"activate",activate_t},
106 {"deactivate",deactivate_t},
107 {"KBactivate",KBactivate},
108 {"enter_leave",Enter_Leave},
109 };
110
111 static char trans_tab [] =
112 "\
113 <FocusIn>: focusIn()\n\
114 <FocusOut>: focusOut()\n\
115 ~Shift<Key>Tab: traverseForward()\n\
116 Shift<Key>Tab: traverseBackward()\n\
117 <Key>Return: KBactivate()\n\
118 <Key>space: KBactivate()\n\
119 <Btn1Down>: hide_help() activate() \n\
120 <Btn1Up>: deactivate() \n\
121 <Enter>: enter_leave() highlight() show_help() \n\
122 <Leave>: enter_leave() unhighlight() hide_help() \n\
123 <BtnDown>: hide_help() \n\
124 <KeyDown>: hide_help() \n\
125 ";
126
127 MwSButtonClassRec mwSButtonClassRec = {
128 /* core */
129 {
130 /* superclass */ (WidgetClass) &mwBaseClassRec,
131 /* class_name */ "MwSButton",
132 /* widget_size */ sizeof(MwSButtonRec),
133 /* class_initialize */ ClassInitialize,
134 /* class_part_initialize */ NULL,
135 /* class_inited */ FALSE,
136 /* initialize */ (XtInitProc) Initialize,
137 /* initialize_hook */ NULL,
138 /* realize */ XtInheritRealize,
139 /* actions */ action,
140 /* num_actions */ XtNumber(action),
141 /* resources */ resources,
142 /* num_resources */ XtNumber(resources),
143 /* xrm_class */ NULLQUARK,
144 /* compress_motion */ TRUE,
145 /* compress_exposure */ TRUE,
146 /* compress_enterleave */ TRUE,
147 /* visible_interest */ FALSE,
148 /* destroy */ NULL,
149 /* resize */ XtInheritResize,
150 /* expose */ XtInheritExpose,
151 /* set_values */ SetValues,
152 /* set_values_hook */ NULL,
153 /* set_values_almost */ XtInheritSetValuesAlmost,
154 /* get_values_hook */ NULL,
155 /* accept_focus */ XtInheritAcceptFocus,
156 /* version */ XtVersion,
157 /* callback_private */ NULL,
158 /* tm_table */ trans_tab,
159 /* query_geometry */ XtInheritQueryGeometry,
160 /* display_accelerator */ XtInheritDisplayAccelerator,
161 /* extension */ NULL
162 },
163 /* base */
164 {
165 /* get_internal_dimension */ XtInheritGetInternalDimension,
166 /* set_internal_dimension */ XtInheritSetInternalDimension,
167 /* highlight */ XtInheritHighlight,
168 /* unhighlight */ XtInheritUnhighlight,
169 /* highlightBorder */ XtInheritHighlightBorder,
170 /* unhighlightBorder */ XtInheritUnhighlightBorder,
171 },
172 /* sButton */
173 {
174 /* empty */ 0
175 }
176 };
177
178 WidgetClass mwSButtonWidgetClass = (WidgetClass) & mwSButtonClassRec;
179
ClassInitialize(void)180 static void ClassInitialize(void)
181 {
182 _InitializeWidgetSet();
183
184 XtSetTypeConverter(XtRString, XtRButtonMode, cvtStringToButtonMode,
185 NULL, 0, XtCacheNone, NULL);
186 }
187
Initialize(Widget req_widget,Widget new_widget,ArgList args,Cardinal * num_args)188 static void Initialize(Widget req_widget, Widget new_widget,
189 ArgList args, Cardinal *num_args)
190 {
191 MwSButtonWidget nw = (MwSButtonWidget) new_widget;
192
193 if (nw->sButton.mode == XtCtoggleMode)
194 {
195 if (nw->sButton.on)
196 {
197 nw->sButton.pressed = True;
198 nw->base.box_type = XtCdown_box;
199 }
200 else
201 {
202 nw->sButton.pressed = False;
203 nw->base.box_type = XtCup_box;
204 }
205 }
206 else nw->sButton.pressed = False;
207 }
208
SetValues(Widget current,Widget request,Widget new_widget,ArgList args,Cardinal * num_args)209 static Boolean SetValues(Widget current, Widget request, Widget new_widget,
210 ArgList args, Cardinal *num_args)
211 {
212 MwSButtonWidget nw = (MwSButtonWidget) new_widget;
213 MwSButtonWidget cw = (MwSButtonWidget) current;
214 Boolean redraw = False;
215
216 if (nw->sButton.mode == XtCtoggleMode && (cw->sButton.on != nw->sButton.on ||
217 cw->sButton.mode != nw->sButton.mode))
218 {
219 if (nw->sButton.on)
220 nw->base.box_type = XtCdown_box;
221 else
222 nw->base.box_type = XtCup_box;
223
224 redraw = True;
225 }
226
227 return redraw;
228 }
229
KBactivate(Widget sw,XEvent * event,String * params,Cardinal * num_params)230 static void KBactivate(Widget sw, XEvent *event,
231 String *params, Cardinal *num_params)
232 {
233 MwSButtonWidget w = (MwSButtonWidget)sw;
234 if (w->sButton.mode == XtCtoggleMode)
235 {
236 w->sButton.on = !w->sButton.on;
237
238 if (w->sButton.on)
239 {
240 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
241 }
242 else
243 {
244 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
245 }
246
247 XtCallCallbackList((Widget)w , w->sButton.switchcb , NULL);
248 }
249 else
250 {
251 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
252
253 XtCallCallbackList((Widget)w, w->sButton.activate, NULL);
254
255 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
256 }
257 }
258
Enter_Leave(Widget sw,XEvent * event,String * params,Cardinal * num_params)259 static void Enter_Leave (Widget sw, XEvent *event,
260 String *params, Cardinal *num_params)
261 {
262 MwSButtonWidget w = (MwSButtonWidget)sw;
263 if (w->sButton.mode == XtCcyclicMode) return;
264
265 if (w->sButton.mode == XtCnormalMode)
266 {
267 if ( (w->sButton.pressed) &&
268 (event->type == LeaveNotify))
269 {
270 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
271
272 w->sButton.pressed = False;
273 }
274 else if ((event->type == EnterNotify) &&
275 (event->xcrossing.state & Button1Mask))
276 {
277 w->sButton.pressed = True;
278
279 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
280 }
281 }
282 else
283 {
284 if ((w->sButton.pressed) &&
285 (event->type == LeaveNotify))
286 {
287 if (w->sButton.on)
288 {
289 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
290 }
291 else
292 {
293 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
294 }
295
296 w->sButton.pressed = False;
297 }
298 else if ((event->type == EnterNotify) &&
299 (event->xcrossing.state & Button1Mask))
300 {
301 if (w->sButton.on)
302 {
303 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
304 }
305 else
306 {
307 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
308 }
309 w->sButton.pressed = True;
310 }
311 }
312 }
313
activate_t(Widget sw,XEvent * event,String * params,Cardinal * num_params)314 static void activate_t(Widget sw , XEvent *event ,
315 String *params , Cardinal *num_params)
316 {
317 MwSButtonWidget w = (MwSButtonWidget)sw;
318 if (w->sButton.mode == XtCcyclicMode)
319 {
320 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
321
322 XtCallCallbackList((Widget)w, w->sButton.activate, NULL);
323
324 w->sButton.timer = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)w),
325 w->sButton.init_delay, timerCB, w);
326 }
327 else if (w->sButton.mode == XtCnormalMode)
328 {
329 w->sButton.pressed = True;
330
331 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
332 }
333 else if (w->sButton.mode == XtCtoggleMode)
334 {
335 if (w->sButton.on)
336 {
337 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
338 }
339 else
340 {
341 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
342 }
343 w->sButton.pressed = True;
344 }
345 }
346
347
deactivate_t(Widget sw,XEvent * event,String * params,Cardinal * num_params)348 static void deactivate_t(Widget sw , XEvent *event ,
349 String *params , Cardinal *num_params)
350 {
351 MwSButtonWidget w = (MwSButtonWidget)sw;
352 if (w->sButton.mode == XtCcyclicMode)
353 {
354 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
355
356 XtRemoveTimeOut(w->sButton.timer);
357 }
358 else if (w->sButton.mode == XtCnormalMode)
359 {
360 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
361
362 XFlush(XtDisplay((Widget)w));
363
364 if (w->sButton.pressed)
365 XtCallCallbackList((Widget)w,w->sButton.activate, NULL);
366
367 w->sButton.pressed = False;
368 }
369 else if (w->sButton.mode == XtCtoggleMode)
370 {
371 if (w->sButton.pressed)
372 {
373 w->sButton.on = !w->sButton.on;
374
375 if (w->sButton.on)
376 {
377 w->sButton.pressed = False;
378 XtVaSetValues((Widget)w , XtNbox_type , XtCdown_box , NULL);
379 }
380 else
381 {
382 w->sButton.pressed = False;
383 XtVaSetValues((Widget)w , XtNbox_type , XtCup_box , NULL);
384 }
385
386 XtCallCallbackList((Widget)w , w->sButton.switchcb , NULL);
387
388 }
389 }
390 }
391
392
timerCB(XtPointer client_data,XtIntervalId * timer)393 static void timerCB(XtPointer client_data, XtIntervalId *timer)
394 {
395 MwSButtonWidget w = (MwSButtonWidget) client_data;
396
397
398 XtCallCallbackList((Widget) w, w->sButton.activate, NULL);
399
400
401 w->sButton.timer = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)w),
402 w->sButton.repeat_delay, timerCB, w);
403 }
404