rebuild geeqie
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1Toggle.c
blobb8acc5d8d78f3eb2516bc77245333b41f51eec48
1 #ifndef lint
2 static char Xrcsid[] = "$XConsortium: Toggle.c,v 1.15 89/12/11 15:22:59 kit Exp $";
3 #endif /* lint */
5 /*
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 * Toggle.c - Toggle button widget
30 * Author: Chris D. Peterson
31 * MIT X Consortium
32 * kit@expo.lcs.mit.edu
34 * Date: January 12, 1989
38 #include <stdio.h>
40 #include <X11/IntrinsicP.h>
41 #include <X11/StringDefs.h>
43 #include <./Xaw3_1XawInit.h>
44 #include <X11/Xmu/Misc.h>
45 #include <./Xaw3_1ToggleP.h>
47 /****************************************************************
49 * Full class record constant
51 ****************************************************************/
53 /* Private Data */
55 /* This is a hack, see the comments in ClassInit(). */
57 extern XtActionList xaw_command_actions_list;
59 /*
60 * The order of toggle and notify are important, as the state has
61 * to be set when we call the notify proc.
64 static char defaultTranslations[] =
65 "<EnterWindow>: highlight(Always) \n\
66 <LeaveWindow>: unhighlight() \n\
67 <Btn1Down>,<Btn1Up>: toggle() notify()";
69 #define offset(field) XtOffset(ToggleWidget, field)
71 static XtResource resources[] = {
72 {XtNstate, XtCState, XtRBoolean, sizeof(Boolean),
73 offset(command.set), XtRString, "off"},
74 {XtNradioGroup, XtCWidget, XtRWidget, sizeof(Widget),
75 offset(toggle.widget), XtRWidget, (caddr_t) NULL },
76 {XtNradioData, XtCRadioData, XtRPointer, sizeof(caddr_t),
77 offset(toggle.radio_data), XtRPointer, (caddr_t) NULL },
80 #undef offset
82 /* Action proceedures retrieved from the command widget */
84 static void Toggle(), Initialize(), Notify(), ToggleSet();
85 static void ToggleDestroy(), ClassInit();
86 static Boolean SetValues();
88 /* Functions for handling the Radio Group. */
90 static RadioGroup * GetRadioGroup();
91 static void CreateRadioGroup(), AddToRadioGroup(), TurnOffRadioSiblings();
92 static void RemoveFromRadioGroup();
94 static XtActionsRec actionsList[] =
96 {"toggle", Toggle},
97 {"notify", Notify},
98 {"set", ToggleSet},
101 #define SuperClass ((CommandWidgetClass)&commandClassRec)
103 ToggleClassRec toggleClassRec = {
105 (WidgetClass) SuperClass, /* superclass */
106 "Toggle", /* class_name */
107 sizeof(ToggleRec), /* size */
108 ClassInit, /* class_initialize */
109 NULL, /* class_part_initialize */
110 FALSE, /* class_inited */
111 Initialize, /* initialize */
112 NULL, /* initialize_hook */
113 XtInheritRealize, /* realize */
114 actionsList, /* actions */
115 XtNumber(actionsList), /* num_actions */
116 resources, /* resources */
117 XtNumber(resources), /* resource_count */
118 NULLQUARK, /* xrm_class */
119 FALSE, /* compress_motion */
120 TRUE, /* compress_exposure */
121 TRUE, /* compress_enterleave */
122 FALSE, /* visible_interest */
123 NULL, /* destroy */
124 XtInheritResize, /* resize */
125 XtInheritExpose, /* expose */
126 SetValues, /* set_values */
127 NULL, /* set_values_hook */
128 XtInheritSetValuesAlmost, /* set_values_almost */
129 NULL, /* get_values_hook */
130 NULL, /* accept_focus */
131 XtVersion, /* version */
132 NULL, /* callback_private */
133 defaultTranslations, /* tm_table */
134 XtInheritQueryGeometry, /* query_geometry */
135 XtInheritDisplayAccelerator, /* display_accelerator */
136 NULL /* extension */
137 }, /* CoreClass fields initialization */
139 XtInheritChangeSensitive /* change_sensitive */
140 }, /* SimpleClass fields initialization */
142 0 /* field not used */
143 }, /* LabelClass fields initialization */
145 0 /* field not used */
146 }, /* CommmandClass fields initialization */
148 NULL, /* Set Proceedure. */
149 NULL, /* Unset Proceedure. */
150 NULL /* extension. */
151 } /* ToggleClass fields initialization */
154 /* for public consumption */
155 WidgetClass toggleWidgetClass = (WidgetClass) &toggleClassRec;
157 /****************************************************************
159 * Private Procedures
161 ****************************************************************/
163 static void
164 ClassInit()
166 XtActionList actions;
167 Cardinal i;
168 ToggleWidgetClass class = (ToggleWidgetClass) toggleWidgetClass;
170 XawInitializeWidgetSet();
172 /* actions = SuperClass->core_class.actions; */
174 /* The actions table should really be retrieved from the toggle widget's
175 * Superclass, but this information is munged by the R3 intrinsics so the
176 * I have hacked the Athena command widget to export its action table
177 * as a global variable.
179 * Chris D. Peterson 12/28/88.
182 actions = xaw_command_actions_list;
185 * Find the set and unset actions in the command widget's action table.
188 for (i = 0 ; i < SuperClass->core_class.num_actions ; i++) {
189 if (streq(actions[i].string, "set"))
190 class->toggle_class.Set = actions[i].proc;
191 if (streq(actions[i].string, "unset"))
192 class->toggle_class.Unset = actions[i].proc;
194 if ( (class->toggle_class.Set != NULL) &&
195 (class->toggle_class.Unset != NULL) ) return;
198 /* We should never get here. */
199 if (class->toggle_class.Set == NULL)
200 XtWarning(
201 "Toggle could not find action Proceedure Set() in the Command Widget.");
202 if (class->toggle_class.Unset == NULL)
203 XtWarning(
204 "Toggle could not find action Proceedure Unset() in the Command Widget.");
205 XtError("Aborting, due to errors in Toggle widget.");
208 static void Initialize(request, new)
209 Widget request, new;
211 ToggleWidget tw = (ToggleWidget) new;
212 ToggleWidget tw_req = (ToggleWidget) request;
214 tw->toggle.radio_group = NULL;
216 if (tw->toggle.radio_data == NULL)
217 tw->toggle.radio_data = (caddr_t) new->core.name;
219 if (tw->toggle.widget != NULL) {
220 if ( GetRadioGroup(tw->toggle.widget) == NULL)
221 CreateRadioGroup(new, tw->toggle.widget);
222 else
223 AddToRadioGroup( GetRadioGroup(tw->toggle.widget), new);
225 XtAddCallback(new, XtNdestroyCallback, ToggleDestroy, NULL);
228 * Command widget assumes that the widget is unset, so we only
229 * have to handle the case where it needs to be set.
231 * If this widget is in a radio group then it may cause another
232 * widget to be unset, thus calling the notify proceedure.
234 * I want to set the toggle if the user set the state to "On" in
235 * the resource group, reguardless of what my ancestors did.
238 if (tw_req->command.set)
239 ToggleSet(new, NULL, NULL, 0);
242 /************************************************************
244 * Action Procedures
246 ************************************************************/
248 /* ARGSUSED */
249 static void
250 ToggleSet(w,event,params,num_params)
251 Widget w;
252 XEvent *event;
253 String *params; /* unused */
254 Cardinal *num_params; /* unused */
256 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
258 TurnOffRadioSiblings(w);
259 class->toggle_class.Set(w, event, NULL, 0);
262 /* ARGSUSED */
263 static void
264 Toggle(w,event,params,num_params)
265 Widget w;
266 XEvent *event;
267 String *params; /* unused */
268 Cardinal *num_params; /* unused */
270 ToggleWidget tw = (ToggleWidget)w;
271 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
273 if (tw->command.set)
274 class->toggle_class.Unset(w, event, NULL, 0);
275 else
276 ToggleSet(w, event, params, num_params);
279 /* ARGSUSED */
280 static void Notify(w,event,params,num_params)
281 Widget w;
282 XEvent *event;
283 String *params; /* unused */
284 Cardinal *num_params; /* unused */
286 ToggleWidget tw = (ToggleWidget) w;
287 XtCallCallbacks(w, XtNcallback, tw->command.set);
290 /************************************************************
292 * Set specified arguments into widget
294 ***********************************************************/
296 /* ARGSUSED */
297 static Boolean
298 SetValues (current, request, new)
299 Widget current, request, new;
301 ToggleWidget oldtw = (ToggleWidget) current;
302 ToggleWidget tw = (ToggleWidget) new;
304 if (oldtw->toggle.widget != tw->toggle.widget)
305 XawToggleChangeRadioGroup(new, tw->toggle.widget);
307 if (oldtw->command.set != tw->command.set) {
308 tw->command.set = oldtw->command.set;
309 Toggle(new, NULL, NULL, 0); /* Does a redisplay. */
311 return(FALSE);
314 /* Function Name: ToggleDestroy
315 * Description: Destroy Callback for toggle widget.
316 * Arguments: w - the toggle widget that is being destroyed.
317 * junk, grabage - not used.
318 * Returns: none.
321 /* ARGSUSED */
322 static void
323 ToggleDestroy(w, junk, garbage)
324 Widget w;
325 caddr_t junk, garbage;
327 RemoveFromRadioGroup(w);
330 /************************************************************
332 * Below are all the private proceedures that handle
333 * radio toggle buttons.
335 ************************************************************/
337 /* Function Name: GetRadioGroup
338 * Description: Gets the radio group associated with a give toggle
339 * widget.
340 * Arguments: w - the toggle widget who's radio group we are getting.
341 * Returns: the radio group associated with this toggle group.
344 static RadioGroup *
345 GetRadioGroup(w)
346 Widget w;
348 ToggleWidget tw = (ToggleWidget) w;
350 if (tw == NULL) return(NULL);
351 return( tw->toggle.radio_group );
354 /* Function Name: CreateRadioGroup
355 * Description: Creates a radio group. give two widgets.
356 * Arguments: w1, w2 - the toggle widgets to add to the radio group.
357 * Returns: none.
359 * NOTE: A pointer to the group is added to each widget's radio_group
360 * field.
363 static void
364 CreateRadioGroup(w1, w2)
365 Widget w1, w2;
367 char error_buf[BUFSIZ];
368 ToggleWidget tw1 = (ToggleWidget) w1;
369 ToggleWidget tw2 = (ToggleWidget) w2;
371 if ( (tw1->toggle.radio_group != NULL) || (tw2->toggle.radio_group != NULL) ) {
372 sprintf(error_buf, "%s %s", "Toggle Widget Error - Attempting",
373 "to create a new toggle group, when one already exists.");
374 XtWarning(error_buf);
377 AddToRadioGroup( NULL, w1 );
378 AddToRadioGroup( GetRadioGroup(w1), w2 );
381 /* Function Name: AddToRadioGroup
382 * Description: Adds a toggle to the radio group.
383 * Arguments: group - any element of the radio group the we are adding to.
384 * w - the new toggle widget to add to the group.
385 * Returns: none.
388 static void
389 AddToRadioGroup(group, w)
390 RadioGroup * group;
391 Widget w;
393 ToggleWidget tw = (ToggleWidget) w;
394 RadioGroup * local;
396 local = (RadioGroup *) XtMalloc( sizeof(RadioGroup) );
397 local->widget = w;
398 tw->toggle.radio_group = local;
400 if (group == NULL) { /* Creating new group. */
401 group = local;
402 group->next = NULL;
403 group->prev = NULL;
404 return;
406 local->prev = group; /* Adding to previous group. */
407 if ((local->next = group->next) != NULL)
408 local->next->prev = local;
409 group->next = local;
412 /* Function Name: TurnOffRadioSiblings
413 * Description: Deactivates all radio siblings.
414 * Arguments: widget - a toggle widget.
415 * Returns: none.
418 static void
419 TurnOffRadioSiblings(w)
420 Widget w;
422 RadioGroup * group;
423 ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
425 if ( (group = GetRadioGroup(w)) == NULL) /* Punt if there is no group */
426 return;
428 /* Go to the top of the group. */
430 for ( ; group->prev != NULL ; group = group->prev );
432 while ( group != NULL ) {
433 ToggleWidget local_tog = (ToggleWidget) group->widget;
434 if ( local_tog->command.set ) {
435 class->toggle_class.Unset(group->widget, NULL, NULL, 0);
436 Notify( group->widget, NULL, NULL, 0);
438 group = group->next;
442 /* Function Name: RemoveFromRadioGroup
443 * Description: Removes a toggle from a RadioGroup.
444 * Arguments: w - the toggle widget to remove.
445 * Returns: none.
448 static void
449 RemoveFromRadioGroup(w)
450 Widget w;
452 RadioGroup * group = GetRadioGroup(w);
453 if (group != NULL) {
454 if (group->prev != NULL)
455 (group->prev)->next = group->next;
456 if (group->next != NULL)
457 (group->next)->prev = group->prev;
458 XtFree(group);
462 /************************************************************
464 * Public Routines
466 ************************************************************/
468 /* Function Name: XawToggleChangeRadioGroup
469 * Description: Allows a toggle widget to change radio groups.
470 * Arguments: w - The toggle widget to change groups.
471 * radio_group - any widget in the new group.
472 * Returns: none.
475 void
476 XawToggleChangeRadioGroup(w, radio_group)
477 Widget w, radio_group;
479 ToggleWidget tw = (ToggleWidget) w;
481 RemoveFromRadioGroup(w);
484 * If the toggle that we are about to add is set then we will
485 * unset all toggles in the new radio group.
488 if ( tw->command.set && radio_group != NULL )
489 XawToggleUnsetCurrent(radio_group);
490 AddToRadioGroup( GetRadioGroup(radio_group), w );
493 /* Function Name: XawToggleGetCurrent
494 * Description: Returns the RadioData associated with the toggle
495 * widget that is currently active in a toggle group.
496 * Arguments: w - any toggle widget in the toggle group.
497 * Returns: The XtNradioData associated with the toggle widget.
500 caddr_t
501 XawToggleGetCurrent(w)
502 Widget w;
504 RadioGroup * group;
506 if ( (group = GetRadioGroup(w)) == NULL) return(NULL);
507 for ( ; group->prev != NULL ; group = group->prev);
509 while ( group != NULL ) {
510 ToggleWidget local_tog = (ToggleWidget) group->widget;
511 if ( local_tog->command.set )
512 return( local_tog->toggle.radio_data );
513 group = group->next;
515 return(NULL);
518 /* Function Name: XawToggleSetCurrent
519 * Description: Sets the Toggle widget associated with the
520 * radio_data specified.
521 * Arguments: radio_group - any toggle widget in the toggle group.
522 * radio_data - radio data of the toggle widget to set.
523 * Returns: none.
526 void
527 XawToggleSetCurrent(radio_group, radio_data)
528 Widget radio_group;
529 caddr_t radio_data;
531 RadioGroup * group;
532 ToggleWidget local_tog;
534 /* Special case case of no radio group. */
536 if ( (group = GetRadioGroup(radio_group)) == NULL) {
537 local_tog = (ToggleWidget) radio_group;
538 if ( (local_tog->toggle.radio_data == radio_data) )
539 if (!local_tog->command.set) {
540 ToggleSet((Widget) local_tog, NULL, NULL, 0);
541 Notify((Widget) local_tog, NULL, NULL, 0);
543 return;
547 * find top of radio_roup
550 for ( ; group->prev != NULL ; group = group->prev);
553 * search for matching radio data.
556 while ( group != NULL ) {
557 local_tog = (ToggleWidget) group->widget;
558 if ( (local_tog->toggle.radio_data == radio_data) ) {
559 if (!local_tog->command.set) { /* if not already set. */
560 ToggleSet((Widget) local_tog, NULL, NULL, 0);
561 Notify((Widget) local_tog, NULL, NULL, 0);
563 return; /* found it, done */
565 group = group->next;
569 /* Function Name: XawToggleUnsetCurrent
570 * Description: Unsets all Toggles in the radio_group specified.
571 * Arguments: radio_group - any toggle widget in the toggle group.
572 * Returns: none.
575 void
576 XawToggleUnsetCurrent(radio_group)
577 Widget radio_group;
579 ToggleWidgetClass class;
580 ToggleWidget local_tog = (ToggleWidget) radio_group;
582 /* Special Case no radio group. */
584 if (local_tog->command.set) {
585 class = (ToggleWidgetClass) local_tog->core.widget_class;
586 class->toggle_class.Unset(radio_group, NULL, NULL, 0);
587 Notify(radio_group, NULL, NULL, 0);
589 if ( GetRadioGroup(radio_group) == NULL) return;
590 TurnOffRadioSiblings(radio_group);