3 Copyright 1989, 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.
28 * Author: Chris D. Peterson
30 * kit@expo.lcs.mit.edu
32 * Date: January 12, 1989
40 #include <X11/IntrinsicP.h>
41 #include <X11/StringDefs.h>
42 #include <X11/Xmu/Converters.h>
43 #include <X11/Xmu/Misc.h>
44 #include <X11/Xaw/ToggleP.h>
45 #include <X11/Xaw/XawInit.h>
50 static void XawToggleClassInitialize(void);
51 static void XawToggleInitialize(Widget, Widget, ArgList, Cardinal*);
52 static Boolean XawToggleSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
57 static void AddToRadioGroup(RadioGroup*, Widget);
58 static void CreateRadioGroup(Widget, Widget);
59 static RadioGroup *GetRadioGroup(Widget);
60 static void RemoveFromRadioGroup(Widget);
61 static void TurnOffRadioSiblings(Widget);
62 static void XawToggleDestroy(Widget, XtPointer, XtPointer);
67 static void Notify(Widget, XEvent*, String*, Cardinal*);
68 static void Toggle(Widget, XEvent*, String*, Cardinal*);
69 static void ToggleSet(Widget, XEvent*, String*, Cardinal*);
75 * The order of toggle and notify are important, as the state has
76 * to be set when we call the notify proc
78 static char defaultTranslations[] =
79 "<Enter>:" "highlight(Always)\n"
80 "<Leave>:" "unhighlight()\n"
81 "<Btn1Down>,<Btn1Up>:" "toggle() notify()\n"
84 #define offset(field) XtOffsetOf(ToggleRec, field)
85 static XtResource resources[] = {
100 offset(toggle.widget),
109 offset(toggle.radio_data),
116 static XtActionsRec actionsList[] = {
122 #define Superclass ((CommandWidgetClass)&commandClassRec)
123 ToggleClassRec toggleClassRec = {
126 (WidgetClass)Superclass, /* superclass */
127 "Toggle", /* class_name */
128 sizeof(ToggleRec), /* size */
129 XawToggleClassInitialize, /* class_initialize */
130 NULL, /* class_part_initialize */
131 False, /* class_inited */
132 XawToggleInitialize, /* initialize */
133 NULL, /* initialize_hook */
134 XtInheritRealize, /* realize */
135 actionsList, /* actions */
136 XtNumber(actionsList), /* num_actions */
137 resources, /* resources */
138 XtNumber(resources), /* resource_count */
139 NULLQUARK, /* xrm_class */
140 False, /* compress_motion */
141 True, /* compress_exposure */
142 True, /* compress_enterleave */
143 False, /* visible_interest */
145 XtInheritResize, /* resize */
146 XtInheritExpose, /* expose */
147 XawToggleSetValues, /* set_values */
148 NULL, /* set_values_hook */
149 XtInheritSetValuesAlmost, /* set_values_almost */
150 NULL, /* get_values_hook */
151 NULL, /* accept_focus */
152 XtVersion, /* version */
153 NULL, /* callback_private */
154 defaultTranslations, /* tm_table */
155 XtInheritQueryGeometry, /* query_geometry */
156 XtInheritDisplayAccelerator, /* display_accelerator */
157 NULL, /* extension */
161 XtInheritChangeSensitive, /* change_sensitive */
165 NULL, /* extension */
169 NULL, /* extension */
175 NULL, /* extension */
179 WidgetClass toggleWidgetClass = (WidgetClass)&toggleClassRec;
185 XawToggleClassInitialize(void)
187 XtActionList actions;
188 Cardinal num_actions;
190 ToggleWidgetClass cclass = (ToggleWidgetClass)toggleWidgetClass;
191 static XtConvertArgRec parentCvtArgs[] = {
192 {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
196 XawInitializeWidgetSet();
197 XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget,
198 parentCvtArgs, XtNumber(parentCvtArgs),
200 XtSetTypeConverter(XtRWidget, XtRString, XmuCvtWidgetToString,
201 NULL, 0, XtCacheNone, NULL);
204 * Find the set and unset actions in the command widget's action table
206 XtGetActionList(commandWidgetClass, &actions, &num_actions);
208 for (i = 0 ; i < num_actions ; i++) {
209 if (streq(actions[i].string, "set"))
210 cclass->toggle_class.Set = actions[i].proc;
211 if (streq(actions[i].string, "unset"))
212 cclass->toggle_class.Unset = actions[i].proc;
214 if (cclass->toggle_class.Set != NULL &&
215 cclass->toggle_class.Unset != NULL) {
216 XtFree((char *)actions);
221 /* We should never get here */
222 XtError("Aborting, due to errors resolving bindings in the Toggle widget.");
227 XawToggleInitialize(Widget request, Widget cnew,
228 ArgList args, Cardinal *num_args)
230 ToggleWidget tw = (ToggleWidget)cnew;
231 ToggleWidget tw_req = (ToggleWidget)request;
233 tw->toggle.radio_group = NULL;
235 if (tw->toggle.radio_data == NULL)
236 tw->toggle.radio_data = (XtPointer)cnew->core.name;
238 if (tw->toggle.widget != NULL) {
239 if (GetRadioGroup(tw->toggle.widget) == NULL)
240 CreateRadioGroup(cnew, tw->toggle.widget);
242 AddToRadioGroup(GetRadioGroup(tw->toggle.widget), cnew);
244 XtAddCallback(cnew, XtNdestroyCallback, XawToggleDestroy, NULL);
247 * Command widget assumes that the widget is unset, so we only
248 * have to handle the case where it needs to be set
250 * If this widget is in a radio group then it may cause another
251 * widget to be unset, thus calling the notify proceedure
253 * I want to set the toggle if the user set the state to "On" in
254 * the resource group, reguardless of what my ancestors did
256 if (tw_req->command.set)
257 ToggleSet(cnew, NULL, NULL, NULL);
262 ToggleSet(Widget w, XEvent *event, String *params, Cardinal *num_params)
264 ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class;
266 TurnOffRadioSiblings(w);
267 cclass->toggle_class.Set(w, event, NULL, NULL);
271 Toggle(Widget w, XEvent *event, String *params, Cardinal *num_params)
273 ToggleWidget tw = (ToggleWidget)w;
274 ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class;
277 cclass->toggle_class.Unset(w, event, NULL, NULL);
279 ToggleSet(w, event, params, num_params);
284 Notify(Widget w, XEvent *event, String *params, Cardinal *num_params)
286 ToggleWidget tw = (ToggleWidget)w;
287 long antilint = tw->command.set;
289 XtCallCallbacks(w, XtNcallback, (XtPointer)antilint);
294 XawToggleSetValues(Widget current, Widget request, Widget cnew,
295 ArgList args, Cardinal *num_args)
297 ToggleWidget oldtw = (ToggleWidget)current;
298 ToggleWidget tw = (ToggleWidget)cnew;
299 ToggleWidget rtw = (ToggleWidget)request;
301 if (oldtw->toggle.widget != tw->toggle.widget)
302 XawToggleChangeRadioGroup(cnew, tw->toggle.widget);
304 if (!tw->core.sensitive && oldtw->core.sensitive && rtw->command.set)
305 tw->command.set = True;
307 if (oldtw->command.set != tw->command.set) {
308 tw->command.set = oldtw->command.set;
309 Toggle(cnew, NULL, NULL, NULL);
320 * w - toggle widget that is being destroyed
325 * Destroy Callback for toggle widget.
329 XawToggleDestroy(Widget w, XtPointer temp1, XtPointer temp2)
331 RemoveFromRadioGroup(w);
339 * w - toggle widget who's radio group we are getting
342 * Gets the radio group associated with a give toggle widget.
345 * The radio group associated with this toggle group
348 GetRadioGroup(Widget w)
350 ToggleWidget tw = (ToggleWidget)w;
355 return (tw->toggle.radio_group);
363 * w1 - toggle widgets to add to the radio group
367 * Creates a radio group. give two widgets.
370 * A pointer to the group is added to each widget's radio_group field.
373 CreateRadioGroup(Widget w1, Widget w2)
375 ToggleWidget tw1 = (ToggleWidget)w1;
376 ToggleWidget tw2 = (ToggleWidget) w2;
378 if (tw1->toggle.radio_group != NULL || tw2->toggle.radio_group != NULL)
379 XtAppWarning(XtWidgetToApplicationContext(w1),
380 "Toggle Widget Error - Attempting to create a "
381 "new toggle group, when one already exists.");
383 AddToRadioGroup(NULL, w1);
384 AddToRadioGroup(GetRadioGroup(w1), w2);
392 * group - element of the radio group the we are adding to
393 * w - new toggle widget to add to the group
396 * Adds a toggle to the radio group.
399 AddToRadioGroup(RadioGroup *group, Widget w)
401 ToggleWidget tw = (ToggleWidget)w;
404 local = (RadioGroup *)XtMalloc(sizeof(RadioGroup));
406 tw->toggle.radio_group = local;
408 if (group == NULL) { /* Creating new group */
414 local->prev = group; /* Adding to previous group */
415 if ((local->next = group->next) != NULL)
416 local->next->prev = local;
422 * TurnOffRadioSiblings
425 * widget - toggle widget
428 * Deactivates all radio siblings.
431 TurnOffRadioSiblings(Widget w)
434 ToggleWidgetClass cclass = (ToggleWidgetClass)w->core.widget_class;
436 if ((group = GetRadioGroup(w)) == NULL) /* Punt if there is no group */
439 /* Go to the top of the group */
440 for (; group->prev != NULL ; group = group->prev)
443 while (group != NULL) {
444 ToggleWidget local_tog = (ToggleWidget)group->widget;
446 if (local_tog->command.set) {
447 cclass->toggle_class.Unset(group->widget, NULL, NULL, NULL);
448 Notify(group->widget, NULL, NULL, NULL);
456 * RemoveFromRadioGroup
459 * w - toggle widget to remove
462 * Removes a toggle from a RadioGroup.
465 RemoveFromRadioGroup(Widget w)
467 RadioGroup *group = GetRadioGroup(w);
469 if (group->prev != NULL)
470 (group->prev)->next = group->next;
471 if (group->next != NULL)
472 (group->next)->prev = group->prev;
473 XtFree((char *)group);
479 * XawToggleChangeRadioGroup
482 * w - toggle widget to change groups
483 * radio_group - any widget in the new group
486 * Allows a toggle widget to change radio groups.
489 XawToggleChangeRadioGroup(Widget w, Widget radio_group)
491 ToggleWidget tw = (ToggleWidget)w;
494 RemoveFromRadioGroup(w);
497 * If the toggle that we are about to add is set then we will
498 * unset all toggles in the new radio group
501 if (tw->command.set && radio_group != NULL)
502 XawToggleUnsetCurrent(radio_group);
504 if (radio_group != NULL) {
505 if ((group = GetRadioGroup(radio_group)) == NULL)
506 CreateRadioGroup(w, radio_group);
508 AddToRadioGroup(group, w);
514 * XawToggleGetCurrent
517 * w - any toggle widget in the toggle group
520 * Returns the RadioData associated with the toggle
521 * widget that is currently active in a toggle group.
524 * The XtNradioData associated with the toggle widget
527 XawToggleGetCurrent(Widget w)
531 if ((group = GetRadioGroup(w)) == NULL)
534 for (; group->prev != NULL ; group = group->prev)
537 while (group != NULL) {
538 ToggleWidget local_tog = (ToggleWidget)group->widget;
540 if (local_tog->command.set)
541 return (local_tog->toggle.radio_data);
550 * XawToggleSetCurrent
553 * radio_group - any toggle widget in the toggle group
554 * radio_data - radio data of the toggle widget to set
557 * Sets the Toggle widget associated with the radio_data specified.
560 XawToggleSetCurrent(Widget radio_group, XtPointer radio_data)
563 ToggleWidget local_tog;
565 /* Special case of no radio group */
567 if ((group = GetRadioGroup(radio_group)) == NULL) {
568 local_tog = (ToggleWidget)radio_group;
570 if (local_tog->toggle.radio_data == radio_data &&
571 !local_tog->command.set) {
572 ToggleSet(radio_group, NULL, NULL, NULL);
573 Notify(radio_group, NULL, NULL, NULL);
579 * find top of radio_roup
581 for (; group->prev != NULL ; group = group->prev)
585 * search for matching radio data
587 while (group != NULL) {
588 local_tog = (ToggleWidget)group->widget;
590 if (local_tog->toggle.radio_data == radio_data) {
591 if (!local_tog->command.set) { /* if not already set */
592 ToggleSet(group->widget, NULL, NULL, NULL);
593 Notify(group->widget, NULL, NULL, NULL);
595 return; /* found it, done */
603 * XawToggleUnsetCurrent
606 * radio_group - any toggle widget in the toggle group
609 * Unsets all Toggles in the radio_group specified.
612 XawToggleUnsetCurrent(Widget radio_group)
614 ToggleWidgetClass cclass;
615 ToggleWidget local_tog = (ToggleWidget)radio_group;
617 /* Special Case no radio group */
619 if (local_tog->command.set) {
620 cclass = (ToggleWidgetClass)local_tog->core.widget_class;
621 cclass->toggle_class.Unset(radio_group, NULL, NULL, NULL);
622 Notify(radio_group, NULL, NULL, NULL);
624 if (GetRadioGroup(radio_group) == NULL)
627 TurnOffRadioSiblings(radio_group);