One more check on valid display which is known to be in the startup
[xcircuit.git] / Xw / MenuMgr.c
blobc928686175a773f03230a4419f62276054ee3b5d
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: MenuMgr.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Menu Manager Meta Class Widget
9 **
10 *****************************************************************************
11 **
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
14 **
15 ** Permission to use, copy, modify, and distribute this software
16 ** and its documentation for any purpose and without fee is hereby
17 ** granted, provided that the above copyright notice appear in all
18 ** copies and that both that copyright notice and this permission
19 ** notice appear in supporting documentation, and that the names of
20 ** Hewlett-Packard or M.I.T. not be used in advertising or publicity
21 ** pertaining to distribution of the software without specific, written
22 ** prior permission.
23 **
24 *****************************************************************************
25 *************************************<+>*************************************/
28 #include <X11/IntrinsicP.h>
29 #include <X11/Xutil.h>
30 #include <X11/StringDefs.h>
31 #include <X11/Xatom.h>
32 #include <Xw/Xw.h>
33 #include <Xw/XwP.h>
35 static void Initialize();
36 static void Destroy();
37 static Boolean SetValues();
38 static void ClassInitialize();
41 /****************************************************************
43 * MenuPane Resources
45 ****************************************************************/
47 static XtResource resources[] = {
48 {XtNassociateChildren, XtCAssociateChildren, XtRBoolean, sizeof(Boolean),
49 XtOffset(XwMenuMgrWidget, menu_mgr.associateChildren), XtRString,
50 "TRUE"},
52 {XtNmenuPost, XtCMenuPost, XtRString, sizeof(String),
53 XtOffset(XwMenuMgrWidget, menu_mgr.postString), XtRString,
54 "<Btn1Down>"},
56 {XtNmenuSelect, XtCMenuSelect, XtRString, sizeof(String),
57 XtOffset(XwMenuMgrWidget, menu_mgr.selectString), XtRString,
58 "<Btn1Up>"},
60 {XtNmenuUnpost, XtCMenuUnpost, XtRString, sizeof(String),
61 XtOffset(XwMenuMgrWidget, menu_mgr.unpostString), XtRString,
62 NULL},
64 {XtNkbdSelect, XtCKbdSelect, XtRString, sizeof(String),
65 XtOffset(XwMenuMgrWidget, menu_mgr.kbdSelectString), XtRString,
66 "<Key>Select"}
70 /****************************************************************
72 * Full class record constant
74 ****************************************************************/
76 XwMenuMgrClassRec XwmenumgrClassRec = {
78 /* core_class fields */
79 /* superclass */ (WidgetClass) &XwmanagerClassRec,
80 /* class_name */ "XwMenuMgr",
81 /* widget_size */ sizeof(XwMenuMgrRec),
82 /* class_initialize */ ClassInitialize,
83 /* class_part_init */ NULL,
84 /* class_inited */ FALSE,
85 /* initialize */ Initialize,
86 /* initialize_hook */ NULL,
87 /* realize */ NULL,
88 /* actions */ NULL,
89 /* num_actions */ 0,
90 /* resources */ resources,
91 /* num_resources */ XtNumber(resources),
92 /* xrm_class */ NULLQUARK,
93 /* compress_motion */ TRUE,
94 /* compress_exposure */ TRUE,
95 /* compress_enterlv */ TRUE,
96 /* visible_interest */ FALSE,
97 /* destroy */ Destroy,
98 /* resize */ NULL,
99 /* expose */ NULL,
100 /* set_values */ SetValues,
101 /* set_values_hook */ NULL,
102 /* set_values_almost */ XtInheritSetValuesAlmost,
103 /* get_values_hook */ NULL,
104 /* accept_focus */ NULL,
105 /* version */ XtVersion,
106 /* PRIVATE cb list */ NULL,
107 /* tm_table */ NULL,
108 /* query_geometry */ NULL,
109 /* display_accelerator */ XtInheritDisplayAccelerator,
110 /* extension */ NULL
112 /* composite_class fields */
113 /* geometry_manager */ NULL,
114 /* change_managed */ NULL,
115 /* insert_child */ XtInheritInsertChild,
116 /* delete_child */ XtInheritDeleteChild,
117 NULL,
119 /* constraint class fields */
120 /* resources */ NULL,
121 /* num_resources */ 0,
122 /* constraint_size */ 0,
123 /* initialize */ NULL,
124 /* destroy */ NULL,
125 /* set_values */ NULL,
126 NULL,
128 /* manager_class fields */
129 /* traversal handler */ NULL,
130 /* translations */ NULL,
132 /* menu manager class - none */
133 /* attachPane */ NULL,
134 /* detachPane */ NULL,
135 /* addPane */ NULL,
136 /* setSelectAccelerar */ NULL,
137 /* clearSelectAcceler */ NULL,
138 /* setPostMnemonic */ NULL,
139 /* clearPostMnemonic */ NULL,
140 /* addButton */ NULL,
141 /* processSelect */ NULL,
142 /* validEvent */ NULL,
143 /* doICascade */ NULL,
144 /* setSelectMnemonic */ NULL,
145 /* clearSelectMnemon */ NULL,
146 /* setTitleAttributes */ NULL,
147 /* paneManagedChildren*/ NULL,
148 /* traverseLeft */ NULL,
149 /* traverseRight */ NULL,
150 /* traverseNext */ NULL,
151 /* traversePrev */ NULL,
152 /* traverseHome */ NULL,
153 /* traverseUp */ NULL,
154 /* traverseDown */ NULL,
155 /* traverseNextTop */ NULL,
156 /* btnSensitivityChan */ NULL,
157 /* paneSensitivityCha */ NULL,
161 WidgetClass XwmenumgrWidgetClass = (WidgetClass)&XwmenumgrClassRec;
164 /*************************************<->*************************************
166 * ClassInitialize(parameters)
168 * Description:
169 * -----------
170 * xxxxxxxxxxxxxxxxxxxxxxx
173 * Inputs:
174 * ------
175 * xxxxxxxxxxxx = xxxxxxxxxxxxx
177 * Outputs:
178 * -------
179 * xxxxxxxxxxxx = xxxxxxxxxxxxx
181 * Procedures Called
182 * -----------------
184 *************************************<->***********************************/
186 static void ClassInitialize ()
191 /*************************************<->*************************************
193 * Initialize
196 * Description:
197 * -----------
198 * Initialize the menu_mgr fields within the widget's instance structure.
201 * Inputs:
202 * ------
203 * xxxxxxxxxxxx = xxxxxxxxxxxxx
205 * Outputs:
206 * -------
207 * xxxxxxxxxxxx = xxxxxxxxxxxxx
209 * Procedures Called
210 * -----------------
212 *************************************<->***********************************/
214 static void Initialize (request, new)
216 XwMenuMgrWidget request, new;
219 KeySym tempKeysym;
221 /* FOR NOW, MENUS DO NOT UNDERSTAND TRAVERSAL */
222 /* new->manager.traversal_on = FALSE; */
225 * Save a copy of the posting event string, and also convert it
226 * into a form which can be compared against an X button event.
228 if ((new->menu_mgr.postString) &&
229 (strlen(new->menu_mgr.postString) > 0))
231 if (_XwMapBtnEvent (new->menu_mgr.postString,
232 &new->menu_mgr.postEventType,
233 &new->menu_mgr.postButton,
234 &new->menu_mgr.postModifiers) == FALSE)
236 /* String was not valid; use the default one */
237 XtWarning("MenuMgr: Invalid post event; using <Btn1Down>");
238 new->menu_mgr.postString = (String) strcpy (XtMalloc (XwStrlen
239 ("<Btn1Down>") + 1), "<Btn1Down>");
241 _XwMapBtnEvent ("<Btn1Down>",
242 &new->menu_mgr.postEventType,
243 &new->menu_mgr.postButton,
244 &new->menu_mgr.postModifiers);
246 else
248 /* String was valid */
249 new->menu_mgr.postString = (String) strcpy (XtMalloc (XwStrlen
250 (new->menu_mgr.postString) + 1), new->menu_mgr.postString);
253 else
255 new->menu_mgr.postString = NULL;
256 new->menu_mgr.postModifiers = 0;
257 new->menu_mgr.postButton = 0;
261 * Save a copy of the selecting event string, and also convert it
262 * into a form which can be compared against an X button event.
264 if ((new->menu_mgr.selectString) &&
265 (strlen(new->menu_mgr.selectString) > 0))
267 if (_XwMapBtnEvent (new->menu_mgr.selectString,
268 &new->menu_mgr.selectEventType,
269 &new->menu_mgr.selectButton,
270 &new->menu_mgr.selectModifiers) == FALSE)
272 /* String was not valid; use the default one */
273 XtWarning("MenuMgr: Invalid select event; using <Btn1Up>");
274 new->menu_mgr.selectString = (String) strcpy (XtMalloc (XwStrlen
275 ("<Btn1Up>") + 1), "<Btn1Up>");
277 _XwMapBtnEvent ("<Btn1Up>",
278 &new->menu_mgr.selectEventType,
279 &new->menu_mgr.selectButton,
280 &new->menu_mgr.selectModifiers);
282 else
284 /* String was valid */
285 new->menu_mgr.selectString = (String) strcpy (XtMalloc (XwStrlen
286 (new->menu_mgr.selectString) + 1), new->menu_mgr.selectString);
289 else
291 new->menu_mgr.selectString = NULL;
292 new->menu_mgr.selectModifiers = 0;
293 new->menu_mgr.selectButton = 0;
297 * Save a copy of the unposting event string, and also convert it
298 * into a form which can be compared against an X button event.
300 if ((new->menu_mgr.unpostString) &&
301 (strlen(new->menu_mgr.unpostString) > 0))
303 if (_XwMapKeyEvent (new->menu_mgr.unpostString,
304 &new->menu_mgr.unpostEventType,
305 &tempKeysym,
306 &new->menu_mgr.unpostModifiers) == FALSE)
308 /* String was not valid; use the default one */
309 XtWarning("MenuMgr: Invalid unpost event; disabling option");
310 new->menu_mgr.unpostString = NULL;
312 else
314 /* String was valid */
315 new->menu_mgr.unpostKey = XKeysymToKeycode(XtDisplay(new),tempKeysym);
316 new->menu_mgr.unpostString = (String) strcpy (XtMalloc (XwStrlen
317 (new->menu_mgr.unpostString) + 1), new->menu_mgr.unpostString);
320 else
322 new->menu_mgr.unpostString = NULL;
323 new->menu_mgr.unpostModifiers = 0;
324 new->menu_mgr.unpostKey = 0;
328 * Save a copy of the kbd select event string, and also convert it
329 * into a form which can be compared against an X key event.
331 if ((new->menu_mgr.kbdSelectString) &&
332 (strlen(new->menu_mgr.kbdSelectString) > 0))
334 if (_XwMapKeyEvent (new->menu_mgr.kbdSelectString,
335 &new->menu_mgr.kbdSelectEventType,
336 &tempKeysym,
337 &new->menu_mgr.kbdSelectModifiers) == FALSE)
339 /* String was not valid; use the default one */
340 XtWarning("MenuMgr: Invalid keyboard select event; using default");
341 new->menu_mgr.kbdSelectString = (String) strcpy (XtMalloc (XwStrlen
342 ("<Key>Select") + 1), "<Key>Select");
344 _XwMapKeyEvent ("<Key>Select",
345 &new->menu_mgr.kbdSelectEventType,
346 &new->menu_mgr.kbdSelectKey,
347 &new->menu_mgr.kbdSelectModifiers);
349 else
351 /* String was valid */
352 new->menu_mgr.kbdSelectKey =
353 XKeysymToKeycode(XtDisplay(new),tempKeysym);
354 new->menu_mgr.kbdSelectString = (String) strcpy (XtMalloc (XwStrlen
355 (new->menu_mgr.kbdSelectString) + 1),
356 new->menu_mgr.kbdSelectString);
359 else
361 new->menu_mgr.kbdSelectString = NULL;
362 new->menu_mgr.kbdSelectModifiers = 0;
363 new->menu_mgr.kbdSelectKey = 0;
367 /* Allocate space for each of the tables used by a menu manager */
368 new->menu_mgr.menuBtnAccelTable =
369 (XwKeyAccel *) XtMalloc(100 * sizeof(XwKeyAccel));
370 new->menu_mgr.numAccels = 0;
371 new->menu_mgr.sizeAccelTable = 100;
373 new->menu_mgr.pendingAttachList =
374 (XwAttachList *) XtMalloc(25 * sizeof(XwAttachList));
375 new->menu_mgr.numAttachReqs = 0;
376 new->menu_mgr.sizeAttachList = 25;
379 /* Set menu flags */
380 new->menu_mgr.menuActive = FALSE;
381 } /* Initialize */
384 /*************************************<->*************************************
386 * SetValues()
388 * Description:
389 * -----------
391 * This procedure simply checks to see if the post or select specification
392 * has changed, and allocates space for the new string and frees up the
393 * old string. It will also map the new specification into a button/
394 * modifier pair.
396 * NOTE: When a new post or select string is specified, this routine will
397 * allocate space for the new string, but will NOT free up the old
398 * string; thus, our subclasses can check to see if these strings
399 * differ, and can remove any translations. It is then upto the
400 * subclass to free the old string and to modify any translations or
401 * button grabs which are associated with the post or select actions.
403 * It is also the responsibility of the subclass to check the state
404 * of the 'associate children' flag, and to modify any corresponding
405 * translations or grabs.
407 * Inputs:
408 * ------
409 * xxxxxxxxxxxx = xxxxxxxxxxxxx
411 * Outputs:
412 * -------
413 * xxxxxxxxxxxx = xxxxxxxxxxxxx
415 * Procedures Called
416 * -----------------
418 *************************************<->***********************************/
420 static Boolean SetValues (current, request, new)
422 XwMenuMgrWidget current, request, new;
425 KeySym tempKeysym;
427 /* FOR NOW, MENUS DO NOT UNDERSTAND TRAVERSAL */
428 /* new->manager.traversal_on = FALSE; */
430 /* Handle the case of a changed posting string */
432 if (current->menu_mgr.postString != new->menu_mgr.postString)
434 /* Allocate a new buffer to hold the string */
435 if ((new->menu_mgr.postString) &&
436 (strlen(new->menu_mgr.postString) > 0))
438 if (_XwMapBtnEvent (new->menu_mgr.postString,
439 &new->menu_mgr.postEventType,
440 &new->menu_mgr.postButton,
441 &new->menu_mgr.postModifiers) == FALSE)
443 /* Invalid post string; use the previous one */
444 XtWarning("MenuMgr: Invalid post event; using previous setting");
445 new->menu_mgr.postString = current->menu_mgr.postString;
446 new->menu_mgr.postEventType = current->menu_mgr.postEventType;
447 new->menu_mgr.postButton = current->menu_mgr.postButton;
448 new->menu_mgr.postModifiers = current->menu_mgr.postModifiers;
450 else
452 /* Valid post string */
453 new->menu_mgr.postString = (String)
454 strcpy (XtMalloc (XwStrlen (new->menu_mgr.postString) + 1),
455 new->menu_mgr.postString);
458 else
460 new->menu_mgr.postString = NULL;
461 new->menu_mgr.postEventType = 0;
462 new->menu_mgr.postButton = 0;
463 new->menu_mgr.postModifiers = 0;
467 * Don't free up the buffer holding the old post string.
468 * This is to be done by our subclass.
472 /* Handle the case of a changed select string */
474 if (current->menu_mgr.selectString != new->menu_mgr.selectString)
476 /* Allocate a new buffer to hold the string */
477 if ((new->menu_mgr.selectString) &&
478 (strlen(new->menu_mgr.selectString) > 0))
480 if (_XwMapBtnEvent (new->menu_mgr.selectString,
481 &new->menu_mgr.selectEventType,
482 &new->menu_mgr.selectButton,
483 &new->menu_mgr.selectModifiers) == FALSE)
485 /* Invalid select string; use the previous one */
486 XtWarning("MenuMgr: Invalid select event; using previous setting");
487 new->menu_mgr.selectString = current->menu_mgr.selectString;
488 new->menu_mgr.selectEventType = current->menu_mgr.selectEventType;
489 new->menu_mgr.selectButton = current->menu_mgr.selectButton;
490 new->menu_mgr.selectModifiers = current->menu_mgr.selectModifiers;
492 else
494 /* Valid select string */
495 new->menu_mgr.selectString = (String)
496 strcpy (XtMalloc (XwStrlen (new->menu_mgr.selectString) + 1),
497 new->menu_mgr.selectString);
500 else
502 new->menu_mgr.selectString = NULL;
503 new->menu_mgr.selectEventType = 0;
504 new->menu_mgr.selectButton = 0;
505 new->menu_mgr.selectModifiers = 0;
509 * Don't free up the buffer holding the old select string.
510 * This is to be done by our subclass.
514 /* Handle the case of a changed unposting string */
516 if (current->menu_mgr.unpostString != new->menu_mgr.unpostString)
518 /* Allocate a new buffer to hold the string */
519 if ((new->menu_mgr.unpostString) &&
520 (strlen(new->menu_mgr.unpostString) > 0))
522 if (_XwMapKeyEvent (new->menu_mgr.unpostString,
523 &new->menu_mgr.unpostEventType,
524 &tempKeysym,
525 &new->menu_mgr.unpostModifiers) == FALSE)
527 /* Invalid unpost string; use the previous one */
528 XtWarning("MenuMgr: Invalid unpost event; using previous setting");
529 new->menu_mgr.unpostString = current->menu_mgr.unpostString;
530 new->menu_mgr.unpostEventType = current->menu_mgr.unpostEventType;
531 new->menu_mgr.unpostKey = current->menu_mgr.unpostKey;
532 new->menu_mgr.unpostModifiers = current->menu_mgr.unpostModifiers;
534 else
536 /* Valid unpost string */
537 new->menu_mgr.unpostKey = XKeysymToKeycode(XtDisplay(new),
538 tempKeysym);
539 new->menu_mgr.unpostString = (String)
540 strcpy (XtMalloc (XwStrlen (new->menu_mgr.unpostString) + 1),
541 new->menu_mgr.unpostString);
544 else
546 new->menu_mgr.unpostString = NULL;
547 new->menu_mgr.unpostEventType = 0;
548 new->menu_mgr.unpostKey = 0;
549 new->menu_mgr.unpostModifiers = 0;
553 * Don't free up the buffer holding the old unpost string.
554 * This is to be done by our subclass.
558 /* Handle the case of a changed kbd select string */
560 if (current->menu_mgr.kbdSelectString != new->menu_mgr.kbdSelectString)
562 /* Allocate a new buffer to hold the string */
563 if ((new->menu_mgr.kbdSelectString) &&
564 (strlen(new->menu_mgr.kbdSelectString) > 0))
566 if (_XwMapKeyEvent (new->menu_mgr.kbdSelectString,
567 &new->menu_mgr.kbdSelectEventType,
568 &tempKeysym,
569 &new->menu_mgr.kbdSelectModifiers) == FALSE)
571 /* Invalid kbd select string; use the previous one */
572 XtWarning
573 ("MenuMgr: Invalid keyboard select event; using previous setting");
574 new->menu_mgr.kbdSelectString = current->menu_mgr.kbdSelectString;
575 new->menu_mgr.kbdSelectEventType =
576 current->menu_mgr.kbdSelectEventType;
577 new->menu_mgr.kbdSelectKey = current->menu_mgr.kbdSelectKey;
578 new->menu_mgr.kbdSelectModifiers =
579 current->menu_mgr.kbdSelectModifiers;
581 else
583 /* Valid kbd select string */
584 new->menu_mgr.kbdSelectKey = XKeysymToKeycode(XtDisplay(new),
585 tempKeysym);
586 new->menu_mgr.kbdSelectString = (String)
587 strcpy (XtMalloc (XwStrlen (new->menu_mgr.kbdSelectString) + 1),
588 new->menu_mgr.kbdSelectString);
591 else
593 new->menu_mgr.kbdSelectString = NULL;
594 new->menu_mgr.kbdSelectEventType = 0;
595 new->menu_mgr.kbdSelectKey = 0;
596 new->menu_mgr.kbdSelectModifiers = 0;
600 * Don't free up the buffer holding the old kbd select string.
601 * This is to be done by our subclass.
605 return (FALSE);
609 /*************************************<->*************************************
611 * Destroy
613 * Description:
614 * -----------
617 * Inputs:
618 * ------
619 * xxxxxxxxxxxx = xxxxxxxxxxxxx
621 * Outputs:
622 * -------
623 * xxxxxxxxxxxx = xxxxxxxxxxxxx
625 * Procedures Called
626 * -----------------
628 *************************************<->***********************************/
630 static void Destroy (mw)
632 XwMenuMgrWidget mw;
635 /* Free up our resources */
637 if (mw->menu_mgr.postString)
638 XtFree (mw->menu_mgr.postString);
640 if (mw->menu_mgr.selectString)
641 XtFree (mw->menu_mgr.selectString);
643 if (mw->menu_mgr.unpostString)
644 XtFree (mw->menu_mgr.unpostString);
646 if (mw->menu_mgr.kbdSelectString)
647 XtFree (mw->menu_mgr.kbdSelectString);
649 XtFree ((char *)(mw->menu_mgr.menuBtnAccelTable));
650 XtFree ((char *)(mw->menu_mgr.pendingAttachList));