1 /**
2  *
3  * $Id: MenuUtil.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $
4  *
5  * Copyright (C) 1995 Free Software Foundation, Inc.
6  * Copyright (C) 1995-2001 LessTif Development Team
7  *
8  * This file is part of the GNU LessTif Library.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  **/
25 
26 static const char rcsid[] = "$Id: MenuUtil.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $";
27 
28 #include <LTconfig.h>
29 
30 #include <XmI/XmI.h>
31 
32 #include <Xm/XmP.h>
33 #include <Xm/CascadeBP.h>
34 #include <Xm/CascadeBGP.h>
35 #include <Xm/RowColumnP.h>
36 #include <Xm/MenuShellP.h>
37 #include <Xm/MenuUtilP.h>
38 #include <Xm/TearOffP.h>
39 #include <Xm/Screen.h>
40 #include <Xm/ScreenP.h>
41 #include <Xm/XmosP.h>
42 
43 #include <XmI/DebugUtil.h>
44 
45 
46 extern Boolean
_XmMenuGetInPMMode(Widget w)47 _XmMenuGetInPMMode(Widget w)
48 {
49     XmMenuState state = _XmGetMenuState(w);
50 
51     return state->MU_InPMMode;
52 }
53 
54 
55 extern void
_XmMenuSetInPMMode(Widget w,Boolean flag)56 _XmMenuSetInPMMode(Widget w, Boolean flag)
57 {
58     XmMenuState state = _XmGetMenuState(w);
59 
60     state->MU_InPMMode = flag;
61 }
62 
63 
64 extern Boolean
_XmGetInDragMode(Widget w)65 _XmGetInDragMode(Widget w)
66 {
67     XmMenuState state = _XmGetMenuState(w);
68 
69     return state->MU_InDragMode;
70 }
71 
72 
73 extern void
_XmSetInDragMode(Widget w,Boolean flag)74 _XmSetInDragMode(Widget w, Boolean flag)
75 {
76     XmMenuState state = _XmGetMenuState(w);
77 
78     DEBUGOUT(_LtDebug(__FILE__, w, "_XmSetInDragMode() - %s\n",
79     		_LtDebugBoolean2String(flag)));
80     state->MU_InDragMode = flag;
81 }
82 
83 
84 extern Widget
_XmGetRC_PopupPosted(Widget rc)85 _XmGetRC_PopupPosted(Widget rc)
86 {
87     if (!XmIsRowColumn(rc))
88     {
89 	return NULL;
90     }
91 
92     if (RC_PopupPosted(rc))
93     {
94 	return XtParent(RC_PopupPosted(rc));
95     }
96     else
97     {
98 	return NULL;		/* FIX ME */
99     }
100 }
101 
102 
103 /*
104  * A wrapper around the Xt Intrinsic's pointer grabbing. This
105  * one retries a failing grab for several times and if all fails
106  * spits out a warning message.
107  */
108 extern int
_XmGrabPointer(Widget w,int owner_events,unsigned int event_mask,int pointer_mode,int keyboard_mode,Window confine_to,Cursor cursor,Time time)109 _XmGrabPointer(Widget w,
110 	       int owner_events,
111 	       unsigned int event_mask,
112 	       int pointer_mode,
113 	       int keyboard_mode,
114 	       Window confine_to,
115 	       Cursor cursor,
116 	       Time time)
117 {
118     int result, retries;
119 
120     DEBUGOUT(_LtDebug(__FILE__, w, "_XmGrabPointer()\n"));
121 
122     for (retries = 4; retries >= 0; retries--)
123     {
124 	result = XtGrabPointer(XmIsGadget(w) ? XtParent(w) : w,
125 			       owner_events, event_mask,
126 			       pointer_mode, keyboard_mode,
127 			       confine_to, cursor, time);
128 
129 	if (result == GrabSuccess)
130 	{
131 	    return result;
132 	}
133 
134 	DEBUGOUT(_LtDebug(__FILE__, w, "_XmGrabPointer => %s, trying again\n",
135 			  (result == AlreadyGrabbed) ? "AlreadyGrabbed" :
136 			  (result == GrabInvalidTime) ? "GrabInvalidTime" :
137 			  (result == GrabNotViewable) ? "GrabNotViewable" :
138 			  (result == GrabFrozen) ? "GrabFrozen" : "??"));
139 
140 	if (retries)
141 	{
142 	    _XmSleep(1);
143 	}
144     }
145 
146     _XmWarning(w, "Can't grab the pointer.");
147 
148     return result;
149 }
150 
151 
152 extern void
_XmUngrabPointer(Widget w,Time t)153 _XmUngrabPointer(Widget w, Time t)
154 {
155     DEBUGOUT(_LtDebug(__FILE__, w, "_XmUngrabPointer\n"));
156 
157     XtUngrabPointer(XmIsGadget(w) ? XtParent(w) : w, t);
158 }
159 
160 
161 /*
162  * Same as the _XmGrabPointer wrapper above, but this time for grabbing
163  * the keyboard.
164  */
165 extern int
_XmGrabKeyboard(Widget widget,int owner_events,int pointer_mode,int keyboard_mode,Time time)166 _XmGrabKeyboard(Widget widget,
167 		int owner_events,
168 		int pointer_mode,
169 		int keyboard_mode,
170 		Time time)
171 {
172     int result, retries;
173 
174     DEBUGOUT(_LtDebug(__FILE__, widget, "_XmGrabKeyboard()\n"));
175 
176     for (retries = 4; retries >= 0; retries--)
177     {
178 	result = XtGrabKeyboard(XmIsGadget(widget) ? XtParent(widget) : widget,
179 				owner_events,
180 				pointer_mode, keyboard_mode,
181 				time);
182 
183 	if (result == GrabSuccess)
184 	{
185 	    return result;
186 	}
187 
188 	DEBUGOUT(_LtDebug(__FILE__, widget,
189 			  "_XmGrabKeyboard : trying again\n"));
190 
191 	if (retries)
192 	{
193 	    _XmSleep(1);
194 	}
195     }
196 
197     _XmWarning(widget, "Can't grab the keyboard.");
198 
199     return result;
200 }
201 
202 
203 extern void
_XmUngrabKeyboard(Widget w,Time t)204 _XmUngrabKeyboard(Widget w, Time t)
205 {
206     DEBUGOUT(_LtDebug(__FILE__, w, "_XmUngrabKeyboard\n"));
207 
208     XtUngrabKeyboard(XmIsGadget(w) ? XtParent(w) : w, t);
209 }
210 
211 
212 extern void
_XmMenuEscape(Widget w,XEvent * ev,String * params,Cardinal * num_params)213 _XmMenuEscape(Widget w, XEvent *ev, String *params, Cardinal *num_params)
214 {
215     /* Widget cb = NULL; */
216     XmRowColumnWidget rc;
217 
218     if (ev && !_XmIsEventUnique(ev))
219     {
220 	return;
221     }
222 
223     _XmRecordEvent(ev);
224 
225     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuEscape()\n"));
226     DEBUGOUT(_LtDebug("ESC", w, "_XmMenuEscape()\n"));
227     if (XmIsRowColumn(w))
228     {
229 	rc = (XmRowColumnWidget)w;
230     }
231     else
232     {
233 	rc = (XmRowColumnWidget)XtParent(w);
234     }
235     DEBUGOUT(_LtDebug(__FILE__, w, "    Menu      %s (%s)\n", XtName(rc), _LtDebugRcType2String(RC_Type(rc))));
236     DEBUGOUT(_LtDebug("ESC", w, "    Menu      %s (%s)\n", XtName(rc), _LtDebugRcType2String(RC_Type(rc))));
237 
238     if (RC_Type(rc) == XmMENU_BAR)
239     {
240     	if (RC_PopupPosted(rc))
241     	{
242 	    /* This should not happen!  If a menu bar has a menu posted the
243 	       events should be going to that menu, not the menu bar
244 	     */
245 	    RCClass_MenuProcs(XtClass(rc))(XmMENU_BAR_CLEANUP,
246 						 (Widget)rc,
247 						 NULL);
248     	}
249     	else
250     	{
251     	}
252     }
253     else if (_XmIsActiveTearOff((Widget)rc))
254     {
255 	DEBUGOUT(_LtDebug(__FILE__, w, "    Menu is TornOff\n"));
256 	DEBUGOUT(_LtDebug("ESC", w, "    Menu is TornOff\n"));
257 	if (RC_PopupPosted(rc))
258 	{
259 	Boolean poppedUp;
260 	Widget menu = RC_PopupPosted(rc);
261 
262 	    DEBUGOUT(_LtDebug(__FILE__, w, "    Menu has %s posted\n", XtName(menu)));
263 	    DEBUGOUT(_LtDebug("ESC", w, "    Menu has %s posted\n", XtName(menu)));
264 	    while (RC_PopupPosted(menu))
265 	    {
266 		menu = RC_PopupPosted(menu);
267 		DEBUGOUT(_LtDebug(__FILE__, w, "    which has %s posted\n", XtName(menu)));
268 	    }
269 	    RC_MenuShellPopdown(RC_CascadeBtn(menu), ev, &poppedUp);
270 	}
271 	else
272 	{
273 	    DEBUGOUT(_LtDebug(__FILE__, w, "    Menu has nothing posted\n"));
274 	    DEBUGOUT(_LtDebug("ESC", w, "    Menu has nothing posted\n"));
275 	    if (RC_TornOff(rc))
276 	    {
277 		RCClass_MenuProcs(XtClass(rc))(XmMENU_DISARM, (Widget)rc, NULL);
278 		_XmDismissTearOff(XtParent(rc), NULL, NULL);
279 	    }
280 	    else
281 	    {
282 	    Boolean poppedUp;
283 	    Widget cb = RC_CascadeBtn(rc);
284 	    unsigned char type = XmIsGadget(cb) ? LabG_MenuType(cb) : Lab_MenuType(cb);
285 
286 		if (type == XmMENU_BAR)
287 		{
288 		    RCClass_MenuProcs(XtClass(XtParent(cb)))(XmMENU_BAR_CLEANUP,
289 							 XtParent(cb),
290 							 NULL);
291 		}
292 		else
293 		{
294 		    RC_MenuShellPopdown(cb, ev, &poppedUp);
295 		    _XmMenuArmItem(cb);
296 		}
297 	    }
298 	}
299     }
300     else if (RC_CascadeBtn(rc))
301     {
302     Boolean poppedUp;
303     Widget cb = RC_CascadeBtn(rc);
304     unsigned char type = XmIsGadget(cb) ? LabG_MenuType(cb) : Lab_MenuType(cb);
305 
306 	DEBUGOUT(_LtDebug(__FILE__, w, "    Posted by %s (%s)\n", XtName(cb), _LtDebugRcType2String(type)));
307 	DEBUGOUT(_LtDebug("ESC", w, "    Posted by %s (%s)\n", XtName(cb), _LtDebugRcType2String(type)));
308 
309 	if (type == XmMENU_BAR)
310 	{
311 	    RCClass_MenuProcs(XtClass(XtParent(cb)))(XmMENU_BAR_CLEANUP,
312 						 XtParent(cb),
313 						 NULL);
314 	}
315 	else
316 	{
317 	    RC_MenuShellPopdown(cb, ev, &poppedUp);
318 	    _XmMenuArmItem(cb);
319 	}
320     }
321     else
322     {
323     Boolean poppedUp;
324 
325 	DEBUGOUT(_LtDebug(__FILE__, w, "    must be a popup\n"));
326     	RC_MenuButtonPopdown(MGR_ActiveChild(rc), ev, &poppedUp);
327     }
328     return;
329 }
330 
331 
332 extern void
_XmMenuTraverseLeft(Widget w,XEvent * ev,String * params,Cardinal * num_params)333 _XmMenuTraverseLeft(Widget w,
334 		    XEvent *ev,
335 		    String *params,
336 		    Cardinal *num_params)
337 {
338     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuTraverseLeft()\n"));
339 
340     if (!_XmIsEventUnique(ev)) return;
341     _XmRecordEvent(ev);
342     /* rws 27 Mar 1999
343        If we are in a menu that also has gadgets, and the gadget is the
344        currently armed item, and the pointer is over a widget in the menu,
345        the widget will get the event that should be going to the gadget, as
346        it should.  In this case we need to traverse from the gadget.
347        (nedit Preferences menu)
348      */
349     if (MGR_ActiveChild(XtParent(w)) && XmIsGadget(MGR_ActiveChild(XtParent(w))))
350     {
351 	_XmMenuTraversalHandler(XtParent(w), MGR_ActiveChild(XtParent(w)), XmTRAVERSE_LEFT);
352     }
353     else
354     {
355 	_XmMenuTraversalHandler(XtParent(w), w, XmTRAVERSE_LEFT);
356     }
357 }
358 
359 
360 extern void
_XmMenuTraverseRight(Widget w,XEvent * ev,String * params,Cardinal * num_params)361 _XmMenuTraverseRight(Widget w,
362 		     XEvent *ev,
363 		     String *params,
364 		     Cardinal *num_params)
365 {
366     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuTraverseRight()\n"));
367 
368     if (!_XmIsEventUnique(ev)) return;
369     _XmRecordEvent(ev);
370     if (MGR_ActiveChild(XtParent(w)) && XmIsGadget(MGR_ActiveChild(XtParent(w))))
371     {
372 	_XmMenuTraversalHandler(XtParent(w), MGR_ActiveChild(XtParent(w)), XmTRAVERSE_RIGHT);
373     }
374     else
375     {
376 	_XmMenuTraversalHandler(XtParent(w), w, XmTRAVERSE_RIGHT);
377     }
378 }
379 
380 
381 extern void
_XmMenuTraverseUp(Widget w,XEvent * ev,String * params,Cardinal * num_params)382 _XmMenuTraverseUp(Widget w,
383 		  XEvent *ev,
384 		  String *params,
385 		  Cardinal *num_params)
386 {
387     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuTraverseUp()\n"));
388 
389     if (!_XmIsEventUnique(ev)) return;
390     _XmRecordEvent(ev);
391     if (MGR_ActiveChild(XtParent(w)) && XmIsGadget(MGR_ActiveChild(XtParent(w))))
392     {
393 	_XmMenuTraversalHandler(XtParent(w), MGR_ActiveChild(XtParent(w)), XmTRAVERSE_UP);
394     }
395     else
396     {
397 	_XmMenuTraversalHandler(XtParent(w), w, XmTRAVERSE_UP);
398     }
399 }
400 
401 
402 extern void
_XmMenuTraverseDown(Widget w,XEvent * ev,String * params,Cardinal * num_params)403 _XmMenuTraverseDown(Widget w,
404 		    XEvent *ev,
405 		    String *params,
406 		    Cardinal *num_params)
407 {
408     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuTraverseDown()\n"));
409     DEBUGOUT(_LtDebug2("TRAV", XtParent(w), w, "_XmMenuTraverseDown() - %s %s\n",
410     	_XmIsEventUnique(ev) ? "unique" : "not-unique",
411     	MGR_ActiveChild(XtParent(w)) ? XtName(MGR_ActiveChild(XtParent(w))) : "no-active"
412     	));
413 
414     if (!_XmIsEventUnique(ev)) return;
415     _XmRecordEvent(ev);
416     if (MGR_ActiveChild(XtParent(w)) && XmIsGadget(MGR_ActiveChild(XtParent(w))))
417     {
418 	_XmMenuTraversalHandler(XtParent(w), MGR_ActiveChild(XtParent(w)), XmTRAVERSE_DOWN);
419     }
420     else
421     {
422 	_XmMenuTraversalHandler(XtParent(w), w, XmTRAVERSE_DOWN);
423     }
424 }
425 
426 
427 extern void
_XmRC_GadgetTraverseDown(Widget w,XEvent * ev,String * params,Cardinal * num_params)428 _XmRC_GadgetTraverseDown(Widget w,
429 			 XEvent *ev,
430 			 String *params,
431 			 Cardinal *num_params)
432 {
433     DEBUGOUT(_LtDebug(__FILE__, w, "_XmRC_GadgetTraverseDown()\n"));
434     DEBUGOUT(_LtDebug("TRAV", w, "_XmRC_GadgetTraverseDown() - %s %s\n",
435     	_XmIsEventUnique(ev) ? "unique" : "not-unique",
436     	MGR_ActiveChild((w)) ? XtName(MGR_ActiveChild((w))) : "no-active"
437     	));
438 
439     if (!_XmIsEventUnique(ev)) return;
440     _XmRecordEvent(ev);
441     if (RC_Type(w) != XmMENU_BAR && MGR_ActiveChild(w) /*&& XmIsGadget(MGR_ActiveChild(w))*/)
442     {
443 	_XmMenuTraversalHandler(w, MGR_ActiveChild(w), XmTRAVERSE_DOWN);
444     }
445 }
446 
447 
448 extern void
_XmRC_GadgetTraverseUp(Widget w,XEvent * ev,String * params,Cardinal * num_params)449 _XmRC_GadgetTraverseUp(Widget w,
450 		       XEvent *ev,
451 		       String *params,
452 		       Cardinal *num_params)
453 {
454     DEBUGOUT(_LtDebug(__FILE__, w, "_XmRC_GadgetTraverseUp()\n"));
455 
456     if (!_XmIsEventUnique(ev)) return;
457     _XmRecordEvent(ev);
458     if (RC_Type(w) != XmMENU_BAR && MGR_ActiveChild(w) /*&& XmIsGadget(MGR_ActiveChild(w))*/)
459     {
460 	_XmMenuTraversalHandler(w, MGR_ActiveChild(w), XmTRAVERSE_UP);
461     }
462 }
463 
464 
465 extern void
_XmRC_GadgetTraverseLeft(Widget w,XEvent * ev,String * params,Cardinal * num_params)466 _XmRC_GadgetTraverseLeft(Widget w,
467 			 XEvent *ev,
468 			 String *params,
469 			 Cardinal *num_params)
470 {
471     DEBUGOUT(_LtDebug(__FILE__, w, "_XmRC_GadgetTraverseLeft()\n"));
472 
473     if (!_XmIsEventUnique(ev)) return;
474     _XmRecordEvent(ev);
475     if (MGR_ActiveChild(w) /*&& XmIsGadget(MGR_ActiveChild(w))*/)
476     {
477 	_XmMenuTraversalHandler(w, MGR_ActiveChild(w), XmTRAVERSE_LEFT);
478     }
479 }
480 
481 
482 extern void
_XmRC_GadgetTraverseRight(Widget w,XEvent * ev,String * params,Cardinal * num_params)483 _XmRC_GadgetTraverseRight(Widget w,
484 			  XEvent *ev,
485 			  String *params,
486 			  Cardinal *num_params)
487 {
488     DEBUGOUT(_LtDebug(__FILE__, w, "_XmRC_GadgetTraverseRight()\n"));
489 
490     if (!_XmIsEventUnique(ev)) return;
491     _XmRecordEvent(ev);
492     if (MGR_ActiveChild(w) /*&& XmIsGadget(MGR_ActiveChild(w))*/)
493     {
494 	_XmMenuTraversalHandler(w, MGR_ActiveChild(w), XmTRAVERSE_RIGHT);
495     }
496 }
497 
498 
499 /*
500  * apparently has something to do with the MenuProcEntry.
501  */
502 extern XtPointer
_XmGetMenuProcContext(void)503 _XmGetMenuProcContext(void)
504 {
505     return NULL;
506 }
507 
508 
509 /*
510  * apparently has something to do with the MenuProcEntry.
511  */
512 extern void
_XmSaveMenuProcContext(XtPointer address)513 _XmSaveMenuProcContext(XtPointer address)
514 {
515 }
516 
517 
518 extern void
_XmSetMenuTraversal(Widget wid,Boolean traversalOn)519 _XmSetMenuTraversal(Widget wid, Boolean traversalOn)
520 {
521 }
522 
523 
524 extern Widget
_XmMenuNextItem(Widget menu,Widget current_item)525 _XmMenuNextItem(Widget menu, Widget current_item)
526 {
527     int current_item_index;
528     int next_item_index;
529 
530     /* printf("in XmMenuNextItem\n"); */
531     for (current_item_index = 0;
532          current_item_index < (int)MGR_NumChildren(menu);
533          current_item_index++)
534     {
535 	if (MGR_Children(menu)[current_item_index] == current_item)
536 	{
537 	    break;
538 	}
539     }
540 
541     {
542 	int valid_control;
543 
544 	next_item_index = current_item_index;
545 	if (MGR_NumChildren(menu) > 1)
546 	{
547 	    for (valid_control = current_item_index + 1 < (int)MGR_NumChildren(menu) ? current_item_index + 1 : 0; valid_control != current_item_index; valid_control = valid_control + 1 < MGR_NumChildren(menu) ? valid_control + 1 : 0)
548 	    {
549 	      Widget w = MGR_Children(menu)[valid_control];
550 	      /* printf("Examining %s (valid_control
551 		 %d)\n",XtName(w),valid_control); */
552 	      /* printf("Newmenus\n"); */
553 	    if (w && XtIsSensitive(w) && XtIsManaged(w) &&
554 		((XmIsLabel(w) && (((XmLabelClassRec *)(XtClass(w)))->label_class.menuProcs) && Prim_TraversalOn(w)) ||
555 		 (XmIsLabelGadget(w) && (((XmLabelGadgetClassRec *)(XtClass(w)))->label_class.menuProcs) && G_TraversalOn(w))))
556 		{
557 		  /* printf("%s passed test\n",XtName(w)); */
558 
559 		    next_item_index = valid_control;
560 		    break;
561 		}
562 	    }
563 	}
564     }
565     /*    printf("returning %s index %d\n",
566 	   XtName(MGR_Children(menu)[next_item_index]),
567 	   next_item_index); */
568     return(MGR_Children(menu)[next_item_index]);
569 }
570 
571 
572 static Widget
_XmMenuPrevItem(Widget menu,Widget current_item)573 _XmMenuPrevItem(Widget menu, Widget current_item)
574 {
575     int current_item_index;
576     int next_item_index;
577 
578     for (current_item_index = 0; current_item_index < (int)MGR_NumChildren(menu); current_item_index++)
579     {
580 	if (MGR_Children(menu)[current_item_index] == current_item)
581 	{
582 	    break;
583 	}
584     }
585     {
586 	int valid_control;
587 
588 	next_item_index = current_item_index;
589 	if (MGR_NumChildren(menu) > 1)
590 	{
591 	    for (valid_control = current_item_index - 1 >= 0 ? current_item_index - 1 : MGR_NumChildren(menu) - 1; valid_control != current_item_index; valid_control = valid_control - 1 >= 0 ? valid_control - 1 : MGR_NumChildren(menu) - 1)
592 	    {
593 	    Widget w = MGR_Children(menu)[valid_control];
594 
595     if (w && XtIsSensitive(w) && XtIsManaged(w) &&
596 	    ((XmIsLabel(w) && (((XmLabelClassRec *)(XtClass(w)))->label_class.menuProcs) && Prim_TraversalOn(w)) ||
597 	     (XmIsLabelGadget(w) && (((XmLabelGadgetClassRec *)(XtClass(w)))->label_class.menuProcs) && G_TraversalOn(w))))
598 		{
599 			next_item_index = valid_control;
600 			break;
601 		}
602 	    }
603 	}
604     }
605 
606     return(MGR_Children(menu)[next_item_index]);
607 }
608 
609 
610 extern void
_XmMenuDisarmItem(Widget w)611 _XmMenuDisarmItem(Widget w)
612 {
613     if (w &&
614 	    ((XmIsLabel(w) && (((XmLabelClassRec *)(XtClass(w)))->label_class.menuProcs)) ||
615 	     (XmIsLabelGadget(w) && (((XmLabelGadgetClassRec *)(XtClass(w)))->label_class.menuProcs))))
616     {
617 	Lab_MenuDisarm(w);
618     }
619 }
620 
621 
622 extern void
_XmMenuArmItem(Widget w)623 _XmMenuArmItem(Widget w)
624 {
625     DEBUGOUT(_LtDebug(__FILE__, w, "_XmMenuArmItem()\n"));
626     DEBUGOUT(_LtDebug("MENU", w, "_XmMenuArmItem() - %s\n"
627     	));
628     if (w && (!XtIsSensitive(w) || !XtIsManaged(w) ||
629 	    (!(XmIsLabel(w) && (((XmLabelClassRec *)(XtClass(w)))->label_class.menuProcs) && Prim_TraversalOn(w)) &&
630 	     !(XmIsLabelGadget(w) && (((XmLabelGadgetClassRec *)(XtClass(w)))->label_class.menuProcs) && G_TraversalOn(w)))))
631     {
632     Widget next;
633 
634     	next = _XmMenuNextItem(XtParent(w),w);
635     	if (next == w)
636     	{
637     		w = NULL;
638     	}
639     	else
640     	{
641     		w = next;
642     	}
643     }
644     if (w)
645     {
646 	if (XmIsGadget(w))
647 	{
648 	    _XmMenuFocus(XtParent(w), XmMENU_FOCUS_SET, CurrentTime);
649 	}
650 	else
651 	{
652 	    _XmMenuFocus(w, XmMENU_FOCUS_SET, CurrentTime);
653 	}
654 	Lab_MenuArm(w);
655     }
656 }
657 
658 
659 extern void
_XmMenuTraversalHandler(Widget w,Widget pw,XmTraversalDirection direction)660 _XmMenuTraversalHandler(Widget w, Widget pw, XmTraversalDirection direction)
661 {
662     DEBUGOUT(_LtDebug2(__FILE__, w, pw, "_XmMenuTraversalHandler()\n"));
663     switch(direction)
664     {
665     case XmTRAVERSE_DOWN:
666     	if ((XmIsCascadeButton(pw) && CB_Submenu(pw)) && RC_Type(w) == XmMENU_BAR)
667     	{
668 	    _XmWarning(pw, "%s(%i) - Traversal down in MENU_BAR not written yet!", __FILE__,__LINE__);
669 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Post %s\n", XtName(CB_Submenu(pw))));
670 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Arm %s\n", XtName(MGR_Children(CB_Submenu(pw))[0])));
671     	}
672     	else if (RC_Type(w) == XmMENU_PULLDOWN || RC_Type(w) == XmMENU_POPUP)
673     	{
674 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Arm %s\n", XtName(_XmMenuNextItem(w, pw))));
675 	    _XmMenuDisarmItem(pw);
676 	    _XmMenuArmItem(_XmMenuNextItem(w,pw));
677 
678 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Active menu item is now %s\n", XtName(_XmMenuNextItem(w, pw))));
679     	}
680     	else
681     	{
682 	    _XmWarning(pw, "%s(%i) - Traversal down in this situation not written yet!\n    w = %s pw = %s",
683 	    		__FILE__,__LINE__,
684 	    		XtName(w), XtName(pw));
685     	}
686     	break;
687     case XmTRAVERSE_UP:
688     	if (RC_Type(w) == XmMENU_PULLDOWN || RC_Type(w) == XmMENU_POPUP)
689     	{
690 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Arm %s\n", XtName(_XmMenuPrevItem(w, pw))));
691 	    _XmMenuDisarmItem(pw);
692 	    _XmMenuArmItem(_XmMenuPrevItem(w,pw));
693 
694 	    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    Active menu item is now %s\n", XtName(_XmMenuPrevItem(w, pw))));
695     	}
696     	else
697     	{
698 	    _XmWarning(pw, "%s(%i) - Traversal up in this situation not written yet!\n    w = %s pw = %s",
699 	    		__FILE__,__LINE__,
700 	    		XtName(w), XtName(pw));
701     	}
702     	break;
703     case XmTRAVERSE_LEFT:
704     	if (RC_Type(w) == XmMENU_BAR)
705     	{
706     		Cardinal num_params = 0;
707 
708 		if (XmIsGadget(_XmMenuPrevItem(w,pw)))
709 		{
710 		    (*GC_ArmAndActivate(XtClass(_XmMenuPrevItem(w,pw))))(_XmMenuPrevItem(w,pw), NULL, NULL, &num_params);
711 		}
712 		else
713 		{
714 		    (*PrimC_ArmAndActivate(XtClass(_XmMenuPrevItem(w,pw))))(_XmMenuPrevItem(w,pw), NULL, NULL, &num_params);
715 		}
716     	}
717     	else
718     	{
719 	    if (RC_CascadeBtn(w) && RC_Type(XtParent(RC_CascadeBtn(w))) != XmMENU_BAR)
720 	    {
721 	    Widget cb = RC_CascadeBtn(w);
722 	    Boolean poppedUp;
723 
724 	    	RC_MenuShellPopdown(cb, NULL, &poppedUp);
725 	    	_XmMenuArmItem(cb);
726 	    }
727 	    else if (RC_LastSelectToplevel(w))
728 	    {
729 		if (RC_CascadeBtn(w)  && !RC_TornOff(w))
730 		{
731 		    DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    RC_LastSelectTopLevel %s %s\n",
732 			    XtName(RC_LastSelectToplevel(w)),
733 			    /* XtName(MGR_ActiveChild(RC_LastSelectToplevel(w))), */
734 			    XtName(RC_CascadeBtn(w))));
735 		    _XmMenuTraversalHandler( RC_LastSelectToplevel(w),
736 				    RC_CascadeBtn(w),
737 				    /* MGR_ActiveChild(RC_LastSelectToplevel(w)), */
738 				    direction);
739 		}
740 	    }
741 	    else
742 	    {
743 	    	_XmWarning(w, "%s:_XmMenuTraversalHandler(%d) - I have no idea what todo!",
744 	    		__FILE__, __LINE__);
745 	    }
746     	}
747     	break;
748     case XmTRAVERSE_RIGHT:
749     	if (RC_Type(w) == XmMENU_BAR)
750     	{
751     		Cardinal num_params = 0;
752 
753 		if (XmIsGadget(_XmMenuNextItem(w,pw)))
754 		{
755 		    (*GC_ArmAndActivate(XtClass(_XmMenuNextItem(w,pw))))(_XmMenuNextItem(w,pw), NULL, NULL, &num_params);
756 		}
757 		else
758 		{
759 		    (*PrimC_ArmAndActivate(XtClass(_XmMenuNextItem(w,pw))))(_XmMenuNextItem(w,pw), NULL, NULL, &num_params);
760 		}
761     	}
762     	else if (RC_Type(w) == XmMENU_PULLDOWN || RC_Type(w) == XmMENU_POPUP)
763     	{
764     		if (XmIsCascadeButton(pw) && CB_Submenu(pw))
765     		{
766     		Cardinal num_params = 0;
767 
768     			(*PrimC_ArmAndActivate(XtClass(pw)))(pw, NULL, NULL, &num_params);
769 			RCClass_MenuTraverse(CB_Submenu(pw), XmTRAVERSE_HOME);
770     		}
771     		else if (XmIsCascadeButtonGadget(pw) && CBG_Submenu(pw))
772     		{
773     		Cardinal num_params = 0;
774 
775     			(*GC_ArmAndActivate(XtClass(pw)))(pw, NULL, NULL, &num_params);
776 			RCClass_MenuTraverse(CBG_Submenu(pw), XmTRAVERSE_HOME);
777     		}
778     		else
779     		{
780 		    if (RC_CascadeBtn(w)  && !RC_TornOff(w))
781 		    {
782 			DEBUGOUT(_LtDebug2(__FILE__, w, pw, "    RC_LastSelectTopLevel %s %s\n",
783 			    XtName(RC_LastSelectToplevel(w)),
784 			    /* XtName(MGR_ActiveChild(RC_LastSelectToplevel(w))), */
785 			    XtName(RC_CascadeBtn(w))));
786 			if (RC_Type(RC_LastSelectToplevel(w)) == XmMENU_BAR)
787 			{
788 			    DEBUGOUT(_LtDebug2("TRAV", w, pw, "    RC_LastSelectTopLevel %s %s %s posted\n",
789 				XtName(RC_LastSelectToplevel(w)),
790 				XtName(RC_CascadeBtn(w)),
791 				RC_PopupPosted(w) ? XtName(RC_PopupPosted(w)) : "nothing"
792 				));
793 			    _XmMenuTraversalHandler( RC_LastSelectToplevel(w),
794 				    RC_CascadeBtn(RC_PopupPosted(RC_LastSelectToplevel(w))),
795 				    direction);
796 			}
797 		    }
798     		}
799     	}
800     	else
801     	{
802 	    _XmWarning(pw, "%s(%i) - Traversal right in this situation not written yet!", __FILE__,__LINE__);
803     	}
804     	break;
805     default:
806     	_XmWarning(pw, "%s(%i) - Traversal request in invalid direction", __FILE__,__LINE__);
807     	break;
808     }
809 }
810 
811 static int num_saved = 0;
812 static String saved_trans[32];
813 
814 
815 extern void
_XmSaveCoreClassTranslations(Widget widget)816 _XmSaveCoreClassTranslations(Widget widget)
817 {
818     saved_trans[num_saved] = CoreClassTranslations(widget);
819     num_saved++;
820 }
821 
822 
823 extern void
_XmRestoreCoreClassTranslations(Widget widget)824 _XmRestoreCoreClassTranslations(Widget widget)
825 {
826     if (num_saved > 0)
827     {
828 	num_saved--;
829 	CoreClassTranslations(widget) = saved_trans[num_saved];
830     }
831 }
832 
833 
834 extern void
XmSetMenuCursor(Display * display,Cursor cursorId)835 XmSetMenuCursor(Display *display, Cursor cursorId)
836 {
837     int	i;
838 
839     /* Set the menuCursor in the screen object for each screen in the display.
840      * But don't bother with that pesky resource interface.
841      */
842 
843     if (display && cursorId)
844 	for (i = ScreenCount(display) - 1; i >= 0; i--)
845 	    Screen_MenuCursor(XmGetXmScreen(ScreenOfDisplay(display, i))) =
846 		cursorId;
847 }
848 
849 
850 extern Cursor
XmGetMenuCursor(Display * display)851 XmGetMenuCursor(Display *display)
852 {
853     return _XmGetMenuCursorByScreen(DefaultScreenOfDisplay(display));
854 }
855 
856 
857 extern XmMenuState
_XmGetMenuState(Widget widget)858 _XmGetMenuState(Widget widget)
859 {
860     XmScreenInfo *info = _XmGetScreenInfo(XmGetXmScreen(XtScreen(widget)));
861 
862     return (XmMenuState)info->menu_state;
863 }
864 
865 #if XmVERSION > 1
866 /* Use routines in PopupUtil.c if a 2.0 build */
867 #else
868 /* For the prototype police */
869 extern void _XmPopup(Widget shell, XtGrabKind grab_kind);
870 extern void _XmPopdown(Widget shell);
871 
872 extern void
_XmPopup(Widget shell,XtGrabKind grab_kind)873 _XmPopup(Widget shell, XtGrabKind grab_kind)
874 {
875     XtPopup(shell, grab_kind);
876 }
877 
878 
879 extern void
_XmPopdown(Widget shell)880 _XmPopdown(Widget shell)
881 {
882     XtPopdown(shell);
883 }
884 #endif /* XmVERSION > 1 */
885