One more check on valid display which is known to be in the startup
[xcircuit.git] / Xw / MenuBtn.c
blob3861eafb38e2f69f4bef6b79d47cfa5168f90189
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: MenuBtn.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Contains code for primitive widget class: MenuButton
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 *#define DEBUG TRUE
30 #undef NLS16
33 * Include files & Static Routine Definitions
35 #include <string.h>
36 #include <X11/IntrinsicP.h>
37 #include <X11/StringDefs.h>
38 #include <X11/keysymdef.h>
39 #include <X11/Xatom.h>
40 #include <X11/Shell.h>
41 #include <Xw/Xw.h>
42 #include <Xw/XwP.h>
43 #include <Xw/MenuBtnP.h>
44 #include <Xw/MenuBtn.h>
46 #ifdef NLS16
47 #include <X11/XHPlib.h>
48 #endif
50 #ifndef XtRWidget
51 #define XtRWidget XtRPointer
52 #endif
54 static void Redisplay();
55 static Boolean SetValues();
56 static void ClassPartInitialize();
57 static void Inverted();
58 static void NonInverted();
59 static void Select();
60 static void Enter();
61 static void Leave();
62 static void Moved();
63 static void Initialize();
64 static void Destroy();
65 static void Realize();
66 static void Resize();
67 static void IdealWidth();
68 static void Unhighlight();
69 static void Highlight();
70 static void SetCascadeEnabled();
71 static void ClearCascadeEnabled();
72 static void EnterParentsWindow();
73 static void SetTraversalType();
74 static void TraverseLeft();
75 static void TraverseRight();
76 static void TraverseNext();
77 static void TraversePrev();
78 static void TraverseHome();
79 static void TraverseUp();
80 static void TraverseDown();
81 static void TraverseNextTop();
82 static void Unmap();
83 static void Visibility();
84 Boolean _XwUniqueEvent();
86 /*************************************<->*************************************
89 * Description: default translation table for class: MenuButton
90 * -----------
92 * Matches events with string descriptors for internal routines.
94 *************************************<->***********************************/
97 static char defaultTranslations[] =
98 "<Btn1Down>: select()\n\
99 <Visible>: visibility()\n\
100 <Unmap>: unmap()\n\
101 <EnterWindow>: enter()\n\
102 <LeaveWindow>: leave()\n\
103 <Motion>: moved()\n\
104 <Key>Select: select()\n\
105 <Key>Left: traverseLeft()\n\
106 <Key>Up: traverseUp()\n\
107 <Key>Right: traverseRight()\n\
108 <Key>Down: traverseDown()\n\
109 <Key>Prior: traversePrev()\n\
110 <Key>Next: traverseNext()\n\
111 <Key>KP_Enter: traverseNextTop()\n\
112 <Key>Home: traverseHome()";
116 /*************************************<->*************************************
119 * Description: action list for class: MenuButton
120 * -----------
122 * Matches string descriptors with internal routines.
124 *************************************<->***********************************/
126 static XtActionsRec actionsList[] =
128 {"select", (XtActionProc) Select},
129 {"visibility", (XtActionProc) Visibility},
130 {"unmap", (XtActionProc) Unmap},
131 {"enter", (XtActionProc) Enter},
132 {"leave", (XtActionProc) Leave},
133 {"moved", (XtActionProc) Moved},
134 {"traverseLeft", (XtActionProc) TraverseLeft },
135 {"traverseRight", (XtActionProc) TraverseRight },
136 {"traverseNext", (XtActionProc) TraverseNext },
137 {"traversePrev", (XtActionProc) TraversePrev },
138 {"traverseHome", (XtActionProc) TraverseHome },
139 {"traverseUp", (XtActionProc) TraverseUp },
140 {"traverseDown", (XtActionProc) TraverseDown },
141 {"traverseNextTop", (XtActionProc) TraverseNextTop },
144 /*************************************<->*************************************
147 * Description: resource list for class: MenuButton
148 * -----------
150 * Provides default resource settings for instances of this class.
151 * To get full set of default settings, examine resouce list of super
152 * classes of this class.
154 *************************************<->***********************************/
156 static XtResource resources[] =
159 XtNborderWidth, XtCBorderWidth,XtRDimension, sizeof(Dimension),
160 XtOffset(XwMenuButtonWidget, core.border_width),
161 XtRString, "0"
165 XtNlabelType, XtCLabelType, XtRLabelType, sizeof(int),
166 XtOffset(XwMenuButtonWidget, menubutton.labelType),
167 XtRString, "string"
171 XtNlabelImage, XtCLabelImage, XtRImage, sizeof(XImage *),
172 XtOffset(XwMenuButtonWidget, menubutton.labelImage),
173 XtRImage, NULL
177 XtNrectColor, XtCRectColor, XtRPixel, sizeof(Pixel),
178 XtOffset(XwMenuButtonWidget, menubutton.rectColor),
179 XtRString, "white"
183 XtNrectStipple, XtCRectStipple, XtRPixmap, sizeof(Pixmap),
184 XtOffset(XwMenuButtonWidget, menubutton.rectStipple),
185 XtRPixmap, NULL
189 XtNcascadeImage, XtCCascadeImage, XtRImage, sizeof(XImage *),
190 XtOffset(XwMenuButtonWidget, menubutton.cascadeImage),
191 XtRImage, NULL
195 XtNmarkImage, XtCMarkImage, XtRImage, sizeof(XImage *),
196 XtOffset(XwMenuButtonWidget, menubutton.markImage),
197 XtRImage, NULL
201 XtNsetMark, XtCSetMark, XtRBoolean, sizeof(Boolean),
202 XtOffset(XwMenuButtonWidget, menubutton.setMark),
203 XtRString, "FALSE"
207 XtNnoPad, XtCNoPad, XtRBoolean, sizeof(Boolean),
208 XtOffset(XwMenuButtonWidget, menubutton.noPad),
209 XtRString, "FALSE"
213 XtNcascadeOn, XtCCascadeOn, XtRWidget, sizeof(Widget),
214 XtOffset(XwMenuButtonWidget, menubutton.cascadeOn),
215 XtRWidget, NULL
219 XtNkbdAccelerator, XtCKbdAccelerator, XtRString, sizeof(caddr_t),
220 XtOffset(XwMenuButtonWidget, menubutton.accelerator),
221 XtRString, NULL
225 XtNhint, XtCHint, XtRString, sizeof(caddr_t),
226 XtOffset(XwMenuButtonWidget, menubutton.hint),
227 XtRString, NULL
231 XtNhintProc, XtCHintProc, XtRFunction, sizeof(XwStrProc),
232 XtOffset(XwMenuButtonWidget, menubutton.hintProc),
233 XtRFunction, NULL
237 XtNmgrOverrideMnemonic, XtCMgrOverrideMnemonic, XtRBoolean,
238 sizeof(Boolean),
239 XtOffset(XwMenuButtonWidget, menubutton.mgrOverrideMnemonic),
240 XtRString, "FALSE"
244 XtNmnemonic, XtCMnemonic, XtRString, sizeof(caddr_t),
245 XtOffset(XwMenuButtonWidget, menubutton.mnemonic),
246 XtRString, NULL
250 XtNhighlightStyle, XtCHighlightStyle, XtRHighlightStyle, sizeof (int),
251 XtOffset (XwPrimitiveWidget, primitive.highlight_style),
252 XtRString, "widget_defined"
256 XtNcascadeSelect, XtCCallback, XtRCallback, sizeof(caddr_t),
257 XtOffset (XwMenuButtonWidget, menubutton.cascadeSelect),
258 XtRPointer, (caddr_t) NULL
262 XtNcascadeUnselect, XtCCallback, XtRCallback, sizeof(caddr_t),
263 XtOffset (XwMenuButtonWidget, menubutton.cascadeUnselect),
264 XtRPointer, (caddr_t) NULL
268 XtNmenuMgrId, XtCMenuMgrId, XtRWidget, sizeof(Widget),
269 XtOffset (XwMenuButtonWidget, menubutton.menuMgr),
270 XtRWidget, NULL
274 /*************************************<->*************************************
277 * Description: global class record for instances of class: MenuButton
278 * -----------
280 * Defines default field settings for this class record.
282 *************************************<->***********************************/
284 XwMenuButtonClassRec XwmenubuttonClassRec =
287 /* core_class fields */
288 /* superclass */ (WidgetClass) &XwbuttonClassRec,
289 /* class_name */ "XwMenuButton",
290 /* widget_size */ sizeof(XwMenuButtonRec),
291 /* class_initialize */ NULL,
292 /* class_part_init */ ClassPartInitialize,
293 /* class_inited */ FALSE,
294 /* initialize */ Initialize,
295 /* initialize_hook */ NULL,
296 /* realize */ Realize,
297 /* actions */ actionsList,
298 /* num_actions */ XtNumber(actionsList),
299 /* resources */ resources,
300 /* num_resources */ XtNumber(resources),
301 /* xrm_class */ NULLQUARK,
302 /* compress_motion */ TRUE,
303 /* compress_exposure */ TRUE,
304 /* compress_enterlv */ TRUE, /* FIX ME LATER */
305 /* visible_interest */ FALSE,
306 /* destroy */ Destroy,
307 /* resize */ Resize,
308 /* expose */ Redisplay,
309 /* set_values */ SetValues,
310 /* set_values_hook */ NULL,
311 /* set_values_almost */ XtInheritSetValuesAlmost,
312 /* get_values_hook */ NULL,
313 /* accept_focus */ NULL,
314 /* version */ XtVersion,
315 /* cb List */ NULL,
316 /* tm_table */ defaultTranslations,
317 /* query_geometry */ NULL, /* FIX ME LATER */
318 /* display_accelerator */ XtInheritDisplayAccelerator,
319 /* extension */ NULL
322 /* primitive class fields */
323 /* border_highlight */ Inverted,
324 /* border_unhighlight */ NonInverted,
325 /* select_proc */ Select,
326 /* release_proc */ NULL,
327 /* toggle_proc */ NULL,
328 /* translations */ NULL,
331 /* button class fields */ 0,
334 /* menubutton class fields */
335 /* ideal width proc */ IdealWidth,
336 /* unhighlight proc */ Unhighlight,
337 /* highlight proc */ Highlight,
338 /* cascade selected */ SetCascadeEnabled,
339 /* cascade unselected*/ ClearCascadeEnabled,
340 /* enter parents win */ EnterParentsWindow,
341 /* cascadeSelectProc */ NULL,
342 /* cascadeUnselectProc */ NULL,
343 /* setTraversalType */ SetTraversalType
346 WidgetClass XwmenubuttonWidgetClass = (WidgetClass)&XwmenubuttonClassRec;
347 WidgetClass XwmenuButtonWidgetClass = (WidgetClass)&XwmenubuttonClassRec;
350 /*************************************<->*************************************
352 * SetCascadeEnabled (mbutton)
354 * Description:
355 * -----------
356 * This routine is called by the Menu Manager to force the menubutton into
357 * thinking that the cascade select callbacks have been recently called.
359 * Inputs:
360 * ------
361 * mbutton = this menubutton widget
363 * Outputs:
364 * -------
366 * Procedures Called
367 * -----------------
369 *************************************<->***********************************/
370 static void SetCascadeEnabled (mbutton)
371 XwMenuButtonWidget mbutton;
373 mbutton->menubutton.cascadeEnabled = TRUE;
376 /*************************************<->*************************************
378 * ClearCascadeEnabled (mbutton)
380 * Description:
381 * -----------
382 * This routine is called by the Menu Manager to force the menubutton into
383 * thinking that the cascade unselect callbacks have been recently called.
385 * Inputs:
386 * ------
387 * mbutton = this menubutton widget
389 * Outputs:
390 * -------
392 * Procedures Called
393 * -----------------
395 *************************************<->***********************************/
396 static void ClearCascadeEnabled (mbutton)
397 XwMenuButtonWidget mbutton;
399 mbutton->menubutton.cascadeEnabled = FALSE;
402 /*************************************<->*************************************
404 * ClassPartInitialize (parameters)
406 * Description:
407 * -----------
410 * Inputs:
411 * ------
413 * Outputs:
414 * -------
416 * Procedures Called
417 * -----------------
419 *************************************<->***********************************/
421 static void ClassPartInitialize (wc)
423 register XwMenuButtonWidgetClass wc;
426 register XwMenuButtonWidgetClass super =
427 (XwMenuButtonWidgetClass) wc->core_class.superclass;
429 if (wc->menubutton_class.idealWidthProc == XtInheritIdealWidthProc)
430 wc->menubutton_class.idealWidthProc =
431 super->menubutton_class.idealWidthProc;
433 if (wc->menubutton_class.unhighlightProc == XtInheritUnhighlightProc)
434 wc->menubutton_class.unhighlightProc =
435 super->menubutton_class.unhighlightProc;
437 if (wc->menubutton_class.highlightProc == XtInheritHighlightProc)
438 wc->menubutton_class.highlightProc =
439 super->menubutton_class.highlightProc;
441 if (wc->menubutton_class.setCascadeProc == XtInheritSetCascadeProc)
442 wc->menubutton_class.setCascadeProc =
443 super->menubutton_class.setCascadeProc;
445 if (wc->menubutton_class.clearCascadeProc == XtInheritClearCascadeProc)
446 wc->menubutton_class.clearCascadeProc =
447 super->menubutton_class.clearCascadeProc;
449 if (wc->menubutton_class.enterParentProc == XtInheritEnterParentProc)
450 wc->menubutton_class.enterParentProc =
451 super->menubutton_class.enterParentProc;
453 if (wc->menubutton_class.cascadeSelectProc == XtInheritCascadeSelectProc)
454 wc->menubutton_class.cascadeSelectProc =
455 super->menubutton_class.cascadeSelectProc;
457 if (wc->menubutton_class.cascadeUnselectProc == XtInheritCascadeUnselectProc)
458 wc->menubutton_class.cascadeUnselectProc =
459 super->menubutton_class.cascadeUnselectProc;
461 if (wc->menubutton_class.setTraversalType == XtInheritSetTraversalTypeProc)
462 wc->menubutton_class.setTraversalType =
463 super->menubutton_class.setTraversalType;
467 /*************************************<->*************************************
469 * ComputeHeight (mbutton)
471 * Description:
472 * -----------
473 * Returns the ideal height of the menubutton by considering whether the
474 * label is text or image.
476 * Inputs:
477 * ------
478 * mbutton = widget to compute height of
480 * Outputs:
481 * -------
482 * returns the ideal height of mbutton
484 * Procedures Called
485 * -----------------
487 *************************************<->***********************************/
489 static Dimension ComputeHeight(mbutton)
490 XwMenuButtonWidget mbutton;
492 Dimension max = 0;
494 if (mbutton->menubutton.labelType == XwSTRING)
495 max = mbutton->button.label_height;
497 if ((mbutton->menubutton.labelType == XwIMAGE) &&
498 (mbutton->menubutton.labelImage->height > max))
499 max = mbutton->menubutton.labelImage->height;
501 if (mbutton->menubutton.markImage->height > max)
502 max = mbutton->menubutton.markImage->height;
504 if (mbutton->menubutton.cascadeImage->height > max)
505 max = mbutton->menubutton.cascadeImage->height;
507 return (max + 2 * mbutton->button.internal_height +
508 2 * mbutton->primitive.highlight_thickness);
512 /*************************************<->*************************************
514 * ComputeVertical
516 * Description:
517 * -----------
518 * Computes the values for mark_y, label_y and cascade_y.
520 * Inputs:
521 * ------
522 * mbutton = menubutton to compute and set values for
524 * Outputs:
525 * -------
527 * Procedures Called
528 * -----------------
530 *************************************<->***********************************/
532 static void ComputeVertical (mbutton)
533 XwMenuButtonWidget mbutton;
535 Dimension string_y;
537 string_y = (mbutton->core.height - mbutton->button.label_height)/2 +
538 mbutton->button.font->max_bounds.ascent;
540 if (mbutton->menubutton.labelType == XwSTRING)
541 mbutton->button.label_y = string_y;
543 else if (mbutton->menubutton.labelImage)
544 mbutton->button.label_y = (mbutton->core.height -
545 mbutton->menubutton.labelImage->height) / 2;
547 mbutton->menubutton.mark_y = (mbutton->core.height -
548 mbutton->menubutton.markImage->height)/2;
550 mbutton->menubutton.cascade_y = (mbutton->core.height -
551 mbutton->menubutton.cascadeImage->height)/2;
555 /*************************************<->*************************************
557 * SetUnderline (mbutton)
559 * Description:
560 * -----------
561 * Set the underline parameters underline_width and underline_y.
563 * Inputs:
564 * ------
565 * mbutton = menubutton
567 * Outputs:
568 * -------
570 * Procedures Called
571 * -----------------
572 * XTextWidth ()
573 * XGetFontProperty ()
575 *************************************<->***********************************/
577 static void SetUnderline (mbutton)
578 XwMenuButtonWidget mbutton;
580 int i, temp;
582 if ((!mbutton->menubutton.mgrOverrideMnemonic) &&
583 (mbutton->menubutton.mnemonic))
585 mbutton->menubutton.mnemonicMatch = FALSE;
586 temp = XwStrlen (mbutton->button.label);
588 for (i = 0; i < temp;)
590 #ifdef NLS16
591 if (XHPIs16bitCharacter (mbutton->button.font->fid,
592 mbutton->button.label[i],
593 mbutton->button.label[i+1]) == NULL)
595 #endif
596 if (*mbutton->menubutton.mnemonic ==
597 (char) mbutton->button.label[i])
599 unsigned long bval;
601 mbutton->menubutton.mnemonicMatch = TRUE;
602 mbutton->menubutton.underline_width =
603 XTextWidth(mbutton->button.font, mbutton->button.label+i, 1);
605 mbutton->menubutton.underline_x =
606 XTextWidth(mbutton->button.font, mbutton->button.label, i) +
607 mbutton->primitive.highlight_thickness +
608 4 * mbutton->button.internal_width + XwMARKWIDTH;
610 if (XGetFontProperty(mbutton->button.font, XA_UNDERLINE_POSITION,
611 &bval) == 0)
612 mbutton->menubutton.underline_y =
613 mbutton->button.font->descent +1;
614 else
615 mbutton->menubutton.underline_y = (Dimension) bval;
617 mbutton->menubutton.underline_y += mbutton->button.label_y;
618 break;
620 else
621 i += 1;
622 #ifdef NLS16
624 else
625 i += 2;
626 #endif
629 else
630 mbutton->menubutton.mnemonicMatch = FALSE;
633 /*************************************<->*************************************
635 * GetGC (mbutton)
637 * Description:
638 * -----------
639 * Creates image_GC
641 * Inputs:
642 * ------
643 * mbutton = menubutton
645 * Outputs:
646 * -------
648 * Procedures Called
649 * -----------------
650 * XtGetGC()
652 *************************************<->***********************************/
654 static void GetGC (mbutton)
655 XwMenuButtonWidget mbutton;
658 XGCValues values;
659 unsigned long dostipple = 0;
661 values.function = GXcopy;
662 values.plane_mask = AllPlanes;
663 values.subwindow_mode = ClipByChildren;
664 values.clip_x_origin = 0;
665 values.clip_y_origin = 0;
666 values.clip_mask = None;
667 values.fill_style = FillSolid;
668 values.graphics_exposures = True;
670 values.foreground = mbutton->primitive.foreground;
671 values.background = mbutton->core.background_pixel;
673 mbutton->menubutton.defPixmap_GC =
674 XtGetGC ((Widget) mbutton,
675 GCFunction | GCPlaneMask | GCSubwindowMode |
676 GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin |
677 GCClipMask | GCForeground | GCBackground,
678 &values);
680 values.foreground = mbutton->core.background_pixel;
681 values.background = mbutton->primitive.foreground;
683 mbutton->menubutton.invertPixmap_GC =
684 XtGetGC ((Widget) mbutton,
685 GCFunction | GCPlaneMask | GCSubwindowMode |
686 GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin |
687 GCClipMask | GCForeground | GCBackground,
688 &values);
690 values.background = mbutton->core.background_pixel;
691 values.stipple = mbutton->menubutton.rectStipple;
692 if (values.stipple != (Pixmap)NULL) {
693 dostipple = GCStipple;
694 values.fill_style = FillOpaqueStippled;
695 values.foreground = mbutton->primitive.foreground;
697 else
698 values.foreground = mbutton->menubutton.rectColor;
700 mbutton->menubutton.rect_GC =
701 XtGetGC ((Widget) mbutton,
702 GCFunction | GCPlaneMask | GCSubwindowMode |
703 GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin |
704 GCClipMask | GCForeground | GCBackground | dostipple |
705 GCFillStyle, &values);
708 /*************************************<->*************************************
710 * GetDefImages
712 * Description:
713 * -----------
715 * Inputs:
716 * ------
717 * mbutton = menubutton
719 * Outputs:
720 * -------
722 * Procedures Called
723 * -----------------
725 *************************************<->***********************************/
727 static void GetDefImages (mbutton)
728 XwMenuButtonWidget mbutton;
730 static unsigned char defMarkData[] =
732 0x00, 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0x3c,
733 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x07,
734 0x8c, 0x03, 0x8e, 0x01, 0xde, 0x01, 0xdc, 0x00,
735 0xd8, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00,
738 static unsigned char defCascadeData[] =
740 0x80, 0x00, 0x80, 0x01, 0x80, 0x03, 0x80, 0x07,
741 0x80, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f,
742 0xfe, 0x3f, 0xfe, 0x1f, 0x80, 0x0f, 0x80, 0x07,
743 0x80, 0x03, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00
746 mbutton->menubutton.defMarkImage =
747 XCreateImage (XtDisplay(mbutton), CopyFromParent, 1, XYBitmap, 0,
748 defMarkData, 16, 16, 8, 2);
750 mbutton->menubutton.defMarkImage->byte_order = MSBFirst;
751 mbutton->menubutton.defMarkImage->bitmap_bit_order = LSBFirst;
752 mbutton->menubutton.defMarkImage->bitmap_unit = 8;
755 mbutton->menubutton.defCascadeImage =
756 XCreateImage (XtDisplay(mbutton), CopyFromParent, 1, XYBitmap, 0,
757 defCascadeData, 16, 16, 8, 2);
759 mbutton->menubutton.defCascadeImage->byte_order = MSBFirst;
760 mbutton->menubutton.defCascadeImage->bitmap_bit_order = LSBFirst;
761 mbutton->menubutton.defCascadeImage->bitmap_unit = 8;
764 /*************************************<->*************************************
766 * CreatePixmap
768 * Description:
769 * -----------
771 * Inputs:
772 * ------
773 * mbutton = menubutton
775 * Outputs:
776 * -------
778 * Procedures Called
779 * -----------------
781 *************************************<->***********************************/
783 static void CreatePixmap (mbutton, image, pix, invertedPix)
784 XwMenuButtonWidget mbutton;
785 XImage * image;
786 Pixmap * pix;
787 Pixmap * invertedPix;
789 if (*pix != (Pixmap)NULL)
790 XFreePixmap (XtDisplay(mbutton), *pix);
792 if (*invertedPix != (Pixmap)NULL)
793 XFreePixmap (XtDisplay(mbutton), *invertedPix);
795 if (image)
797 *pix = XCreatePixmap (XtDisplay(mbutton),
798 RootWindowOfScreen(XtScreen(mbutton)),
799 image->width, image->height,
800 DefaultDepthOfScreen(XtScreen(mbutton)));
802 XPutImage (XtDisplay(mbutton), *pix, mbutton->menubutton.defPixmap_GC,
803 image, 0, 0, 0, 0, image->width, image->height);
805 if (image->format == XYBitmap)
807 *invertedPix = XCreatePixmap (XtDisplay(mbutton),
808 RootWindowOfScreen(XtScreen(mbutton)),
809 image->width, image->height,
810 DefaultDepthOfScreen(XtScreen(mbutton)));
812 XPutImage (XtDisplay(mbutton), *invertedPix,
813 mbutton->menubutton.invertPixmap_GC,
814 image, 0, 0, 0, 0, image->width, image->height);
818 else
820 *pix = (Pixmap)NULL;
821 *invertedPix = (Pixmap)NULL;
825 /*************************************<->*************************************
827 * IdealWidth
829 * Description:
830 * -----------
831 * NOTE!!! This should be eventually replaced by a QueryProc.
833 * Inputs:
834 * ------
835 * w = menubutton widget
838 * Outputs:
839 * -------
841 * Procedures Called
842 * -----------------
844 *************************************<->***********************************/
846 static void IdealWidth (w, width)
847 Widget w;
848 Dimension * width;
850 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
852 *width = 2 * mbutton->primitive.highlight_thickness +
853 2 * (XwMENUBTNPAD + mbutton->button.internal_width) +
854 XwMARKWIDTH + XwCASCADEWIDTH;
856 if (mbutton->menubutton.labelType == XwSTRING)
857 *width += mbutton->button.label_width;
858 else if (mbutton->menubutton.labelType == XwIMAGE)
859 *width += mbutton->menubutton.labelImage->width;
862 /*************************************<->*************************************
864 * Initialize (request, new)
866 * Description:
867 * -----------
868 * This is the menubutton instance initialize procedure.
871 * Inputs:
872 * ------
873 * request = original instance record;
875 * new = instance record with modifications induced by
876 * other initialize routines, changes are made to this
877 * record;
879 * args = argument list specified in XtCreateWidget;
881 * num_args = argument count;
883 * Outputs:
884 * -------
886 * Procedures Called
887 * -----------------
889 *************************************<->***********************************/
891 static void Initialize (request, new)
892 Widget request, new;
894 Dimension dim;
895 KeySym tempKeysym;
897 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) new;
899 /* Augment our translations to include the traversal actions */
900 XtAugmentTranslations ((Widget)mbutton,
901 XwprimitiveClassRec.primitive_class.translations);
904 * Always disable traversal in a menubutton. Since the traversal
905 * state is inherited from the menu manager, we will let it control
906 * our traversal state.
908 mbutton->primitive.traversal_type = XwHIGHLIGHT_OFF;
910 mbutton->menubutton.cascadeEnabled = FALSE;
911 mbutton->menubutton.inverted = FALSE;
912 mbutton->menubutton.labelPixmap =
913 mbutton->menubutton.markPixmap =
914 mbutton->menubutton.cascadePixmap =
915 mbutton->menubutton.invertLabelPixmap =
916 mbutton->menubutton.invertMarkPixmap =
917 mbutton->menubutton.invertCascadePixmap = (Pixmap)NULL;
919 GetDefImages(mbutton);
920 GetGC(mbutton);
923 * If the menuMgr field has not been set up, check if in a menu system
924 * (menu manager as ancestor).
926 if (mbutton->menubutton.menuMgr == NULL)
928 if ((XtIsSubclass (XtParent (mbutton), XwmenupaneWidgetClass)) &&
929 (XtIsSubclass (XtParent (XtParent (mbutton)), shellWidgetClass)) &&
930 (XtIsSubclass (XtParent (XtParent (XtParent (mbutton))),
931 XwmenumgrWidgetClass)))
933 mbutton->menubutton.menuMgr =
934 (Widget) XtParent (XtParent (XtParent(mbutton)));
939 * We need to malloc space for the strings and copy them to our
940 * space. The toolkit simply copies the pointer to the string.
942 if ((mbutton->menubutton.accelerator) &&
943 (_XwMapKeyEvent (mbutton->menubutton.accelerator,
944 &mbutton->menubutton.accelEventType,
945 &tempKeysym,
946 &mbutton->menubutton.accelModifiers)))
948 mbutton->menubutton.accelDetail = XKeysymToKeycode (XtDisplay(mbutton),
949 tempKeysym);
950 mbutton->menubutton.accelerator =
951 strcpy(XtMalloc((unsigned)(XwStrlen(mbutton->menubutton.accelerator)+1)),
952 mbutton->menubutton.accelerator);
954 else
956 if (mbutton->menubutton.accelerator)
957 XtWarning ("MenuButton: Invalid accelerator; disabling feature");
958 mbutton->menubutton.accelerator = NULL;
959 mbutton->menubutton.accelEventType = 0;
960 mbutton->menubutton.accelDetail = 0;
961 mbutton->menubutton.accelModifiers = 0;
964 if (mbutton->menubutton.hint)
965 mbutton->menubutton.hint =
966 strcpy(XtMalloc((unsigned)(XwStrlen(mbutton->menubutton.hint)+1)),
967 mbutton->menubutton.hint);
970 * malloc space for mnemonic. Only take 1st character & null
972 if ((mbutton->menubutton.mnemonic) &&
973 (*(mbutton->menubutton.mnemonic) != '\0'))
975 char mne = mbutton->menubutton.mnemonic[0];
977 mbutton->menubutton.mnemonic = (String) XtMalloc(2);
978 mbutton->menubutton.mnemonic[0] = mne;
979 mbutton->menubutton.mnemonic[1] = '\0';
981 else
982 if (mbutton->menubutton.mnemonic)
983 XtWarning ("MenuButton: Invalid mnemonic; disabling feature");
985 if (mbutton->menubutton.labelImage)
986 CreatePixmap(mbutton, mbutton->menubutton.labelImage,
987 &mbutton->menubutton.labelPixmap,
988 &mbutton->menubutton.invertLabelPixmap);
990 if (!mbutton->menubutton.markImage)
991 mbutton->menubutton.markImage = mbutton->menubutton.defMarkImage;
993 CreatePixmap(mbutton, mbutton->menubutton.markImage,
994 &mbutton->menubutton.markPixmap,
995 &mbutton->menubutton.invertMarkPixmap);
997 if (!mbutton->menubutton.cascadeImage)
998 mbutton->menubutton.cascadeImage = mbutton->menubutton.defCascadeImage;
1000 CreatePixmap(mbutton, mbutton->menubutton.cascadeImage,
1001 &mbutton->menubutton.cascadePixmap,
1002 &mbutton->menubutton.invertCascadePixmap);
1004 if (request->core.height <= 0)
1005 mbutton->core.height = ComputeHeight(mbutton);
1007 ComputeVertical(mbutton);
1008 SetUnderline(mbutton);
1010 if (request->core.width <= 0)
1011 IdealWidth(mbutton, &mbutton->core.width);
1014 /*************************************<->*************************************
1016 * Destroy
1018 * Description:
1019 * -----------
1021 * Inputs:
1022 * ------
1024 * Outputs:
1025 * -------
1027 * Procedures Called
1028 * -----------------
1030 *************************************<->***********************************/
1032 static void Destroy (mbutton)
1033 XwMenuButtonWidget mbutton;
1035 if (mbutton->menubutton.accelerator)
1036 XtFree (mbutton->menubutton.accelerator);
1038 XtDestroyGC (mbutton->menubutton.defPixmap_GC);
1039 XtDestroyGC (mbutton->menubutton.inverted_GC);
1040 XtDestroyGC (mbutton->menubutton.invertPixmap_GC);
1041 XtDestroyGC (mbutton->menubutton.rect_GC);
1043 mbutton->menubutton.defMarkImage->data = NULL;
1044 XDestroyImage (mbutton->menubutton.defMarkImage);
1045 mbutton->menubutton.defCascadeImage->data = NULL;
1046 XDestroyImage (mbutton->menubutton.defCascadeImage);
1048 XtRemoveAllCallbacks ((Widget)mbutton, XtNcascadeSelect);
1049 XtRemoveAllCallbacks ((Widget)mbutton, XtNcascadeUnselect);
1051 XFreePixmap (XtDisplay(mbutton), mbutton->menubutton.markPixmap);
1052 XFreePixmap (XtDisplay(mbutton), mbutton->menubutton.cascadePixmap);
1053 if (mbutton->menubutton.labelPixmap)
1054 XFreePixmap (XtDisplay(mbutton), mbutton->menubutton.labelPixmap);
1057 /*************************************<->*************************************
1059 * Realize
1061 * Description:
1062 * -----------
1063 * Creates the window for this menubutton instance. Sets bit gravity
1064 * so that on resize the menubutton is repainted.
1067 * Inputs:
1068 * ------
1069 * w = widget to be realized.
1071 * valueMask = contains event mask for this window/widget.
1073 * attributes = window attributes for this window/widget.
1075 * Outputs:
1076 * -------
1078 * Procedures Called
1079 * -----------------
1080 * XtCreateWindow()
1081 *************************************<->***********************************/
1083 static void Realize(w, p_valueMask, attributes)
1084 Widget w;
1085 XtValueMask * p_valueMask;
1086 XSetWindowAttributes * attributes;
1088 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
1090 XtValueMask valueMask = *p_valueMask;
1091 valueMask |= CWBitGravity;
1092 attributes->bit_gravity = ForgetGravity;
1095 XtCreateWindow ((Widget)mbutton, InputOutput, (Visual *) CopyFromParent,
1096 valueMask, attributes);
1098 _XwRegisterName (mbutton);
1099 } /* Realize */
1101 /*************************************<->*************************************
1103 * Select (w, event) PRIVATE
1105 * Description:
1106 * -----------
1107 * Mark menubutton as selected, (i.e., draw it as active)
1108 * Generate the correct callbacks.
1111 * Inputs:
1112 * ------
1113 * w = widget instance that was selected.
1114 * event = event record
1116 * Outputs:
1117 * -------
1119 * Procedures Called
1120 * -----------------
1121 * XtCallCallbacks()
1122 *************************************<->***********************************/
1124 static void Select(w,event)
1125 Widget w;
1126 XEvent *event;
1129 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
1131 /* Don't do anything if its not sensitive. */
1133 if (XtIsSensitive((Widget)mbutton))
1136 * if there is a menu manager, call the process select routine to
1137 * determine if the event is valid for the menu system.
1139 if (mbutton->menubutton.menuMgr)
1141 if ((*(((XwMenuMgrWidgetClass) XtClass(mbutton->menubutton.menuMgr))->
1142 menu_mgr_class.processSelect))
1143 (mbutton->menubutton.menuMgr, mbutton, event) == FALSE)
1145 return;
1149 XtCallCallbacks ((Widget)mbutton, XtNselect, NULL);
1153 /*************************************<->*************************************
1155 * DrawLabelMarkCascade (mbutton)
1157 * Description:
1158 * -----------
1160 * Inputs:
1161 * ------
1163 * Outputs:
1164 * -------
1166 * Procedures Called
1167 * -----------------
1169 *************************************<->***********************************/
1171 static void DrawLabelMarkCascade (mbutton)
1172 XwMenuButtonWidget mbutton;
1174 Dimension labelStarts;
1175 GC theGC;
1176 Pixmap thePixmap;
1178 if (mbutton->menubutton.inverted)
1179 theGC = mbutton->button.inverse_GC;
1180 else
1181 theGC = mbutton->button.normal_GC;
1184 if (mbutton->menubutton.noPad == True)
1185 labelStarts = mbutton->primitive.highlight_thickness +
1186 mbutton->button.internal_width;
1187 else
1188 labelStarts = mbutton->primitive.highlight_thickness +
1189 mbutton->button.internal_width + XwMENUBTNPAD + XwMARKWIDTH;
1191 * Draw the label with its underline if needed.
1193 if (mbutton->menubutton.labelType == XwSTRING)
1195 XDrawString(
1196 XtDisplay(mbutton), XtWindow(mbutton), theGC,
1197 labelStarts, mbutton->button.label_y,
1198 mbutton->button.label, (int) mbutton->button.label_len);
1200 if ((!mbutton->menubutton.mgrOverrideMnemonic) &&
1201 (mbutton->menubutton.mnemonicMatch))
1202 XDrawLine(
1203 XtDisplay(mbutton), XtWindow(mbutton), theGC,
1204 mbutton->menubutton.underline_x,
1205 mbutton->menubutton.underline_y,
1206 mbutton->menubutton.underline_x +
1207 mbutton->menubutton.underline_width,
1208 mbutton->menubutton.underline_y);
1210 else if (mbutton->menubutton.labelType == XwRECT)
1212 /* Draw a colored or stippled rectangle with a border around it */
1214 if (mbutton->menubutton.noPad == True) {
1215 XFillRectangle(
1216 XtDisplay(mbutton), XtWindow(mbutton),
1217 mbutton->menubutton.rect_GC,
1218 2, 2, mbutton->menubutton.labelImage->width - 1,
1219 mbutton->menubutton.labelImage->height - 1);
1220 XDrawRectangle(
1221 XtDisplay(mbutton), XtWindow(mbutton), theGC,
1222 2, 2, mbutton->menubutton.labelImage->width - 1,
1223 mbutton->menubutton.labelImage->height - 1);
1225 else {
1226 XFillRectangle(
1227 XtDisplay(mbutton), XtWindow(mbutton),
1228 mbutton->menubutton.rect_GC,
1229 XwMARKWIDTH + 3, 3, mbutton->core.width - XwMARKWIDTH - 6,
1230 mbutton->core.height - 6);
1231 XDrawRectangle(
1232 XtDisplay(mbutton), XtWindow(mbutton), theGC,
1233 XwMARKWIDTH + 3, 3, mbutton->core.width - XwMARKWIDTH - 6,
1234 mbutton->core.height - 6);
1237 else
1239 if ((mbutton->menubutton.inverted) &&
1240 (mbutton->menubutton.invertLabelPixmap))
1241 thePixmap = mbutton->menubutton.invertLabelPixmap;
1242 else
1243 thePixmap = mbutton->menubutton.labelPixmap;
1245 XCopyArea (XtDisplay(mbutton), thePixmap, XtWindow(mbutton),
1246 mbutton->menubutton.defPixmap_GC, 0, 0,
1247 mbutton->menubutton.labelImage->width,
1248 mbutton->menubutton.labelImage->height,
1249 labelStarts, mbutton->button.label_y);
1253 * If the mark is set, display the mark.
1255 if (mbutton->menubutton.setMark)
1257 if ((mbutton->menubutton.inverted) &&
1258 (mbutton->menubutton.invertMarkPixmap))
1259 thePixmap = mbutton->menubutton.invertMarkPixmap;
1260 else
1261 thePixmap = mbutton->menubutton.markPixmap;
1263 XCopyArea (XtDisplay(mbutton), thePixmap, XtWindow(mbutton),
1264 mbutton->menubutton.defPixmap_GC, 0, 0,
1265 mbutton->menubutton.markImage->width,
1266 mbutton->menubutton.markImage->height,
1267 mbutton->button.internal_width +
1268 mbutton->primitive.highlight_thickness,
1269 mbutton->menubutton.mark_y);
1273 * If the cascade is set, display it.
1275 if (mbutton->menubutton.cascadeOn)
1277 if ((mbutton->menubutton.inverted) &&
1278 (mbutton->menubutton.invertCascadePixmap))
1279 thePixmap = mbutton->menubutton.invertCascadePixmap;
1280 else
1281 thePixmap = mbutton->menubutton.cascadePixmap;
1283 XCopyArea (XtDisplay(mbutton), thePixmap, XtWindow(mbutton),
1284 mbutton->menubutton.defPixmap_GC, 0, 0,
1285 mbutton->menubutton.cascadeImage->width,
1286 mbutton->menubutton.cascadeImage->height,
1287 mbutton->core.width - XwCASCADEWIDTH -
1288 mbutton->primitive.highlight_thickness -
1289 mbutton->button.internal_width,
1290 mbutton->menubutton.cascade_y);
1294 /*************************************<->*************************************
1296 * Inverted (mbutton)
1298 * Description:
1299 * -----------
1301 * Inputs:
1302 * ------
1304 * Outputs:
1305 * -------
1307 * Procedures Called
1308 * -----------------
1309 * XFillRectangle
1310 * DrawLabelMarkCascade
1312 *************************************<->***********************************/
1314 static void Inverted (mw)
1315 XwMenuButtonWidget mw;
1318 mw -> menubutton.inverted = TRUE;
1320 XFillRectangle (XtDisplay (mw), XtWindow (mw),
1321 mw->button.normal_GC,
1322 mw -> primitive.highlight_thickness + 1,
1323 mw -> primitive.highlight_thickness + 1,
1324 mw -> core.width - 2 *
1325 (mw -> primitive.highlight_thickness + 1),
1326 mw -> core.height - 2 *
1327 (mw -> primitive.highlight_thickness + 1));
1328 DrawLabelMarkCascade (mw);
1333 /*************************************<->*************************************
1335 * NonInverted (mbutton)
1337 * Description:
1338 * -----------
1340 * Inputs:
1341 * ------
1343 * Outputs:
1344 * -------
1346 * Procedures Called
1347 * -----------------
1348 * XClearWindow
1349 * DrawLabelMarkCascade
1351 *************************************<->***********************************/
1353 static void NonInverted (mbutton)
1354 XwMenuButtonWidget mbutton;
1357 mbutton->menubutton.inverted = FALSE;
1359 XClearWindow (XtDisplay(mbutton), XtWindow(mbutton));
1360 DrawLabelMarkCascade (mbutton);
1365 /*************************************<->*************************************
1367 * Highlight(mbutton)
1369 * Description:
1370 * -----------
1372 * Inputs:
1373 * ------
1375 * Outputs:
1376 * -------
1378 * Procedures Called
1379 * -----------------
1380 * Moved
1381 * Inverted
1383 *************************************<->***********************************/
1385 static void Highlight (mbutton)
1386 XwMenuButtonWidget mbutton;
1389 if (mbutton->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
1390 _XwHighlightBorder(mbutton);
1391 else
1393 Inverted (mbutton);
1396 /*************************************<->*************************************
1398 * Unhighlight (mbutton)
1400 * Description:
1401 * -----------
1403 * Inputs:
1404 * ------
1406 * Outputs:
1407 * -------
1409 * Procedures Called
1410 * -----------------
1411 * Moved
1412 * Inverted
1414 *************************************<->***********************************/
1416 static void Unhighlight (mbutton)
1417 XwMenuButtonWidget mbutton;
1420 if (mbutton->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
1421 _XwUnhighlightBorder(mbutton);
1422 else
1424 NonInverted (mbutton);
1425 mbutton->menubutton.cascadeEnabled = FALSE;
1428 /*************************************<->*************************************
1430 * Enter (w, event) PRIVATE
1432 * Description:
1433 * -----------
1435 * Inputs:
1436 * ------
1437 * w = widget instance that was selected.
1438 * event = event record
1440 * Outputs:
1441 * -------
1443 * Procedures Called
1444 * -----------------
1445 * Moved
1446 * Inverted
1448 *************************************<->***********************************/
1450 static void Enter(w,event)
1451 Widget w;
1452 XEvent *event;
1454 XwMenuButtonWidget mbutton = (XwMenuButtonWidget)w;
1456 #ifdef DEBUG
1457 printf ("Enter %s\n", w->core.name);
1458 #endif
1459 if ((mbutton->menubutton.menuMgr == NULL) ||
1460 ((*(((XwMenuMgrWidgetClass)
1461 XtClass (mbutton->menubutton.menuMgr))->menu_mgr_class.validEvent))
1462 (mbutton->menubutton.menuMgr, mbutton, event)))
1465 * Check on cascade indicator
1467 Moved (w, event);
1470 * if (mbutton->primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
1472 Inverted(mbutton);
1475 /* to-do: if no hintProc is specified, should generate a hint tag */
1477 if ((mbutton->menubutton.hint != NULL) &&
1478 (mbutton->menubutton.hintProc != NULL)) {
1479 mbutton->menubutton.hintProc(mbutton->menubutton.hint);
1483 /*************************************<->*************************************
1485 * EnterParentsWindow (menupane, mbutton,event)
1487 * Description:
1488 * -----------
1490 * Inputs:
1491 * ------
1493 * Outputs:
1494 * -------
1496 * Procedures Called
1497 * -----------------
1499 *************************************<->***********************************/
1501 static void EnterParentsWindow (menupane, mbutton, event)
1502 Widget menupane;
1503 XwMenuButtonWidget mbutton;
1504 XEvent * event;
1506 Boolean remainHighlighted;
1507 XwunselectParams params;
1509 XEnterWindowEvent * entEvent = (XEnterWindowEvent *) event;
1511 #ifdef DEBUG
1512 printf ("EnterParents %s %s ", menupane->core.name, mbutton->core.name);
1513 #endif
1516 * if outside of the menubutton, bring down submenu. I am assuming that
1517 * the x parameters are okay. This means that entering my parents borders
1518 * on the correct y parameters will not cause the unselects to be called.
1520 if ((entEvent->y < mbutton->core.y) ||
1521 (entEvent->y > mbutton->core.y + mbutton->core.height +
1522 2 * mbutton->core.border_width))
1524 params.rootX = entEvent->x_root;
1525 params.rootY = entEvent->y_root;
1526 params.remainHighlighted = FALSE;
1528 #ifdef DEBUG
1529 printf ("rootX %d rootY %d\n", params.rootX, params.rootY);
1530 printf ("disabled\n");
1531 #endif
1533 XtCallCallbacks ((Widget)mbutton, XtNcascadeUnselect, &params);
1534 mbutton->menubutton.cascadeEnabled = params.remainHighlighted;
1535 if (mbutton->menubutton.cascadeEnabled == FALSE)
1536 Unhighlight (mbutton);
1538 /* else
1539 * Moved (mbutton, event);
1542 #ifdef DEBUG
1543 printf ("\n");
1544 #endif
1546 XtRemoveEventHandler (menupane, EnterWindowMask, FALSE,
1547 (XtEventHandler)EnterParentsWindow, mbutton);
1550 /*************************************<->*************************************
1552 * Leave (w, event) PRIVATE
1554 * Description:
1555 * -----------
1557 * Inputs:
1558 * ------
1560 * Outputs:
1561 * -------
1563 * Procedures Called
1564 * -----------------
1565 * XtCallCallbacks
1566 * NonInverted
1568 *************************************<->***********************************/
1570 static void Leave(w,event)
1571 Widget w;
1572 XEvent *event;
1575 XwunselectParams params;
1576 XwMenuButtonWidget mbutton = (XwMenuButtonWidget)w;
1577 XLeaveWindowEvent * lEvent = (XLeaveWindowEvent *) event;
1579 params.rootX = lEvent->x_root;
1580 params.rootY = lEvent->y_root;
1583 if ((mbutton->menubutton.menuMgr == NULL) ||
1584 ((*(((XwMenuMgrWidgetClass)
1585 XtClass (mbutton->menubutton.menuMgr))->menu_mgr_class.validEvent))
1586 (mbutton->menubutton.menuMgr, mbutton, event)))
1588 if (mbutton->menubutton.cascadeEnabled)
1590 params.remainHighlighted = FALSE;
1591 XtCallCallbacks ((Widget)mbutton, XtNcascadeUnselect, &params);
1592 mbutton->menubutton.cascadeEnabled = params.remainHighlighted;
1594 if (mbutton->menubutton.cascadeEnabled)
1596 XtAddEventHandler (XtParent(mbutton), EnterWindowMask, FALSE,
1597 (XtEventHandler)EnterParentsWindow, mbutton);
1598 return;
1602 if (mbutton->menubutton.inverted)
1603 NonInverted(mbutton);
1606 if ((mbutton->menubutton.hint != NULL) &&
1607 (mbutton->menubutton.hintProc != NULL)) {
1608 mbutton->menubutton.hintProc("");
1612 /*************************************<->*************************************
1614 * Moved
1616 * Description:
1617 * -----------
1619 * Inputs:
1620 * ------
1622 * Outputs:
1623 * -------
1625 * Procedures Called
1626 * -----------------
1627 * XQueryPointer
1628 * XtCallCallbacks
1630 *************************************<->***********************************/
1632 static void Moved (w,event)
1633 Widget w;
1634 XEvent * event;
1637 XwMenuButtonWidget mbutton = (XwMenuButtonWidget)w;
1639 int xPosition, yPosition;
1640 int xroot, yroot;
1641 Window root, child;
1642 unsigned int mask;
1643 XwunselectParams params;
1645 XButtonPressedEvent * buttonEvent = (XButtonPressedEvent *) event;
1647 #ifdef DEBUG
1648 printf ("Moved %s\n", w->core.name);
1649 #endif
1652 * only do this if I have a cascade showing
1654 if ((mbutton->menubutton.cascadeOn) &&
1655 (mbutton->primitive.traversal_type == XwHIGHLIGHT_OFF))
1658 * if there is a menu manager and the cascade has not been popped up,
1659 * then ask the menu manager if it should be popped up
1661 if ((mbutton->menubutton.menuMgr == NULL) ||
1662 (mbutton->menubutton.cascadeEnabled == TRUE) ||
1663 (*(((XwMenuMgrWidgetClass)
1664 XtClass(mbutton->menubutton.menuMgr))->menu_mgr_class.doICascade))
1665 (mbutton->menubutton.menuMgr, mbutton))
1668 * check if the event appears to have occurred in the cascade area
1670 if ((mbutton->menubutton.cascadeEnabled) ||
1671 ((buttonEvent->y > 0) &&
1672 (buttonEvent->y < mbutton->core.height +
1673 2 * mbutton->core.border_width) &&
1674 (buttonEvent->x < mbutton->core.width +
1675 2 * mbutton->core.border_width) &&
1676 (buttonEvent->x > mbutton->core.width +
1677 2 * mbutton->core.border_width -
1678 XwCASCADEWIDTH -
1679 mbutton->primitive.highlight_thickness -
1680 mbutton->button.internal_width)))
1683 * Verify that its really in the cascade area
1685 XQueryPointer (XtDisplay(mbutton), mbutton->core.window,
1686 &root, &child, &xroot, &yroot, &xPosition,
1687 &yPosition, &mask);
1689 if ((yPosition > 0) &&
1690 (yPosition < mbutton->core.height +
1691 2 * mbutton->core.border_width) &&
1692 (xPosition < mbutton->core.width +
1693 2 * mbutton->core.border_width) &&
1694 (xPosition > mbutton->core.width +
1695 2 * mbutton->core.border_width - XwCASCADEWIDTH -
1696 mbutton->primitive.highlight_thickness -
1697 mbutton->button.internal_width))
1699 if (!mbutton->menubutton.cascadeEnabled)
1701 XtCallCallbacks ((Widget)mbutton, XtNcascadeSelect, NULL);
1702 #ifdef DEBUG
1703 printf ("enabled\n");
1704 #endif
1705 mbutton->menubutton.cascadeEnabled = TRUE;
1708 else if (mbutton->menubutton.cascadeEnabled)
1710 params.rootX = xroot;
1711 params.rootY = yroot;
1712 params.remainHighlighted = FALSE;
1713 #ifdef DEBUG
1714 printf ("Moved rootX %d rootY %d\n", params.rootX, params.rootY);
1715 #endif
1716 XtCallCallbacks ((Widget)mbutton, XtNcascadeUnselect, &params);
1717 mbutton->menubutton.cascadeEnabled = params.remainHighlighted;
1724 /*************************************<->*************************************
1726 * Redisplay (w, event)
1728 * Description:
1729 * -----------
1730 * Cause the widget, identified by w, to be redisplayed.
1732 * Inputs:
1733 * ------
1734 * w = widget to be redisplayed;
1735 * event = event structure identifying need for redisplay on this
1736 * widget.
1738 * Outputs:
1739 * -------
1741 * Procedures Called
1742 * -----------------
1743 * Inverted
1744 * NonInverted
1745 * _XwHighlightBorder
1746 * _XwUnhighlightBorder
1748 *************************************<->***********************************/
1750 static void Redisplay(w, event)
1751 Widget w;
1752 XEvent *event;
1754 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
1757 * if the highlight state has changed since the last redisplay,
1758 * update the window and set the font GC.
1760 if (mbutton->menubutton.inverted)
1761 Inverted(mbutton);
1763 else
1764 NonInverted(mbutton);
1766 if (mbutton->primitive.highlighted)
1767 _XwHighlightBorder(mbutton);
1769 else
1770 if (mbutton->primitive.display_highlighted)
1771 _XwUnhighlightBorder(mbutton);
1774 /*************************************<->*************************************
1776 * SetValues(urrent, request, new)
1778 * Description:
1779 * -----------
1780 * This is the set values procedure for the menubutton class. It is
1781 * called last (the set values rtnes for its superclasses are called
1782 * first).
1785 * Inputs:
1786 * ------
1787 * current = original widget;
1788 * request = copy of current (?);
1789 * new = copy of request which reflects changes made to it by
1790 * set values procedures of its superclasses;
1792 * Outputs:
1793 * -------
1795 * Procedures Called
1796 * -----------------
1798 *************************************<->***********************************/
1800 static Boolean SetValues (current, request, new)
1801 Widget current, request, new;
1803 XtWidgetGeometry reqGeo;
1804 XtWidgetGeometry replyGeo;
1805 XwMenuButtonWidget curmbutton = (XwMenuButtonWidget) current;
1806 XwMenuButtonWidget newmbutton = (XwMenuButtonWidget) new;
1807 Boolean flag = FALSE; /* our return value */
1808 Dimension dim;
1809 KeySym tempKeysym;
1811 /* We never allow our traversal state to change using SetValues() */
1812 newmbutton->primitive.traversal_type = curmbutton->primitive.traversal_type;
1815 * If the accelerator string changed, malloc space for the string
1816 * and copy it to our space. The old string must be freed.
1819 if (curmbutton->menubutton.accelerator !=
1820 newmbutton->menubutton.accelerator)
1822 if (newmbutton->menubutton.accelerator)
1824 if (_XwMapKeyEvent (newmbutton->menubutton.accelerator,
1825 &newmbutton->menubutton.accelEventType,
1826 &tempKeysym,
1827 &newmbutton->menubutton.accelModifiers)
1828 == FALSE)
1830 /* Invalid string; revert to previous one */
1831 XtWarning
1832 ("MenuButton: Invalid accelerator; using previous setting");
1833 newmbutton->menubutton.accelerator =
1834 curmbutton->menubutton.accelerator;
1835 newmbutton->menubutton.accelEventType =
1836 curmbutton->menubutton.accelEventType;
1837 newmbutton->menubutton.accelDetail =
1838 curmbutton->menubutton.accelDetail;
1839 newmbutton->menubutton.accelModifiers =
1840 curmbutton->menubutton.accelModifiers;
1842 else
1844 /* valid string */
1845 newmbutton->menubutton.accelDetail = XKeysymToKeycode (
1846 XtDisplay(newmbutton), tempKeysym);
1847 newmbutton->menubutton.accelerator =
1848 strcpy(XtMalloc((unsigned)
1849 (XwStrlen(newmbutton->menubutton.accelerator)+1)),
1850 newmbutton->menubutton.accelerator);
1852 if (newmbutton->menubutton.menuMgr)
1853 (*(((XwMenuMgrWidgetClass)
1854 XtClass (newmbutton->menubutton.menuMgr))->
1855 menu_mgr_class.setSelectAccelerator))
1856 (newmbutton->menubutton.menuMgr, (Widget)newmbutton,
1857 newmbutton->menubutton.accelerator,
1858 newmbutton->menubutton.accelEventType,
1859 newmbutton->menubutton.accelDetail,
1860 newmbutton->menubutton.accelModifiers);
1862 if (curmbutton->menubutton.accelerator)
1863 XtFree ((char *) curmbutton->menubutton.accelerator);
1866 else if (curmbutton->menubutton.accelerator)
1868 if (curmbutton->menubutton.menuMgr)
1869 (*(((XwMenuMgrWidgetClass)
1870 XtClass(curmbutton->menubutton.menuMgr))->
1871 menu_mgr_class.clearSelectAccelerator))
1872 (curmbutton->menubutton.menuMgr, (Widget)curmbutton);
1874 XtFree ((char *) curmbutton->menubutton.accelerator);
1879 * Determine if the mnemonic changed, verify and malloc space.
1880 * Notify menuMgr of the change.
1883 if (curmbutton->menubutton.mnemonic != newmbutton->menubutton.mnemonic)
1885 if (newmbutton->menubutton.mnemonic)
1887 if (*(newmbutton->menubutton.mnemonic) == '\0')
1889 XtWarning
1890 ("MenuButton: Invalid mnemonic; using previous setting");
1891 newmbutton->menubutton.mnemonic = curmbutton->menubutton.mnemonic;
1893 else
1895 char mne = newmbutton->menubutton.mnemonic[0];
1897 newmbutton->menubutton.mnemonic = (String)XtMalloc(2);
1898 newmbutton->menubutton.mnemonic[0] = mne;
1899 newmbutton->menubutton.mnemonic[1] = '\0';
1901 if (newmbutton->menubutton.menuMgr)
1902 (*(((XwMenuMgrWidgetClass)
1903 XtClass (newmbutton->menubutton.menuMgr))->
1904 menu_mgr_class.setSelectMnemonic))
1905 (newmbutton->menubutton.menuMgr, (Widget)newmbutton,
1906 newmbutton->menubutton.mnemonic);
1908 XtFree (curmbutton->menubutton.mnemonic);
1911 else
1913 if (newmbutton->menubutton.menuMgr)
1914 (*(((XwMenuMgrWidgetClass)
1915 XtClass (curmbutton->menubutton.menuMgr))->
1916 menu_mgr_class.clearSelectMnemonic))
1917 (curmbutton->menubutton.menuMgr, (Widget)curmbutton);
1919 XtFree(curmbutton->menubutton.mnemonic);
1924 * recalculate the underline parameters if mnemonic or font changes
1926 if ((newmbutton->menubutton.mnemonic != curmbutton->menubutton.mnemonic) ||
1927 (newmbutton->button.font != curmbutton->button.font))
1929 SetUnderline (newmbutton);
1930 flag = TRUE;
1935 * If the foreground or background changed, or the color or stipple
1936 * declaration was changed, recreate the GC's
1938 if ((newmbutton->primitive.foreground !=
1939 curmbutton->primitive.foreground) ||
1940 (newmbutton->core.background_pixel !=
1941 curmbutton->core.background_pixel) ||
1942 (newmbutton->menubutton.rectColor !=
1943 curmbutton->menubutton.rectColor) ||
1944 (newmbutton->menubutton.rectStipple !=
1945 curmbutton->menubutton.rectStipple))
1947 GetGC (newmbutton);
1948 XtDestroyGC (curmbutton->menubutton.defPixmap_GC);
1949 XtDestroyGC (curmbutton->menubutton.invertPixmap_GC);
1953 * If the GCs are new, or the images are new, create new pixmaps
1955 if ((newmbutton->menubutton.markImage !=
1956 curmbutton->menubutton.markImage) ||
1957 (newmbutton->primitive.foreground !=
1958 curmbutton->primitive.foreground) ||
1959 (newmbutton->core.background_pixel !=
1960 curmbutton->core.background_pixel))
1962 if (!newmbutton->menubutton.markImage)
1963 newmbutton->menubutton.markImage =
1964 newmbutton->menubutton.defMarkImage;
1966 CreatePixmap(newmbutton, newmbutton->menubutton.markImage,
1967 &newmbutton->menubutton.markPixmap,
1968 &newmbutton->menubutton.invertMarkPixmap);
1969 flag = TRUE;
1972 if ((newmbutton->menubutton.cascadeImage !=
1973 curmbutton->menubutton.cascadeImage) ||
1974 (newmbutton->primitive.foreground !=
1975 curmbutton->primitive.foreground) ||
1976 (newmbutton->core.background_pixel !=
1977 curmbutton->core.background_pixel))
1979 if (!newmbutton->menubutton.cascadeImage)
1980 newmbutton->menubutton.cascadeImage =
1981 newmbutton->menubutton.defCascadeImage;
1983 CreatePixmap(newmbutton, newmbutton->menubutton.cascadeImage,
1984 &newmbutton->menubutton.cascadePixmap,
1985 &newmbutton->menubutton.invertCascadePixmap);
1986 flag = TRUE;
1989 if ((newmbutton->menubutton.labelImage !=
1990 curmbutton->menubutton.labelImage) ||
1991 (newmbutton->primitive.foreground !=
1992 curmbutton->primitive.foreground) ||
1993 (newmbutton->core.background_pixel !=
1994 curmbutton->core.background_pixel))
1996 CreatePixmap(newmbutton, newmbutton->menubutton.labelImage,
1997 &newmbutton->menubutton.labelPixmap,
1998 &newmbutton->menubutton.invertLabelPixmap);
2000 if (newmbutton->menubutton.labelType == XwIMAGE)
2001 flag = TRUE;
2004 if ((newmbutton->core.sensitive != curmbutton->core.sensitive) ||
2005 (newmbutton->core.ancestor_sensitive !=
2006 curmbutton->core.ancestor_sensitive))
2008 if (curmbutton->menubutton.menuMgr)
2010 (*(((XwMenuMgrWidgetClass)
2011 XtClass(curmbutton->menubutton.menuMgr))->
2012 menu_mgr_class.btnSensitivityChanged))
2013 (curmbutton->menubutton.menuMgr, (Widget)newmbutton);
2018 * fields that change that cause a redraw
2020 if ((newmbutton->menubutton.labelType !=
2021 curmbutton->menubutton.labelType) ||
2022 (newmbutton->menubutton.setMark !=
2023 curmbutton->menubutton.setMark) ||
2024 (newmbutton->menubutton.cascadeOn !=
2025 curmbutton->menubutton.cascadeOn) ||
2026 (newmbutton->menubutton.mgrOverrideMnemonic !=
2027 curmbutton->menubutton.mgrOverrideMnemonic) ||
2028 (newmbutton->menubutton.rectColor !=
2029 curmbutton->menubutton.rectColor) ||
2030 (newmbutton->menubutton.rectStipple !=
2031 curmbutton->menubutton.rectStipple))
2034 flag = TRUE;
2037 /**********************************************************************
2038 * Calculate the window size: The assumption here is that if
2039 * the width and height are the same in the new and current instance
2040 * record that those fields were not changed with set values. Therefore
2041 * its okay to recompute the necessary width and height. However, if
2042 * the new and current do have different width/heights then leave them
2043 * alone because that's what the user wants.
2044 *********************************************************************/
2046 /* "noPad" option prevents button from resizing itself 2/24/00 --Tim */
2048 if (curmbutton->core.width == request->core.width &&
2049 curmbutton->menubutton.noPad == False)
2051 IdealWidth (newmbutton, &newmbutton->core.width);
2052 flag = TRUE;
2054 else if (request->core.width <= 0)
2056 XtWarning ("MenuButton: Invalid width; using previous setting");
2057 newmbutton->core.width = curmbutton->core.width;
2060 if (curmbutton->core.height == request->core.height &&
2061 curmbutton->menubutton.noPad == False)
2063 newmbutton->core.height = ComputeHeight(newmbutton);
2064 flag = TRUE;
2066 else if (request->core.height <= 0)
2068 XtWarning ("MenuButton: Invalid height; using previous setting");
2069 newmbutton->core.height = curmbutton->core.height;
2072 return (flag);
2075 /*************************************<->*************************************
2077 * Resize(w)
2079 * Description:
2080 * -----------
2081 * A resize event has been generated. Recompute location of button
2082 * elements.
2084 * Inputs:
2085 * ------
2086 * w = widget to be resized.
2088 * Outputs:
2089 * -------
2091 * Procedures Called
2092 * -----------------
2094 *************************************<->***********************************/
2096 static void Resize(w)
2097 Widget w;
2100 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
2102 ComputeVertical(mbutton);
2103 SetUnderline(mbutton);
2107 /*************************************<->*************************************
2109 * SetTraversalType(w)
2111 * Description:
2112 * -----------
2114 * Inputs:
2115 * ------
2117 * Outputs:
2118 * -------
2120 * Procedures Called
2121 * -----------------
2123 *************************************<->***********************************/
2125 static void SetTraversalType (w, highlight_mode)
2127 Widget w;
2128 int highlight_mode;
2132 XwMenuButtonWidget mbutton = (XwMenuButtonWidget) w;
2134 mbutton->primitive.traversal_type = highlight_mode;
2136 if (highlight_mode == XwHIGHLIGHT_TRAVERSAL)
2138 XtAugmentTranslations (w, XwprimitiveClassRec.primitive_class.
2139 translations);
2140 w->core.widget_class->core_class.visible_interest = True;
2145 /*************************************<->*************************************
2147 * TraverseRight(w, event)
2149 * Description:
2150 * -----------
2152 * Inputs:
2153 * ------
2155 * Outputs:
2156 * -------
2158 * Procedures Called
2159 * -----------------
2161 *************************************<->***********************************/
2163 static void TraverseRight (w, event)
2165 XwMenuButtonWidget w;
2166 XEvent * event;
2170 * Ask the menu manager to traverse to the next menupane, if we
2171 * have a cascade.
2174 if ((w->menubutton.cascadeOn) && (w->menubutton.menuMgr) &&
2175 (w->primitive.I_have_traversal) && (_XwUniqueEvent (event)))
2177 (*(((XwMenuMgrWidgetClass)
2178 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseRight))
2179 (w->menubutton.menuMgr, event);
2184 /*************************************<->*************************************
2186 * TraverseLeft(w, event)
2188 * Description:
2189 * -----------
2191 * Inputs:
2192 * ------
2194 * Outputs:
2195 * -------
2197 * Procedures Called
2198 * -----------------
2200 *************************************<->***********************************/
2202 static void TraverseLeft (w, event)
2204 XwMenuButtonWidget w;
2205 XEvent * event;
2209 * Ask the menu manager to traverse to the previous menupane.
2212 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2213 (w->primitive.I_have_traversal))
2215 (*(((XwMenuMgrWidgetClass)
2216 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseLeft))
2217 (w->menubutton.menuMgr, event);
2222 /*************************************<->*************************************
2224 * TraverseNext(w, event)
2226 * Description:
2227 * -----------
2229 * Inputs:
2230 * ------
2232 * Outputs:
2233 * -------
2235 * Procedures Called
2236 * -----------------
2238 *************************************<->***********************************/
2240 static void TraverseNext (w, event)
2242 XwMenuButtonWidget w;
2243 XEvent * event;
2247 * Ask the menu manager to traverse to the previous menupane.
2250 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2251 (w->primitive.I_have_traversal))
2253 (*(((XwMenuMgrWidgetClass)
2254 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseNext))
2255 (w->menubutton.menuMgr, event);
2260 /*************************************<->*************************************
2262 * TraversePrev(w, event)
2264 * Description:
2265 * -----------
2267 * Inputs:
2268 * ------
2270 * Outputs:
2271 * -------
2273 * Procedures Called
2274 * -----------------
2276 *************************************<->***********************************/
2278 static void TraversePrev (w, event)
2280 XwMenuButtonWidget w;
2281 XEvent * event;
2285 * Ask the menu manager to traverse to the previous menupane.
2288 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2289 (w->primitive.I_have_traversal))
2291 (*(((XwMenuMgrWidgetClass)
2292 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traversePrev))
2293 (w->menubutton.menuMgr, event);
2298 /*************************************<->*************************************
2300 * TraverseHome(w)
2302 * Description:
2303 * -----------
2305 * Inputs:
2306 * ------
2308 * Outputs:
2309 * -------
2311 * Procedures Called
2312 * -----------------
2314 *************************************<->***********************************/
2316 static void TraverseHome (w, event)
2318 XwMenuButtonWidget w;
2319 XEvent * event;
2323 * Ask the menu manager to traverse to the first menupane.
2326 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2327 (w->primitive.I_have_traversal))
2329 (*(((XwMenuMgrWidgetClass)
2330 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseHome))
2331 (w->menubutton.menuMgr, event);
2336 /*************************************<->*************************************
2338 * TraverseUp(w)
2340 * Description:
2341 * -----------
2343 * Inputs:
2344 * ------
2346 * Outputs:
2347 * -------
2349 * Procedures Called
2350 * -----------------
2352 *************************************<->***********************************/
2354 static void TraverseUp (w, event)
2356 XwMenuButtonWidget w;
2357 XEvent * event;
2361 * Ask the menu manager to traverse up one menu button
2364 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2365 (w->primitive.I_have_traversal))
2367 (*(((XwMenuMgrWidgetClass)
2368 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseUp))
2369 (w->menubutton.menuMgr, event);
2374 /*************************************<->*************************************
2376 * TraverseDown(w)
2378 * Description:
2379 * -----------
2381 * Inputs:
2382 * ------
2384 * Outputs:
2385 * -------
2387 * Procedures Called
2388 * -----------------
2390 *************************************<->***********************************/
2392 static void TraverseDown (w, event)
2394 XwMenuButtonWidget w;
2395 XEvent * event;
2399 * Ask the menu manager to traverse down one menu button
2402 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2403 (w->primitive.I_have_traversal))
2405 (*(((XwMenuMgrWidgetClass)
2406 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseDown))
2407 (w->menubutton.menuMgr, event);
2412 /*************************************<->*************************************
2414 * TraverseNextTop(w)
2416 * Description:
2417 * -----------
2419 * Inputs:
2420 * ------
2422 * Outputs:
2423 * -------
2425 * Procedures Called
2426 * -----------------
2428 *************************************<->***********************************/
2430 static void TraverseNextTop (w, event)
2432 XwMenuButtonWidget w;
2433 XEvent * event;
2437 * Ask the menu manager to traverse to the next top level menupane
2440 if ((w->menubutton.menuMgr) && (_XwUniqueEvent (event)) &&
2441 (w->primitive.I_have_traversal))
2443 (*(((XwMenuMgrWidgetClass)
2444 XtClass(w->menubutton.menuMgr))->menu_mgr_class.traverseNextTop))
2445 (w->menubutton.menuMgr, event);
2450 /************************************************************************
2452 * _XwExtractTime
2453 * Extract the time field from the event structure.
2455 ************************************************************************/
2457 static Time _XwExtractTime (event)
2459 XEvent * event;
2462 if ((event->type == ButtonPress) || (event->type == ButtonRelease))
2463 return (event->xbutton.time);
2465 if ((event->type == KeyPress) || (event->type == KeyRelease))
2466 return (event->xkey.time);
2468 return ((Time) 0);
2472 Boolean _XwUniqueEvent (event)
2474 XEvent * event;
2477 static unsigned long serial = 0;
2478 static Time time = 0;
2479 static int type = 0;
2480 Time newTime;
2483 * Ignore duplicate events, caused by an event being dispatched
2484 * to both the focus widget and the spring-loaded widget, where
2485 * these map to the same widget (menus).
2487 if ((time != (newTime = _XwExtractTime (event))) ||
2488 (type != event->type) ||
2489 (serial != event->xany.serial))
2491 /* Save the fingerprints for the new event */
2492 type = event->type;
2493 serial = event->xany.serial;
2494 time = newTime;
2496 return (TRUE);
2499 return (FALSE);
2503 /*************************************<->*************************************
2505 * Visibility(parameters)
2507 * Description:
2508 * -----------
2509 * xxxxxxxxxxxxxxxxxxxxxxx
2512 * Inputs:
2513 * ------
2514 * xxxxxxxxxxxx = xxxxxxxxxxxxx
2516 * Outputs:
2517 * -------
2518 * xxxxxxxxxxxx = xxxxxxxxxxxxx
2520 * Procedures Called
2521 * -----------------
2523 *************************************<->***********************************/
2525 static void Visibility (widget, event)
2527 Widget widget;
2528 XEvent * event;
2532 * Noop; purpose is to prevent Primitive's translation from
2533 * taking effect.
2538 /*************************************<->*************************************
2540 * Unmap(parameters)
2542 * Description:
2543 * -----------
2544 * xxxxxxxxxxxxxxxxxxxxxxx
2547 * Inputs:
2548 * ------
2549 * xxxxxxxxxxxx = xxxxxxxxxxxxx
2551 * Outputs:
2552 * -------
2553 * xxxxxxxxxxxx = xxxxxxxxxxxxx
2555 * Procedures Called
2556 * -----------------
2558 *************************************<->***********************************/
2560 static void Unmap (widget, event)
2562 Widget widget;
2563 XEvent * event;
2567 * Noop; purpose is to prevent Primitive's translation from
2568 * taking effect.