gtk+3: fix dependencies for new gnome/accessibility/at-spi2-core
[oi-userland.git] / components / x11 / libXaw5 / src / Toggle.c
blob6cda9dc44214d4333022042204bde235a8ddc783
1 /* $XConsortium: Toggle.c,v 1.28 94/04/17 20:13:17 kaleb Exp $ */
3 /*
5 Copyright (c) 1989, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
31 * Toggle.c - Toggle button widget
33 * Author: Chris D. Peterson
34 * MIT X Consortium
35 * kit@expo.lcs.mit.edu
37 * Date: January 12, 1989
41 #include <stdio.h>
43 #include <X11/IntrinsicP.h>
44 #include <X11/StringDefs.h>
45 #include <X11/Xaw/XawInit.h>
46 #include <X11/Xmu/Converters.h>
47 #include <X11/Xmu/Misc.h>
48 #include <X11/Xaw/ToggleP.h>
50 /****************************************************************
52 * Full class record constant
54 ****************************************************************/
56 /* Private Data */
58 /*
59 * The order of toggle and notify are important, as the state has
60 * to be set when we call the notify proc.
63 static char defaultTranslations[] =
64 "<EnterWindow>: highlight(Always) \n\
65 <LeaveWindow>: unhighlight() \n\
66 <Btn1Down>,<Btn1Up>: toggle() notify()";
68 #define offset(field) XtOffsetOf(ToggleRec, field)
70 static XtResource resources[] = {
71 {XtNstate, XtCState, XtRBoolean, sizeof(Boolean),
72 offset(command.set), XtRString, "off"},
73 {XtNradioGroup, XtCWidget, XtRWidget, sizeof(Widget),
74 offset(toggle.widget), XtRWidget, (XtPointer) NULL },
75 {XtNradioData, XtCRadioData, XtRPointer, sizeof(XtPointer),
76 offset(toggle.radio_data), XtRPointer, (XtPointer) NULL },
79 #undef offset
82 static void Toggle(), Initialize(), Notify(), ToggleSet();
83 static void ToggleDestroy(), ClassInit();
84 static Boolean SetValues();
86 /* Functions for handling the Radio Group. */
88 static RadioGroup * GetRadioGroup();
89 static void CreateRadioGroup(), AddToRadioGroup(), TurnOffRadioSiblings();
90 static void RemoveFromRadioGroup();
92 static XtActionsRec actionsList[] =
94 {"toggle", Toggle},
95 {"notify", Notify},
96 {"set", ToggleSet},
99 #define SuperClass ((CommandWidgetClass)&commandClassRec)
101 ToggleClassRec toggleClassRec = {
103 (WidgetClass) SuperClass, /* superclass */
104 "Toggle", /* class_name */
105 sizeof(ToggleRec), /* size */
106 ClassInit, /* class_initialize */
107 NULL, /* class_part_initialize */
108 FALSE, /* class_inited */
109 Initialize, /* initialize */
110 NULL, /* initialize_hook */
111 XtInheritRealize, /* realize */
112 actionsList, /* actions */
113 XtNumber(actionsList), /* num_actions */
114 resources, /* resources */
115 XtNumber(resources), /* resource_count */
116 NULLQUARK, /* xrm_class */
117 FALSE, /* compress_motion */
118 TRUE, /* compress_exposure */
119 TRUE, /* compress_enterleave */
120 FALSE, /* visible_interest */
121 NULL, /* destroy */
122 XtInheritResize, /* resize */
123 XtInheritExpose, /* expose */
124 SetValues, /* set_values */
125 NULL, /* set_values_hook */
126 XtInheritSetValuesAlmost, /* set_values_almost */
127 NULL, /* get_values_hook */
128 NULL, /* accept_focus */
129 XtVersion, /* version */
130 NULL, /* callback_private */
131 defaultTranslations, /* tm_table */
132 XtInheritQueryGeometry, /* query_geometry */
133 XtInheritDisplayAccelerator, /* display_accelerator */
134 NULL /* extension */
135 }, /* CoreClass fields initialization */
137 XtInheritChangeSensitive /* change_sensitive */
138 }, /* SimpleClass fields initialization */
140 0 /* field not used */
141 }, /* LabelClass fields initialization */
143 0 /* field not used */
144 }, /* CommandClass fields initialization */
146 NULL, /* Set Procedure. */
147 NULL, /* Unset Procedure. */
148 NULL /* extension. */
149 } /* ToggleClass fields initialization */
152 /* for public consumption */
153 WidgetClass toggleWidgetClass = (WidgetClass) &toggleClassRec;
155 /****************************************************************
157 * Private Procedures
159 ****************************************************************/
161 static void
162 ClassInit()
164 XtActionList actions;
165 Cardinal num_actions;
166 Cardinal i;
167 ToggleWidgetClass class = (ToggleWidgetClass) toggleWidgetClass;
168 static XtConvertArgRec parentCvtArgs[] = {
169 {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
170 sizeof(Widget)}
173 XawInitializeWidgetSet();
174 XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget,
175 parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone,
176 (XtDestructor)NULL);
178 * Find the set and unset actions in the command widget's action table.
181 XtGetActionList(commandWidgetClass, &actions, &num_actions);
183 for (i = 0 ; i < num_actions ; i++) {
184 if (streq(actions[i].string, "set"))
185 class->toggle_class.Set = actions[i].proc;
186 if (streq(actions[i].string, "unset"))
187 class->toggle_class.Unset = actions[i].proc;
189 if ( (class->toggle_class.Set != NULL) &&
190 (class->toggle_class.Unset != NULL) ) {
191 XtFree((char *) actions);
192 return;
196 /* We should never get here. */
197 XtError("Aborting, due to errors resolving bindings in the Toggle widget.");
200 /*ARGSUSED*/
201 static void Initialize(request, new, args, num_args)
202 Widget request, new;
203 ArgList args;
204 Cardinal *num_args;
206 ToggleWidget tw = (ToggleWidget) new;
207 ToggleWidget tw_req = (ToggleWidget) request;
209 tw->toggle.radio_group = NULL;
211 if (tw->toggle.radio_data == NULL)
212 tw->toggle.radio_data = (XtPointer) new->core.name;
214 if (tw->toggle.widget != NULL) {
215 if ( GetRadioGroup(tw->toggle.widget) == NULL)
216 CreateRadioGroup(new, tw->toggle.widget);
217 else
218 AddToRadioGroup( GetRadioGroup(tw->toggle.widget), new);
220 XtAddCallback(new, XtNdestroyCallback, ToggleDestroy, (XtPointer)NULL);
223 * Command widget assumes that the widget is unset, so we only
224 * have to handle the case where it needs to be set.
226 * If this widget is in a radio group then it may cause another
227 * widget to be unset, thus calling the notify proceedure.
229 * I want to set the toggle if the user set the state to "On" in
230 * the resource group, reguardless of what my ancestors did.
233 if (tw_req->command.set)
234 ToggleSet(new, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
237 /************************************************************
239 * Action Procedures
241 ************************************************************/
243 /* ARGSUSED */
244 static void
245 ToggleSet(w,event,params,num_params)
246 Widget w;
247 XEvent *event;
248 String *params; /* unused */
249 Cardinal *num_params; /* unused */
251 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
253 TurnOffRadioSiblings(w);
254 class->toggle_class.Set(w, event, NULL, 0);
257 /* ARGSUSED */
258 static void
259 Toggle(w,event,params,num_params)
260 Widget w;
261 XEvent *event;
262 String *params; /* unused */
263 Cardinal *num_params; /* unused */
265 ToggleWidget tw = (ToggleWidget)w;
266 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
268 if (tw->command.set)
269 class->toggle_class.Unset(w, event, NULL, 0);
270 else
271 ToggleSet(w, event, params, num_params);
274 /* ARGSUSED */
275 static void Notify(w,event,params,num_params)
276 Widget w;
277 XEvent *event;
278 String *params; /* unused */
279 Cardinal *num_params; /* unused */
281 ToggleWidget tw = (ToggleWidget) w;
282 long antilint = tw->command.set;
284 XtCallCallbacks( w, XtNcallback, (XtPointer) antilint );
287 /************************************************************
289 * Set specified arguments into widget
291 ***********************************************************/
293 /* ARGSUSED */
294 static Boolean
295 SetValues (current, request, new, args, num_args)
296 Widget current, request, new;
297 ArgList args;
298 Cardinal *num_args;
300 ToggleWidget oldtw = (ToggleWidget) current;
301 ToggleWidget tw = (ToggleWidget) new;
302 ToggleWidget rtw = (ToggleWidget) request;
304 if (oldtw->toggle.widget != tw->toggle.widget)
305 XawToggleChangeRadioGroup(new, tw->toggle.widget);
307 if (!tw->core.sensitive && oldtw->core.sensitive && rtw->command.set)
308 tw->command.set = True;
310 if (oldtw->command.set != tw->command.set) {
311 tw->command.set = oldtw->command.set;
312 Toggle(new, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
314 return(FALSE);
317 /* Function Name: ToggleDestroy
318 * Description: Destroy Callback for toggle widget.
319 * Arguments: w - the toggle widget that is being destroyed.
320 * junk, grabage - not used.
321 * Returns: none.
324 /* ARGSUSED */
325 static void
326 ToggleDestroy(w, junk, garbage)
327 Widget w;
328 XtPointer junk, garbage;
330 RemoveFromRadioGroup(w);
333 /************************************************************
335 * Below are all the private procedures that handle
336 * radio toggle buttons.
338 ************************************************************/
340 /* Function Name: GetRadioGroup
341 * Description: Gets the radio group associated with a give toggle
342 * widget.
343 * Arguments: w - the toggle widget who's radio group we are getting.
344 * Returns: the radio group associated with this toggle group.
347 static RadioGroup *
348 GetRadioGroup(w)
349 Widget w;
351 ToggleWidget tw = (ToggleWidget) w;
353 if (tw == NULL) return(NULL);
354 return( tw->toggle.radio_group );
357 /* Function Name: CreateRadioGroup
358 * Description: Creates a radio group. give two widgets.
359 * Arguments: w1, w2 - the toggle widgets to add to the radio group.
360 * Returns: none.
362 * NOTE: A pointer to the group is added to each widget's radio_group
363 * field.
366 static void
367 CreateRadioGroup(w1, w2)
368 Widget w1, w2;
370 char error_buf[BUFSIZ];
371 ToggleWidget tw1 = (ToggleWidget) w1;
372 ToggleWidget tw2 = (ToggleWidget) w2;
374 if ( (tw1->toggle.radio_group != NULL) || (tw2->toggle.radio_group != NULL) ) {
375 (void) sprintf(error_buf, "%s %s", "Toggle Widget Error - Attempting",
376 "to create a new toggle group, when one already exists.");
377 XtWarning(error_buf);
380 AddToRadioGroup( (RadioGroup *)NULL, w1 );
381 AddToRadioGroup( GetRadioGroup(w1), w2 );
384 /* Function Name: AddToRadioGroup
385 * Description: Adds a toggle to the radio group.
386 * Arguments: group - any element of the radio group the we are adding to.
387 * w - the new toggle widget to add to the group.
388 * Returns: none.
391 static void
392 AddToRadioGroup(group, w)
393 RadioGroup * group;
394 Widget w;
396 ToggleWidget tw = (ToggleWidget) w;
397 RadioGroup * local;
399 local = (RadioGroup *) XtMalloc( sizeof(RadioGroup) );
400 local->widget = w;
401 tw->toggle.radio_group = local;
403 if (group == NULL) { /* Creating new group. */
404 group = local;
405 group->next = NULL;
406 group->prev = NULL;
407 return;
409 local->prev = group; /* Adding to previous group. */
410 if ((local->next = group->next) != NULL)
411 local->next->prev = local;
412 group->next = local;
415 /* Function Name: TurnOffRadioSiblings
416 * Description: Deactivates all radio siblings.
417 * Arguments: widget - a toggle widget.
418 * Returns: none.
421 static void
422 TurnOffRadioSiblings(w)
423 Widget w;
425 RadioGroup * group;
426 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
428 if ( (group = GetRadioGroup(w)) == NULL) /* Punt if there is no group */
429 return;
431 /* Go to the top of the group. */
433 for ( ; group->prev != NULL ; group = group->prev );
435 while ( group != NULL ) {
436 ToggleWidget local_tog = (ToggleWidget) group->widget;
437 if ( local_tog->command.set ) {
438 class->toggle_class.Unset(group->widget, NULL, NULL, 0);
439 Notify( group->widget, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
441 group = group->next;
445 /* Function Name: RemoveFromRadioGroup
446 * Description: Removes a toggle from a RadioGroup.
447 * Arguments: w - the toggle widget to remove.
448 * Returns: none.
451 static void
452 RemoveFromRadioGroup(w)
453 Widget w;
455 RadioGroup * group = GetRadioGroup(w);
456 if (group != NULL) {
457 if (group->prev != NULL)
458 (group->prev)->next = group->next;
459 if (group->next != NULL)
460 (group->next)->prev = group->prev;
461 XtFree((char *) group);
465 /************************************************************
467 * Public Routines
469 ************************************************************/
471 /* Function Name: XawToggleChangeRadioGroup
472 * Description: Allows a toggle widget to change radio groups.
473 * Arguments: w - The toggle widget to change groups.
474 * radio_group - any widget in the new group.
475 * Returns: none.
478 void
479 #if NeedFunctionPrototypes
480 XawToggleChangeRadioGroup(Widget w, Widget radio_group)
481 #else
482 XawToggleChangeRadioGroup(w, radio_group)
483 Widget w, radio_group;
484 #endif
486 ToggleWidget tw = (ToggleWidget) w;
487 RadioGroup * group;
489 RemoveFromRadioGroup(w);
492 * If the toggle that we are about to add is set then we will
493 * unset all toggles in the new radio group.
496 if ( tw->command.set && radio_group != NULL )
497 XawToggleUnsetCurrent(radio_group);
499 if (radio_group != NULL)
500 if ((group = GetRadioGroup(radio_group)) == NULL)
501 CreateRadioGroup(w, radio_group);
502 else AddToRadioGroup(group, w);
505 /* Function Name: XawToggleGetCurrent
506 * Description: Returns the RadioData associated with the toggle
507 * widget that is currently active in a toggle group.
508 * Arguments: w - any toggle widget in the toggle group.
509 * Returns: The XtNradioData associated with the toggle widget.
512 XtPointer
513 #if NeedFunctionPrototypes
514 XawToggleGetCurrent(Widget w)
515 #else
516 XawToggleGetCurrent(w)
517 Widget w;
518 #endif
520 RadioGroup * group;
522 if ( (group = GetRadioGroup(w)) == NULL) return(NULL);
523 for ( ; group->prev != NULL ; group = group->prev);
525 while ( group != NULL ) {
526 ToggleWidget local_tog = (ToggleWidget) group->widget;
527 if ( local_tog->command.set )
528 return( local_tog->toggle.radio_data );
529 group = group->next;
531 return(NULL);
534 /* Function Name: XawToggleSetCurrent
535 * Description: Sets the Toggle widget associated with the
536 * radio_data specified.
537 * Arguments: radio_group - any toggle widget in the toggle group.
538 * radio_data - radio data of the toggle widget to set.
539 * Returns: none.
542 void
543 #if NeedFunctionPrototypes
544 XawToggleSetCurrent(Widget radio_group, XtPointer radio_data)
545 #else
546 XawToggleSetCurrent(radio_group, radio_data)
547 Widget radio_group;
548 XtPointer radio_data;
549 #endif
551 RadioGroup * group;
552 ToggleWidget local_tog;
554 /* Special case of no radio group. */
556 if ( (group = GetRadioGroup(radio_group)) == NULL) {
557 local_tog = (ToggleWidget) radio_group;
558 if ( (local_tog->toggle.radio_data == radio_data) )
559 if (!local_tog->command.set) {
560 ToggleSet((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
561 Notify((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
563 return;
567 * find top of radio_roup
570 for ( ; group->prev != NULL ; group = group->prev);
573 * search for matching radio data.
576 while ( group != NULL ) {
577 local_tog = (ToggleWidget) group->widget;
578 if ( (local_tog->toggle.radio_data == radio_data) ) {
579 if (!local_tog->command.set) { /* if not already set. */
580 ToggleSet((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
581 Notify((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
583 return; /* found it, done */
585 group = group->next;
589 /* Function Name: XawToggleUnsetCurrent
590 * Description: Unsets all Toggles in the radio_group specified.
591 * Arguments: radio_group - any toggle widget in the toggle group.
592 * Returns: none.
595 void
596 #if NeedFunctionPrototypes
597 XawToggleUnsetCurrent(Widget radio_group)
598 #else
599 XawToggleUnsetCurrent(radio_group)
600 Widget radio_group;
601 #endif
603 ToggleWidgetClass class;
604 ToggleWidget local_tog = (ToggleWidget) radio_group;
606 /* Special Case no radio group. */
608 if (local_tog->command.set) {
609 class = (ToggleWidgetClass) local_tog->core.widget_class;
610 class->toggle_class.Unset(radio_group, NULL, NULL, 0);
611 Notify(radio_group, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
613 if ( GetRadioGroup(radio_group) == NULL) return;
614 TurnOffRadioSiblings(radio_group);