SimpleMenu.c revision 5b16253f
17a84e134Smrg/* 27a84e134SmrgCopyright 1989, 1994, 1998 The Open Group 37a84e134Smrg 47a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its 57a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that 67a84e134Smrgthe above copyright notice appear in all copies and that both that 77a84e134Smrgcopyright notice and this permission notice appear in supporting 87a84e134Smrgdocumentation. 97a84e134Smrg 107a84e134SmrgThe above copyright notice and this permission notice shall be included in 117a84e134Smrgall copies or substantial portions of the Software. 127a84e134Smrg 137a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 147a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 157a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 167a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 177a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 187a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 197a84e134Smrg 207a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be 217a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings 227a84e134Smrgin this Software without prior written authorization from The Open Group. 237a84e134Smrg */ 247a84e134Smrg 257a84e134Smrg/* 267a84e134Smrg * SimpleMenu.c - Source code file for SimpleMenu widget. 277a84e134Smrg * 287a84e134Smrg * Date: April 3, 1989 297a84e134Smrg * 307a84e134Smrg * By: Chris D. Peterson 31421c997bSmrg * MIT X Consortium 327a84e134Smrg * kit@expo.lcs.mit.edu 337a84e134Smrg */ 347a84e134Smrg 357a84e134Smrg#ifdef HAVE_CONFIG_H 367a84e134Smrg#include <config.h> 377a84e134Smrg#endif 387a84e134Smrg#include <stdio.h> 397a84e134Smrg#include <X11/IntrinsicP.h> 407a84e134Smrg#include <X11/StringDefs.h> 417a84e134Smrg#include <X11/Xmu/Initer.h> 427a84e134Smrg#include <X11/Xaw/Cardinals.h> 437a84e134Smrg#include <X11/Xaw/SimpleMenP.h> 447a84e134Smrg#include <X11/Xaw/SmeBSBP.h> 457a84e134Smrg#include <X11/Xaw/XawInit.h> 467a84e134Smrg#include "Private.h" 477a84e134Smrg 487a84e134Smrg#define streq(a, b) (strcmp((a), (b)) == 0) 497a84e134Smrg 507a84e134Smrg#define ForAllChildren(smw, childP) \ 517a84e134Smrgfor ((childP) = (SmeObject *)(smw)->composite.children; \ 527a84e134Smrg (childP) < (SmeObject *)((smw)->composite.children \ 537a84e134Smrg + (smw)->composite.num_children); \ 547a84e134Smrg (childP)++) 557a84e134Smrg 567a84e134Smrg#ifndef OLDXAW 577a84e134Smrg#define SMW_UNMAPPING 0x01 587a84e134Smrg#define SMW_POPLEFT 0x02 597a84e134Smrg#endif 607a84e134Smrg 617a84e134Smrg/* 627a84e134Smrg * Class Methods 637a84e134Smrg */ 647a84e134Smrgstatic void XawSimpleMenuChangeManaged(Widget); 657a84e134Smrgstatic void XawSimpleMenuClassInitialize(void); 667a84e134Smrgstatic void XawSimpleMenuClassPartInitialize(WidgetClass); 677a84e134Smrgstatic XtGeometryResult XawSimpleMenuGeometryManager(Widget, XtWidgetGeometry*, 687a84e134Smrg XtWidgetGeometry*); 697a84e134Smrgstatic void XawSimpleMenuInitialize(Widget, Widget, ArgList, Cardinal*); 707a84e134Smrgstatic void XawSimpleMenuRealize(Widget, XtValueMask*, XSetWindowAttributes*); 717a84e134Smrgstatic void XawSimpleMenuRedisplay(Widget, XEvent*, Region); 727a84e134Smrgstatic void XawSimpleMenuResize(Widget); 737a84e134Smrgstatic Boolean XawSimpleMenuSetValues(Widget, Widget, Widget, 747a84e134Smrg ArgList, Cardinal*); 757a84e134Smrgstatic Boolean XawSimpleMenuSetValuesHook(Widget, ArgList, Cardinal*); 767a84e134Smrg#ifndef OLDXAW 777a84e134Smrgstatic void PopupSubMenu(SimpleMenuWidget); 787a84e134Smrgstatic void PopdownSubMenu(SimpleMenuWidget); 797a84e134Smrgstatic void PopupCB(Widget, XtPointer, XtPointer); 807a84e134Smrg#endif 817a84e134Smrg 827a84e134Smrg/* 837a84e134Smrg * Prototypes 847a84e134Smrg */ 857a84e134Smrgstatic void AddPositionAction(XtAppContext, XPointer); 867a84e134Smrgstatic void CalculateNewSize(Widget, Dimension*, Dimension*); 877a84e134Smrgstatic void ChangeCursorOnGrab(Widget, XtPointer, XtPointer); 887a84e134Smrgstatic void CreateLabel(Widget); 897a84e134Smrgstatic SmeObject DoGetEventEntry(Widget, int, int); 907a84e134Smrgstatic Widget FindMenu(Widget, String); 917a84e134Smrgstatic SmeObject GetEventEntry(Widget, XEvent*); 927a84e134Smrgstatic void Layout(Widget, Dimension*, Dimension*); 937a84e134Smrgstatic void MakeResizeRequest(Widget); 947a84e134Smrgstatic void MakeSetValuesRequest(Widget, unsigned int, unsigned int); 957a84e134Smrgstatic void MoveMenu(Widget, int, int); 967a84e134Smrgstatic void PositionMenu(Widget, XPoint*); 977a84e134Smrg 987a84e134Smrg/* 997a84e134Smrg * Actions 1007a84e134Smrg */ 1017a84e134Smrgstatic void Highlight(Widget, XEvent*, String*, Cardinal*); 1027a84e134Smrgstatic void Notify(Widget, XEvent*, String*, Cardinal*); 1037a84e134Smrg#ifndef OLDXAW 1047a84e134Smrgstatic void Popdown(Widget, XEvent*, String*, Cardinal*); 1057a84e134Smrg#endif 1067a84e134Smrgstatic void PositionMenuAction(Widget, XEvent*, String*, Cardinal*); 1077a84e134Smrgstatic void Unhighlight(Widget, XEvent*, String*, Cardinal*); 1087a84e134Smrg 1097a84e134Smrg/* 1107a84e134Smrg * Initialization 1117a84e134Smrg */ 1127a84e134Smrg#define offset(field) XtOffsetOf(SimpleMenuRec, simple_menu.field) 1137a84e134Smrg 1147a84e134Smrgstatic XtResource resources[] = { 1157a84e134Smrg /* label */ 1167a84e134Smrg { 1177a84e134Smrg XtNlabel, 1187a84e134Smrg XtCLabel, 1197a84e134Smrg XtRString, 1207a84e134Smrg sizeof(String), 1217a84e134Smrg offset(label_string), 1227a84e134Smrg XtRString, 1237a84e134Smrg NULL 1247a84e134Smrg }, 1257a84e134Smrg { 1267a84e134Smrg XtNlabelClass, 1277a84e134Smrg XtCLabelClass, 1287a84e134Smrg XtRPointer, 1297a84e134Smrg sizeof(WidgetClass), 1307a84e134Smrg offset(label_class), 1317a84e134Smrg XtRImmediate, 1327a84e134Smrg NULL 1337a84e134Smrg }, 1347a84e134Smrg 1357a84e134Smrg /* layout */ 1367a84e134Smrg { 1377a84e134Smrg XtNrowHeight, 1387a84e134Smrg XtCRowHeight, 1397a84e134Smrg XtRDimension, 1407a84e134Smrg sizeof(Dimension), 1417a84e134Smrg offset(row_height), 1427a84e134Smrg XtRImmediate, 1437a84e134Smrg (XtPointer)0 1447a84e134Smrg }, 1457a84e134Smrg { 1467a84e134Smrg XtNtopMargin, 1477a84e134Smrg XtCVerticalMargins, 1487a84e134Smrg XtRDimension, 1497a84e134Smrg sizeof(Dimension), 1507a84e134Smrg offset(top_margin), 1517a84e134Smrg XtRImmediate, 1527a84e134Smrg (XtPointer)0 1537a84e134Smrg }, 1547a84e134Smrg { 1557a84e134Smrg XtNbottomMargin, 1567a84e134Smrg XtCVerticalMargins, 1577a84e134Smrg XtRDimension, 1587a84e134Smrg sizeof(Dimension), 1597a84e134Smrg offset(bottom_margin), 1607a84e134Smrg XtRImmediate, 1617a84e134Smrg (XtPointer)0 1627a84e134Smrg }, 1637a84e134Smrg#ifndef OLDXAW 1647a84e134Smrg { 1657a84e134Smrg XtNleftMargin, 1667a84e134Smrg XtCHorizontalMargins, 1677a84e134Smrg XtRDimension, 1687a84e134Smrg sizeof(Dimension), 1697a84e134Smrg offset(left_margin), 1707a84e134Smrg XtRImmediate, 1717a84e134Smrg (XtPointer)0 1727a84e134Smrg }, 1737a84e134Smrg { 1747a84e134Smrg XtNrightMargin, 1757a84e134Smrg XtCHorizontalMargins, 1767a84e134Smrg XtRDimension, 1777a84e134Smrg sizeof(Dimension), 1787a84e134Smrg offset(right_margin), 1797a84e134Smrg XtRImmediate, 1807a84e134Smrg (XtPointer)0 1817a84e134Smrg }, 1827a84e134Smrg#endif 1837a84e134Smrg 1847a84e134Smrg /* misc */ 1857a84e134Smrg { 1867a84e134Smrg XtNallowShellResize, 1877a84e134Smrg XtCAllowShellResize, 1887a84e134Smrg XtRBoolean, 1897a84e134Smrg sizeof(Boolean), 1907a84e134Smrg XtOffsetOf(SimpleMenuRec, shell.allow_shell_resize), 1917a84e134Smrg XtRImmediate, 1927a84e134Smrg (XtPointer)True 1937a84e134Smrg }, 1947a84e134Smrg { 1957a84e134Smrg XtNcursor, 1967a84e134Smrg XtCCursor, 1977a84e134Smrg XtRCursor, 1987a84e134Smrg sizeof(Cursor), 1997a84e134Smrg offset(cursor), 2007a84e134Smrg XtRImmediate, 2017a84e134Smrg (XtPointer)None 2027a84e134Smrg }, 2037a84e134Smrg { 2047a84e134Smrg XtNmenuOnScreen, 2057a84e134Smrg XtCMenuOnScreen, 2067a84e134Smrg XtRBoolean, 2077a84e134Smrg sizeof(Boolean), 2087a84e134Smrg offset(menu_on_screen), 2097a84e134Smrg XtRImmediate, 2107a84e134Smrg (XtPointer)True 2117a84e134Smrg }, 2127a84e134Smrg { 2137a84e134Smrg XtNpopupOnEntry, 2147a84e134Smrg XtCPopupOnEntry, 2157a84e134Smrg XtRWidget, 2167a84e134Smrg sizeof(Widget), 2177a84e134Smrg offset(popup_entry), 2187a84e134Smrg XtRWidget, 2197a84e134Smrg NULL 2207a84e134Smrg }, 2217a84e134Smrg { 2227a84e134Smrg XtNbackingStore, 2237a84e134Smrg XtCBackingStore, 2247a84e134Smrg XtRBackingStore, 2257a84e134Smrg sizeof(int), 226421c997bSmrg offset(backing_store), 2277a84e134Smrg XtRImmediate, 2287a84e134Smrg (XtPointer)(Always + WhenMapped + NotUseful) 2297a84e134Smrg }, 2307a84e134Smrg#ifndef OLDXAW 2317a84e134Smrg { 2327a84e134Smrg XawNdisplayList, 2337a84e134Smrg XawCDisplayList, 2347a84e134Smrg XawRDisplayList, 2357a84e134Smrg sizeof(XawDisplayList*), 236421c997bSmrg offset(display_list), 2377a84e134Smrg XtRImmediate, 2387a84e134Smrg NULL 2397a84e134Smrg }, 2407a84e134Smrg#endif 241421c997bSmrg}; 2427a84e134Smrg#undef offset 2437a84e134Smrg 2447a84e134Smrgstatic char defaultTranslations[] = 2457a84e134Smrg"<Enter>:" "highlight()\n" 2467a84e134Smrg"<Leave>:" "unhighlight()\n" 2477a84e134Smrg"<BtnMotion>:" "highlight()\n" 2487a84e134Smrg#ifndef OLDXAW 2497a84e134Smrg"<BtnUp>:" "popdown() notify() unhighlight()\n" 2507a84e134Smrg#else 2517a84e134Smrg"<BtnUp>:" "MenuPopdown() notify() unhighlight()\n" 2527a84e134Smrg#endif 2537a84e134Smrg; 2547a84e134Smrg 2557a84e134Smrgstatic XtActionsRec actionsList[] = 2567a84e134Smrg{ 2577a84e134Smrg {"notify", Notify}, 2587a84e134Smrg {"highlight", Highlight}, 2597a84e134Smrg {"unhighlight", Unhighlight}, 2607a84e134Smrg#ifndef OLDXAW 2617a84e134Smrg {"popdown", Popdown}, 2627a84e134Smrg {"set-values", XawSetValuesAction}, 2637a84e134Smrg {"get-values", XawGetValuesAction}, 2647a84e134Smrg {"declare", XawDeclareAction}, 2657a84e134Smrg {"call-proc", XawCallProcAction}, 2667a84e134Smrg#endif 2677a84e134Smrg}; 268421c997bSmrg 2697a84e134Smrgstatic CompositeClassExtensionRec extension_rec = { 2707a84e134Smrg NULL, /* next_extension */ 2717a84e134Smrg NULLQUARK, /* record_type */ 2727a84e134Smrg XtCompositeExtensionVersion, /* version */ 2737a84e134Smrg sizeof(CompositeClassExtensionRec), /* record_size */ 2747a84e134Smrg True, /* accepts_objects */ 2757a84e134Smrg}; 2767a84e134Smrg 2777a84e134Smrg#define Superclass (&overrideShellClassRec) 2787a84e134SmrgSimpleMenuClassRec simpleMenuClassRec = { 2797a84e134Smrg /* core */ 2807a84e134Smrg { 2817a84e134Smrg (WidgetClass)Superclass, /* superclass */ 2827a84e134Smrg "SimpleMenu", /* class_name */ 2837a84e134Smrg sizeof(SimpleMenuRec), /* size */ 2847a84e134Smrg XawSimpleMenuClassInitialize, /* class_initialize */ 2857a84e134Smrg XawSimpleMenuClassPartInitialize, /* class_part_initialize */ 2867a84e134Smrg False, /* class_inited */ 2877a84e134Smrg XawSimpleMenuInitialize, /* initialize */ 2887a84e134Smrg NULL, /* initialize_hook */ 2897a84e134Smrg XawSimpleMenuRealize, /* realize */ 2907a84e134Smrg actionsList, /* actions */ 2917a84e134Smrg XtNumber(actionsList), /* num_actions */ 2927a84e134Smrg resources, /* resources */ 2937a84e134Smrg XtNumber(resources), /* num_resources */ 2947a84e134Smrg NULLQUARK, /* xrm_class */ 2957a84e134Smrg True, /* compress_motion */ 2967a84e134Smrg True, /* compress_exposure */ 2977a84e134Smrg True, /* compress_enterleave */ 2987a84e134Smrg False, /* visible_interest */ 2997a84e134Smrg NULL, /* destroy */ 3007a84e134Smrg XawSimpleMenuResize, /* resize */ 3017a84e134Smrg XawSimpleMenuRedisplay, /* expose */ 3027a84e134Smrg XawSimpleMenuSetValues, /* set_values */ 3037a84e134Smrg XawSimpleMenuSetValuesHook, /* set_values_hook */ 3047a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 3057a84e134Smrg NULL, /* get_values_hook */ 3067a84e134Smrg NULL, /* accept_focus */ 3077a84e134Smrg XtVersion, /* intrinsics version */ 3087a84e134Smrg NULL, /* callback offsets */ 3097a84e134Smrg defaultTranslations, /* tm_table */ 3107a84e134Smrg NULL, /* query_geometry */ 3117a84e134Smrg NULL, /* display_accelerator */ 3127a84e134Smrg NULL, /* extension */ 3137a84e134Smrg }, 3147a84e134Smrg /* composite */ 3157a84e134Smrg { 3167a84e134Smrg XawSimpleMenuGeometryManager, /* geometry_manager */ 3177a84e134Smrg XawSimpleMenuChangeManaged, /* change_managed */ 3187a84e134Smrg XtInheritInsertChild, /* insert_child */ 3197a84e134Smrg XtInheritDeleteChild, /* delete_child */ 3207a84e134Smrg NULL, /* extension */ 3217a84e134Smrg }, 3227a84e134Smrg /* shell */ 3237a84e134Smrg { 3247a84e134Smrg NULL, /* extension */ 3257a84e134Smrg }, 3267a84e134Smrg /* override */ 3277a84e134Smrg { 3287a84e134Smrg NULL, /* extension */ 3297a84e134Smrg }, 3307a84e134Smrg /* simple_menu */ 3317a84e134Smrg { 3327a84e134Smrg NULL, /* extension */ 3337a84e134Smrg }, 3347a84e134Smrg}; 3357a84e134Smrg 3367a84e134SmrgWidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec; 3377a84e134Smrg 3387a84e134Smrg/* 3397a84e134Smrg * Implementation 3407a84e134Smrg */ 3417a84e134Smrg/* 3427a84e134Smrg * Function: 3437a84e134Smrg * XawSimpleMenuClassInitialize 3447a84e134Smrg * 3457a84e134Smrg * Description: 3467a84e134Smrg * Class Initialize routine, called only once. 3477a84e134Smrg */ 3487a84e134Smrgstatic void 3497a84e134SmrgXawSimpleMenuClassInitialize(void) 3507a84e134Smrg{ 3517a84e134Smrg XawInitializeWidgetSet(); 3527a84e134Smrg XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, 3537a84e134Smrg NULL, 0); 3547a84e134Smrg XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString, 3557a84e134Smrg NULL, 0, XtCacheNone, NULL); 3567a84e134Smrg XmuAddInitializer(AddPositionAction, NULL); 3577a84e134Smrg} 3587a84e134Smrg 3597a84e134Smrg/* 3607a84e134Smrg * Function: 3617a84e134Smrg * XawSimpleMenuClassPartInitialize 3627a84e134Smrg * Arguments: wc - the widget class of the subclass. 3637a84e134Smrg * 3647a84e134Smrg * Description: 3657a84e134Smrg * Class Part Initialize routine, called for every subclass. Makes 3667a84e134Smrg * sure that the subclasses pick up the extension record. 3677a84e134Smrg */ 3687a84e134Smrgstatic void 3697a84e134SmrgXawSimpleMenuClassPartInitialize(WidgetClass wc) 3707a84e134Smrg{ 3717a84e134Smrg SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass)wc; 3727a84e134Smrg 3737a84e134Smrg /* 3747a84e134Smrg * Make sure that our subclass gets the extension rec too 3757a84e134Smrg */ 3767a84e134Smrg extension_rec.next_extension = smwc->composite_class.extension; 3777a84e134Smrg smwc->composite_class.extension = (XtPointer) &extension_rec; 3787a84e134Smrg} 3797a84e134Smrg 3807a84e134Smrg/* 3817a84e134Smrg * Function: 3827a84e134Smrg * XawSimpleMenuInitialize 3837a84e134Smrg * 3847a84e134Smrg * Parameters: 3857a84e134Smrg * request - widget requested by the argument list 3867a84e134Smrg * cnew - new widget with both resource and non resource values 3877a84e134Smrg * 3887a84e134Smrg * Description: 3897a84e134Smrg * Initializes the simple menu widget. 3907a84e134Smrg */ 3917a84e134Smrg/*ARGSUSED*/ 3927a84e134Smrgstatic void 3935ec34c4cSmrgXawSimpleMenuInitialize(Widget request _X_UNUSED, Widget cnew, 3945ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 3957a84e134Smrg{ 3967a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)cnew; 3977a84e134Smrg Dimension width, height; 3987a84e134Smrg 3997a84e134Smrg XmuCallInitializers(XtWidgetToApplicationContext(cnew)); 4007a84e134Smrg 401421c997bSmrg if (smw->simple_menu.label_class == NULL) 4027a84e134Smrg smw->simple_menu.label_class = smeBSBObjectClass; 4037a84e134Smrg 4047a84e134Smrg smw->simple_menu.label = NULL; 4057a84e134Smrg smw->simple_menu.entry_set = NULL; 4067a84e134Smrg smw->simple_menu.recursive_set_values = False; 4077a84e134Smrg#ifndef OLDXAW 4087a84e134Smrg smw->simple_menu.sub_menu = NULL; 4097a84e134Smrg smw->simple_menu.state = 0; 4107a84e134Smrg 4117a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, PopupCB, NULL); 4127a84e134Smrg#endif 4137a84e134Smrg 4147a84e134Smrg if (smw->simple_menu.label_string != NULL) 4157a84e134Smrg CreateLabel(cnew); 4167a84e134Smrg 4177a84e134Smrg width = height = 0; 4187a84e134Smrg CalculateNewSize(cnew, &width, &height); 4197a84e134Smrg 4207a84e134Smrg smw->simple_menu.menu_width = True; 4217a84e134Smrg 4227a84e134Smrg if (XtWidth(smw) == 0) { 4237a84e134Smrg smw->simple_menu.menu_width = False; 4247a84e134Smrg XtWidth(smw) = width; 4257a84e134Smrg } 4267a84e134Smrg 4277a84e134Smrg smw->simple_menu.menu_height = True; 4287a84e134Smrg 4297a84e134Smrg if (XtHeight(smw) == 0) { 4307a84e134Smrg smw->simple_menu.menu_height = False; 4317a84e134Smrg XtHeight(smw) = height; 4327a84e134Smrg } 4337a84e134Smrg 4347a84e134Smrg /* 4357a84e134Smrg * Add a popup_callback routine for changing the cursor 4367a84e134Smrg */ 4377a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, ChangeCursorOnGrab, NULL); 4387a84e134Smrg} 4397a84e134Smrg 4407a84e134Smrg/* 4417a84e134Smrg * Function: 4427a84e134Smrg * XawSimpleMenuRedisplay 4437a84e134Smrg * 4447a84e134Smrg * Parameters: 4457a84e134Smrg * w - simple menu widget 4467a84e134Smrg * event - X event that caused this redisplay 4477a84e134Smrg * region - region the needs to be repainted 4487a84e134Smrg * 4497a84e134Smrg * Description: 4507a84e134Smrg * Redisplays the contents of the widget. 4517a84e134Smrg */ 4527a84e134Smrg/*ARGSUSED*/ 4537a84e134Smrgstatic void 4545ec34c4cSmrgXawSimpleMenuRedisplay(Widget w, XEvent *event _X_UNUSED, Region region) 4557a84e134Smrg{ 4567a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 4577a84e134Smrg SmeObject *entry; 4587a84e134Smrg SmeObjectClass cclass; 4597a84e134Smrg 4607a84e134Smrg if (region == NULL) 4617a84e134Smrg XClearWindow(XtDisplay(w), XtWindow(w)); 4627a84e134Smrg 4637a84e134Smrg#ifndef OLDXAW 4647a84e134Smrg if (smw->simple_menu.display_list) 4657a84e134Smrg XawRunDisplayList(w, smw->simple_menu.display_list, event, region); 4667a84e134Smrg#endif 4677a84e134Smrg 4687a84e134Smrg /* 4697a84e134Smrg * Check and Paint each of the entries - including the label 4707a84e134Smrg */ 4717a84e134Smrg ForAllChildren(smw, entry) { 4727a84e134Smrg if (!XtIsManaged((Widget)*entry)) 4737a84e134Smrg continue; 4747a84e134Smrg 475421c997bSmrg if (region != NULL) 4767a84e134Smrg switch(XRectInRegion(region, XtX(*entry),XtY(*entry), 4777a84e134Smrg XtWidth(*entry), XtHeight(*entry))) { 4787a84e134Smrg case RectangleIn: 4797a84e134Smrg case RectanglePart: 4807a84e134Smrg break; 4817a84e134Smrg default: 4827a84e134Smrg continue; 4837a84e134Smrg } 4847a84e134Smrg 4857a84e134Smrg cclass = (SmeObjectClass)(*entry)->object.widget_class; 4867a84e134Smrg 4877a84e134Smrg if (cclass->rect_class.expose != NULL) 4887a84e134Smrg (cclass->rect_class.expose)((Widget)*entry, NULL, NULL); 4897a84e134Smrg } 4907a84e134Smrg} 4917a84e134Smrg 4927a84e134Smrg/* 4937a84e134Smrg * Function: 4947a84e134Smrg * XawSimpleMenuRealize 4957a84e134Smrg * 4967a84e134Smrg * Parameters: 4977a84e134Smrg * w - simple menu widget 4987a84e134Smrg * mask - value mask for the window to create 4997a84e134Smrg * attrs - attributes for the window to create 5007a84e134Smrg * 5017a84e134Smrg * Description: 5027a84e134Smrg * Realizes the widget. 5037a84e134Smrg */ 5047a84e134Smrgstatic void 5057a84e134SmrgXawSimpleMenuRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attrs) 5067a84e134Smrg{ 5077a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 5087a84e134Smrg#ifndef OLDXAW 5097a84e134Smrg XawPixmap *pixmap; 5107a84e134Smrg#endif 5117a84e134Smrg 5127a84e134Smrg attrs->cursor = smw->simple_menu.cursor; 5137a84e134Smrg *mask |= CWCursor; 5147a84e134Smrg if (smw->simple_menu.backing_store == Always || 5157a84e134Smrg smw->simple_menu.backing_store == NotUseful || 5167a84e134Smrg smw->simple_menu.backing_store == WhenMapped) { 5177a84e134Smrg *mask |= CWBackingStore; 5187a84e134Smrg attrs->backing_store = smw->simple_menu.backing_store; 5197a84e134Smrg } 5207a84e134Smrg else 5215ec34c4cSmrg *mask &= (XtValueMask)(~CWBackingStore); 5227a84e134Smrg 5237a84e134Smrg (*Superclass->core_class.realize)(w, mask, attrs); 5247a84e134Smrg 5257a84e134Smrg#ifndef OLDXAW 5267a84e134Smrg if (w->core.background_pixmap > XtUnspecifiedPixmap) { 5277a84e134Smrg pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), 5285ec34c4cSmrg w->core.colormap, (int)w->core.depth); 5297a84e134Smrg if (pixmap && pixmap->mask) 5307a84e134Smrg XawReshapeWidget(w, pixmap); 5317a84e134Smrg } 5327a84e134Smrg#endif 5337a84e134Smrg} 5347a84e134Smrg 5357a84e134Smrg/* 5367a84e134Smrg * Function: 5377a84e134Smrg * XawSimpleMenuResize 5387a84e134Smrg * 5397a84e134Smrg * Parameters: 5407a84e134Smrg * w - simple menu widget 5417a84e134Smrg * 5427a84e134Smrg * Description: 5437a84e134Smrg * Handle the menu being resized. 5447a84e134Smrg */ 5457a84e134Smrgstatic void 5467a84e134SmrgXawSimpleMenuResize(Widget w) 5477a84e134Smrg{ 5487a84e134Smrg if (!XtIsRealized(w)) 5497a84e134Smrg return; 5507a84e134Smrg 5517a84e134Smrg Layout(w, NULL, NULL); 5527a84e134Smrg 5537a84e134Smrg XawSimpleMenuRedisplay(w, NULL, NULL); 5547a84e134Smrg} 5557a84e134Smrg 5567a84e134Smrg/* 5577a84e134Smrg * Function: 5587a84e134Smrg * XawSimpleMenuSetValues 5597a84e134Smrg * 5607a84e134Smrg * Parameters: 5617a84e134Smrg * current - current state of the widget 5627a84e134Smrg * request - what was requested 5637a84e134Smrg * cnew - what the widget will become 5647a84e134Smrg * 5657a84e134Smrg * Description: 5667a84e134Smrg * Relayout the menu when one of the resources is changed. 5677a84e134Smrg */ 5687a84e134Smrg/*ARGSUSED*/ 5697a84e134Smrgstatic Boolean 5705ec34c4cSmrgXawSimpleMenuSetValues(Widget current, Widget request _X_UNUSED, Widget cnew, 5715ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 5727a84e134Smrg{ 5737a84e134Smrg SimpleMenuWidget smw_old = (SimpleMenuWidget)current; 5747a84e134Smrg SimpleMenuWidget smw_new = (SimpleMenuWidget)cnew; 5757a84e134Smrg Boolean ret_val = False, layout = False; 5767a84e134Smrg 5777a84e134Smrg if (!XtIsRealized(current)) 5787a84e134Smrg return (False); 5797a84e134Smrg 5807a84e134Smrg if (!smw_new->simple_menu.recursive_set_values) { 5817a84e134Smrg if (XtWidth(smw_new) != XtWidth(smw_old)) { 5827a84e134Smrg smw_new->simple_menu.menu_width = XtWidth(smw_new) != 0; 5837a84e134Smrg layout = True; 5847a84e134Smrg } 5857a84e134Smrg if (XtHeight(smw_new) != XtHeight(smw_old)) { 5867a84e134Smrg smw_new->simple_menu.menu_height = XtHeight(smw_new) != 0; 5877a84e134Smrg layout = True; 5887a84e134Smrg } 5897a84e134Smrg } 5907a84e134Smrg 5917a84e134Smrg if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor) 5927a84e134Smrg XDefineCursor(XtDisplay(cnew), XtWindow(cnew), 5937a84e134Smrg smw_new->simple_menu.cursor); 5947a84e134Smrg 5957a84e134Smrg if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string) { 5967a84e134Smrg if (smw_new->simple_menu.label_string == NULL) /* Destroy */ 5977a84e134Smrg XtDestroyWidget((Widget)smw_old->simple_menu.label); 5987a84e134Smrg else if (smw_old->simple_menu.label_string == NULL) /* Create */ 5997a84e134Smrg CreateLabel(cnew); 6007a84e134Smrg else { /* Change */ 6017a84e134Smrg Arg arglist[1]; 602421c997bSmrg 6037a84e134Smrg XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string); 6047a84e134Smrg XtSetValues((Widget)smw_new->simple_menu.label, arglist, ONE); 6057a84e134Smrg } 6067a84e134Smrg } 6077a84e134Smrg 6087a84e134Smrg if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class) 6097a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(cnew), 6107a84e134Smrg "No Dynamic class change of the SimpleMenu Label."); 611421c997bSmrg 6127a84e134Smrg if (smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin 6137a84e134Smrg || smw_old->simple_menu.bottom_margin 6147a84e134Smrg != smw_new->simple_menu.bottom_margin) { 6157a84e134Smrg layout = True; 6167a84e134Smrg ret_val = True; 6177a84e134Smrg } 6187a84e134Smrg 6197a84e134Smrg#ifndef OLDXAW 6207a84e134Smrg if (smw_old->core.background_pixmap != smw_new->core.background_pixmap) { 6217a84e134Smrg XawPixmap *opix, *npix; 6227a84e134Smrg 6237a84e134Smrg opix = XawPixmapFromXPixmap(smw_old->core.background_pixmap, 6247a84e134Smrg XtScreen(smw_old), smw_old->core.colormap, 6255ec34c4cSmrg (int)smw_old->core.depth); 6267a84e134Smrg npix = XawPixmapFromXPixmap(smw_new->core.background_pixmap, 6277a84e134Smrg XtScreen(smw_new), smw_new->core.colormap, 6285ec34c4cSmrg (int)smw_new->core.depth); 6297a84e134Smrg if ((npix && npix->mask) || (opix && opix->mask)) 6307a84e134Smrg XawReshapeWidget(cnew, npix); 6317a84e134Smrg } 6327a84e134Smrg#endif 6337a84e134Smrg 6347a84e134Smrg if (layout) 6357a84e134Smrg Layout(cnew, NULL, NULL); 6367a84e134Smrg 6377a84e134Smrg return (ret_val); 6387a84e134Smrg} 6397a84e134Smrg 640421c997bSmrg/* 6417a84e134Smrg * Function: 6427a84e134Smrg * XawSimpleMenuSetValuesHook 6437a84e134Smrg * 6447a84e134Smrg * Parameters: 6457a84e134Smrg * w - menu widget 6467a84e134Smrg * arglist - argument list passed to XtSetValues 6477a84e134Smrg * num_args - number of args 6487a84e134Smrg * 6497a84e134Smrg * Description: 6507a84e134Smrg * To handle a special case, this is passed the actual arguments. 6517a84e134Smrg */ 6527a84e134Smrgstatic Boolean 6537a84e134SmrgXawSimpleMenuSetValuesHook(Widget w, ArgList arglist, Cardinal *num_args) 6547a84e134Smrg{ 6557a84e134Smrg Cardinal i; 6567a84e134Smrg Dimension width, height; 657421c997bSmrg 6587a84e134Smrg width = XtWidth(w); 6597a84e134Smrg height = XtHeight(w); 660421c997bSmrg 6617a84e134Smrg for (i = 0 ; i < *num_args ; i++) { 6627a84e134Smrg if (streq(arglist[i].name, XtNwidth)) 6637a84e134Smrg width = (Dimension)arglist[i].value; 6647a84e134Smrg if (streq(arglist[i].name, XtNheight)) 6657a84e134Smrg height = (Dimension) arglist[i].value; 6667a84e134Smrg } 6677a84e134Smrg 6687a84e134Smrg if (width != XtWidth(w) || height != XtHeight(w)) 6697a84e134Smrg MakeSetValuesRequest(w, width, height); 6707a84e134Smrg 6717a84e134Smrg return (False); 6727a84e134Smrg} 6737a84e134Smrg 6747a84e134Smrg/* 6757a84e134Smrg * Geometry Management routines 6767a84e134Smrg */ 6777a84e134Smrg/* 6787a84e134Smrg * Function: 6797a84e134Smrg * XawSimpleMenuGeometryManager 6807a84e134Smrg * 6817a84e134Smrg * Parameters: 6827a84e134Smrg * w - Menu Entry making the request 6837a84e134Smrg * request - requested new geometry 6847a84e134Smrg * reply - the allowed geometry. 6857a84e134Smrg * 6867a84e134Smrg * Description: 6877a84e134Smrg * This is the SimpleMenu Widget's Geometry Manager. 6887a84e134Smrg * 6897a84e134Smrg * Returns: 6907a84e134Smrg * XtGeometry{Yes, No, Almost} 6917a84e134Smrg */ 6927a84e134Smrgstatic XtGeometryResult 6937a84e134SmrgXawSimpleMenuGeometryManager(Widget w, XtWidgetGeometry *request, 6947a84e134Smrg XtWidgetGeometry *reply) 6957a84e134Smrg{ 6967a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)XtParent(w); 6977a84e134Smrg SmeObject entry = (SmeObject)w; 6987a84e134Smrg XtGeometryMask mode = request->request_mode; 6997a84e134Smrg XtGeometryResult answer; 7007a84e134Smrg Dimension old_height, old_width; 7017a84e134Smrg 7027a84e134Smrg if (!(mode & CWWidth) && !(mode & CWHeight)) 7037a84e134Smrg return (XtGeometryNo); 7047a84e134Smrg 7057a84e134Smrg reply->width = request->width; 7067a84e134Smrg reply->height = request->height; 7077a84e134Smrg 7087a84e134Smrg old_width = XtWidth(entry); 7097a84e134Smrg old_height = XtHeight(entry); 7107a84e134Smrg 7117a84e134Smrg Layout(w, &reply->width, &reply->height); 7127a84e134Smrg 7137a84e134Smrg /* 7147a84e134Smrg * Since we are an override shell and have no parent there is no one to 7157a84e134Smrg * ask to see if this geom change is okay, so I am just going to assume 7167a84e134Smrg * we can do whatever we want. If you subclass be very careful with this 7177a84e134Smrg * assumption, it could bite you. 7187a84e134Smrg * 7197a84e134Smrg * Chris D. Peterson - Sept. 1989. 7207a84e134Smrg */ 7217a84e134Smrg if ((!(mode & CWWidth) || reply->width == request->width) 7227a84e134Smrg && (!(mode & CWHeight) || reply->height == request->height)) { 7237a84e134Smrg if (mode & XtCWQueryOnly) { /* Actually perform the layout */ 7247a84e134Smrg XtWidth(entry) = old_width; 7257a84e134Smrg XtHeight(entry) = old_height; 7267a84e134Smrg } 7277a84e134Smrg else 7287a84e134Smrg Layout((Widget)smw, NULL, NULL); 7297a84e134Smrg answer = XtGeometryDone; 7307a84e134Smrg } 7317a84e134Smrg else { 7327a84e134Smrg XtWidth(entry) = old_width; 7337a84e134Smrg XtHeight(entry) = old_height; 7347a84e134Smrg 7357a84e134Smrg if ((reply->width == request->width && !(mode & CWHeight)) 7367a84e134Smrg || (reply->height == request->height && !(mode & CWWidth)) 7377a84e134Smrg || (reply->width == request->width 7387a84e134Smrg && reply->height == request->height)) 7397a84e134Smrg answer = XtGeometryNo; 7407a84e134Smrg else { 7417a84e134Smrg answer = XtGeometryAlmost; 7427a84e134Smrg reply->request_mode = 0; 7437a84e134Smrg if (reply->width != request->width) 7447a84e134Smrg reply->request_mode |= CWWidth; 7457a84e134Smrg if (reply->height != request->height) 7467a84e134Smrg reply->request_mode |= CWHeight; 7477a84e134Smrg } 7487a84e134Smrg } 7497a84e134Smrg 7507a84e134Smrg return (answer); 7517a84e134Smrg} 7527a84e134Smrg 7537a84e134Smrg/* 7547a84e134Smrg * Function: 7557a84e134Smrg * XawSimpleMenuChangeManaged 7567a84e134Smrg * 7577a84e134Smrg * Parameters: 7587a84e134Smrg * w - simple menu widget 7597a84e134Smrg * 7607a84e134Smrg * Description: 7617a84e134Smrg * Called whenever a new child is managed. 7627a84e134Smrg */ 7637a84e134Smrgstatic void 7647a84e134SmrgXawSimpleMenuChangeManaged(Widget w) 7657a84e134Smrg{ 7667a84e134Smrg Layout(w, NULL, NULL); 7677a84e134Smrg} 7687a84e134Smrg 7697a84e134Smrg/* 7707a84e134Smrg * Global Action Routines 771421c997bSmrg * 7727a84e134Smrg * These actions routines will be added to the application's 7737a84e134Smrg * global action list 7747a84e134Smrg */ 7757a84e134Smrg/* 7767a84e134Smrg * Function: 7777a84e134Smrg * PositionMenuAction 778421c997bSmrg * 7797a84e134Smrg * Parameters: 7807a84e134Smrg * w - a widget (no the simple menu widget) 7817a84e134Smrg * event - the event that caused this action 7827a84e134Smrg * params - parameters passed to the routine. 7837a84e134Smrg * we expect the name of the menu here. 7847a84e134Smrg * num_params - "" 7857a84e134Smrg * 7867a84e134Smrg * Description: 7877a84e134Smrg * Positions the simple menu widget. 7887a84e134Smrg */ 7897a84e134Smrg/*ARGSUSED*/ 7907a84e134Smrgstatic void 7917a84e134SmrgPositionMenuAction(Widget w, XEvent *event, 7927a84e134Smrg String *params, Cardinal *num_params) 793421c997bSmrg{ 7947a84e134Smrg Widget menu; 7957a84e134Smrg XPoint loc; 7967a84e134Smrg 7977a84e134Smrg if (*num_params != 1) { 7987a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 7997a84e134Smrg "SimpleMenuWidget: position menu action expects " 8007a84e134Smrg "only one parameter which is the name of the menu."); 8017a84e134Smrg return; 8027a84e134Smrg } 8037a84e134Smrg 8047a84e134Smrg if ((menu = FindMenu(w, params[0])) == NULL) { 8057a84e134Smrg char error_buf[BUFSIZ]; 8067a84e134Smrg 807421c997bSmrg snprintf(error_buf, sizeof(error_buf), 808421c997bSmrg "SimpleMenuWidget: could not find menu named %s.", 809421c997bSmrg params[0]); 8107a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), error_buf); 8117a84e134Smrg return; 8127a84e134Smrg } 813421c997bSmrg 8147a84e134Smrg switch (event->type) { 8157a84e134Smrg case ButtonPress: 8167a84e134Smrg case ButtonRelease: 8175ec34c4cSmrg loc.x = (short)event->xbutton.x_root; 8185ec34c4cSmrg loc.y = (short)event->xbutton.y_root; 8197a84e134Smrg PositionMenu(menu, &loc); 8207a84e134Smrg break; 8217a84e134Smrg case EnterNotify: 8227a84e134Smrg case LeaveNotify: 8235ec34c4cSmrg loc.x = (short)event->xcrossing.x_root; 8245ec34c4cSmrg loc.y = (short)event->xcrossing.y_root; 8257a84e134Smrg PositionMenu(menu, &loc); 8267a84e134Smrg break; 8277a84e134Smrg case MotionNotify: 8285ec34c4cSmrg loc.x = (short)event->xmotion.x_root; 8295ec34c4cSmrg loc.y = (short)event->xmotion.y_root; 8307a84e134Smrg PositionMenu(menu, &loc); 8317a84e134Smrg break; 8327a84e134Smrg default: 8337a84e134Smrg PositionMenu(menu, NULL); 8347a84e134Smrg break; 8357a84e134Smrg } 836421c997bSmrg} 8377a84e134Smrg 8387a84e134Smrg/* 8397a84e134Smrg * Widget Action Routines 8407a84e134Smrg */ 8417a84e134Smrg/* 8427a84e134Smrg * Function: 8437a84e134Smrg * Unhighlight 8447a84e134Smrg * 8457a84e134Smrg * Parameters: 8467a84e134Smrg * w - simple menu widget 8477a84e134Smrg * event - event that caused this action 8487a84e134Smrg * params - not used 8497a84e134Smrg * num_params - "" 850421c997bSmrg * 8517a84e134Smrg * Description: 8527a84e134Smrg * Unhighlights current entry. 8537a84e134Smrg */ 8547a84e134Smrg/*ARGSUSED*/ 8557a84e134Smrgstatic void 8565ec34c4cSmrgUnhighlight(Widget w, XEvent *event _X_UNUSED, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 857421c997bSmrg{ 8587a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8597a84e134Smrg SmeObject entry = smw->simple_menu.entry_set; 860421c997bSmrg 8617a84e134Smrg if (entry == NULL) 8627a84e134Smrg return; 8637a84e134Smrg 8647a84e134Smrg#ifndef OLDXAW 8657a84e134Smrg if (!smw->simple_menu.sub_menu) 8667a84e134Smrg#endif 8677a84e134Smrg { 8687a84e134Smrg SmeObjectClass cclass; 8697a84e134Smrg 8707a84e134Smrg smw->simple_menu.entry_set = NULL; 8717a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 8727a84e134Smrg (cclass->sme_class.unhighlight)((Widget)entry); 8737a84e134Smrg } 8747a84e134Smrg} 8757a84e134Smrg 8767a84e134Smrg/* 8777a84e134Smrg * Function: 8787a84e134Smrg * Highlight 8797a84e134Smrg * 8807a84e134Smrg * Parameters: 8817a84e134Smrg * w - simple menu widget 8827a84e134Smrg * event - event that caused this action 8837a84e134Smrg * params - not used 8847a84e134Smrg * num_params - "" 8857a84e134Smrg * 8867a84e134Smrg * Description: 8877a84e134Smrg * Highlights current entry. 8887a84e134Smrg */ 8897a84e134Smrg/*ARGSUSED*/ 8907a84e134Smrgstatic void 8917a84e134SmrgHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) 8927a84e134Smrg{ 8937a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8947a84e134Smrg SmeObject entry; 8957a84e134Smrg 8967a84e134Smrg if (!XtIsSensitive(w)) 8977a84e134Smrg return; 8987a84e134Smrg 8997a84e134Smrg entry = GetEventEntry(w, event); 9007a84e134Smrg 9017a84e134Smrg if (entry == smw->simple_menu.entry_set) 9027a84e134Smrg return; 9037a84e134Smrg 9047a84e134Smrg#ifndef OLDXAW 9057a84e134Smrg if (!smw->simple_menu.sub_menu) 9067a84e134Smrg#endif 9077a84e134Smrg Unhighlight(w, event, params, num_params); 9087a84e134Smrg 9097a84e134Smrg if (entry == NULL) 9107a84e134Smrg return; 9117a84e134Smrg 9127a84e134Smrg if (!XtIsSensitive((Widget)entry)) 9137a84e134Smrg return; 9147a84e134Smrg 9157a84e134Smrg#ifndef OLDXAW 9167a84e134Smrg if (smw->simple_menu.sub_menu) 9177a84e134Smrg PopdownSubMenu(smw); 9187a84e134Smrg#endif 9197a84e134Smrg 9207a84e134Smrg Unhighlight(w, event, params, num_params); 9217a84e134Smrg 9227a84e134Smrg#ifndef OLDXAW 9237a84e134Smrg if (!(smw->simple_menu.state & SMW_UNMAPPING)) 9247a84e134Smrg#endif 9257a84e134Smrg { 9267a84e134Smrg SmeObjectClass cclass; 9277a84e134Smrg 9287a84e134Smrg smw->simple_menu.entry_set = entry; 9297a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 9307a84e134Smrg 9317a84e134Smrg (cclass->sme_class.highlight)((Widget)entry); 9327a84e134Smrg 9337a84e134Smrg#ifndef OLDXAW 9347a84e134Smrg if (XtIsSubclass((Widget)entry, smeBSBObjectClass)) 9357a84e134Smrg PopupSubMenu(smw); 9367a84e134Smrg#endif 9377a84e134Smrg } 9387a84e134Smrg} 9397a84e134Smrg 9407a84e134Smrg/* 9417a84e134Smrg * Function: 9427a84e134Smrg * Notify 9437a84e134Smrg * 9447a84e134Smrg * Parameters: 9457a84e134Smrg * w - simple menu widget 9467a84e134Smrg * event - event that caused this action 9477a84e134Smrg * params - not used 9487a84e134Smrg * num_params - "" 9497a84e134Smrg * 9507a84e134Smrg * Description: 9517a84e134Smrg * Notify user of current entry. 9527a84e134Smrg */ 9537a84e134Smrg/*ARGSUSED*/ 9547a84e134Smrgstatic void 9555ec34c4cSmrgNotify(Widget w, XEvent *event, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 9567a84e134Smrg{ 9577a84e134Smrg SmeObject entry; 9587a84e134Smrg SmeObjectClass cclass; 9597a84e134Smrg 9607a84e134Smrg /* may be a propagated event from a sub menu, need to check it */ 9617a84e134Smrg if (XtWindow(w) != event->xany.window) 9627a84e134Smrg return; 9637a84e134Smrg entry = GetEventEntry(w, event); 9647a84e134Smrg if (entry == NULL || !XtIsSensitive((Widget)entry)) 9657a84e134Smrg return; 9667a84e134Smrg 9677a84e134Smrg cclass = (SmeObjectClass) entry->object.widget_class; 9687a84e134Smrg (cclass->sme_class.notify)((Widget)entry); 9697a84e134Smrg} 9707a84e134Smrg 9717a84e134Smrg/* 9727a84e134Smrg * Public Functions 9737a84e134Smrg */ 9747a84e134Smrg/* 9757a84e134Smrg * Function: 9767a84e134Smrg * XawSimpleMenuAddGlobalActions 9777a84e134Smrg * 9787a84e134Smrg * Arguments: 9797a84e134Smrg * app_con - appcontext 9807a84e134Smrg * 9817a84e134Smrg * Description: 9827a84e134Smrg * Adds the global actions to the simple menu widget. 9837a84e134Smrg */ 9847a84e134Smrgvoid 9857a84e134SmrgXawSimpleMenuAddGlobalActions(XtAppContext app_con) 9867a84e134Smrg{ 9877a84e134Smrg XtInitializeWidgetClass(simpleMenuWidgetClass); 9887a84e134Smrg XmuCallInitializers(app_con); 989421c997bSmrg} 9907a84e134Smrg 9917a84e134Smrg/* 9927a84e134Smrg * Function: 9937a84e134Smrg * XawSimpleMenuGetActiveEntry 9947a84e134Smrg * 9957a84e134Smrg * Parameters: 9967a84e134Smrg * w - smw widget 9977a84e134Smrg * 9987a84e134Smrg * Description: 9997a84e134Smrg * Gets the currently active (set) entry. 10007a84e134Smrg * 10017a84e134Smrg * Returns: 10027a84e134Smrg * The currently set entry or NULL if none is set 10037a84e134Smrg */ 10047a84e134SmrgWidget 10057a84e134SmrgXawSimpleMenuGetActiveEntry(Widget w) 10067a84e134Smrg{ 10077a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10087a84e134Smrg 10097a84e134Smrg return ((Widget)smw->simple_menu.entry_set); 1010421c997bSmrg} 10117a84e134Smrg 10127a84e134Smrg/* 10137a84e134Smrg * Function: 10147a84e134Smrg * XawSimpleMenuClearActiveEntry 10157a84e134Smrg * 10167a84e134Smrg * Parameters: 10177a84e134Smrg * w - smw widget 10187a84e134Smrg * 10197a84e134Smrg * Description: 10207a84e134Smrg * Unsets the currently active (set) entry. 10217a84e134Smrg */ 10227a84e134Smrgvoid 10237a84e134SmrgXawSimpleMenuClearActiveEntry(Widget w) 10247a84e134Smrg{ 10257a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10267a84e134Smrg 10277a84e134Smrg smw->simple_menu.entry_set = NULL; 1028421c997bSmrg} 10297a84e134Smrg 10307a84e134Smrg/* 10317a84e134Smrg * Private Functions 10327a84e134Smrg */ 10337a84e134Smrg/* 10347a84e134Smrg * Function: 10357a84e134Smrg * CreateLabel 10367a84e134Smrg * 10377a84e134Smrg * Parameters: 10387a84e134Smrg * w - smw widget 1039421c997bSmrg * 10407a84e134Smrg * Description: 10417a84e134Smrg * Creates the label object and makes sure it is the first child in 10427a84e134Smrg * in the list. 10437a84e134Smrg */ 10447a84e134Smrgstatic void 10457a84e134SmrgCreateLabel(Widget w) 10467a84e134Smrg{ 10477a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10487a84e134Smrg Widget *child, *next_child; 10497a84e134Smrg int i; 10507a84e134Smrg Arg args[2]; 10517a84e134Smrg 10527a84e134Smrg if (smw->simple_menu.label_string == NULL || 10537a84e134Smrg smw->simple_menu.label != NULL) { 10547a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 10557a84e134Smrg "Xaw Simple Menu Widget: label string is NULL or " 10567a84e134Smrg "label already exists, no label is being created."); 10577a84e134Smrg return; 10587a84e134Smrg } 10597a84e134Smrg 10607a84e134Smrg XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string); 10617a84e134Smrg XtSetArg(args[1], XtNjustify, XtJustifyCenter); 1062421c997bSmrg smw->simple_menu.label = (SmeObject) 1063421c997bSmrg XtCreateManagedWidget("menuLabel", 10647a84e134Smrg smw->simple_menu.label_class, w, args, TWO); 10657a84e134Smrg 10667a84e134Smrg next_child = NULL; 10677a84e134Smrg for (child = smw->composite.children + smw->composite.num_children, 10685ec34c4cSmrg i = (int)smw->composite.num_children; i > 0; i--, child--) { 10697a84e134Smrg if (next_child != NULL) 10707a84e134Smrg *next_child = *child; 10717a84e134Smrg next_child = child; 10727a84e134Smrg } 10737a84e134Smrg *child = (Widget)smw->simple_menu.label; 10747a84e134Smrg} 10757a84e134Smrg 10767a84e134Smrg/* 10777a84e134Smrg * Function: 10787a84e134Smrg * Layout 10797a84e134Smrg * 10807a84e134Smrg * Arguments: 10817a84e134Smrg * w - See below 10827a84e134Smrg * width_ret - returned width 10837a84e134Smrg * height_ret - returned height 10847a84e134Smrg * 10857a84e134Smrg * Note: 10867a84e134Smrg * if width == NULL || height == NULL then it assumes the you do not care 10877a84e134Smrg * about the return values, and just want a relayout. 10887a84e134Smrg * 10897a84e134Smrg * if this is not the case then it will set width_ret and height_ret 10905b16253fSmrg * to be width and height that the child would get if it were laid out 10917a84e134Smrg * at this time. 10927a84e134Smrg * 10937a84e134Smrg * "w" can be the simple menu widget or any of its object children. 10947a84e134Smrg */ 10957a84e134Smrgstatic void 10967a84e134SmrgLayout(Widget w, Dimension *width_ret, Dimension *height_ret) 10977a84e134Smrg{ 10987a84e134Smrg SmeObject current_entry; 10997a84e134Smrg SimpleMenuWidget smw; 11007a84e134Smrg Dimension width, height; 11017a84e134Smrg Boolean allow_change_size; 11027a84e134Smrg Widget kid; 11037a84e134Smrg Cardinal i, count, n; 11047a84e134Smrg int width_kid, height_kid, tmp_w, tmp_h; 11057a84e134Smrg short vadd, hadd, x_ins, y_ins; 11067a84e134Smrg Dimension *widths; 11077a84e134Smrg 11087a84e134Smrg height = 0; 11097a84e134Smrg 11107a84e134Smrg if (XtIsSubclass(w, simpleMenuWidgetClass)) { 11117a84e134Smrg smw = (SimpleMenuWidget)w; 11127a84e134Smrg current_entry = NULL; 11137a84e134Smrg } 11147a84e134Smrg else { 11157a84e134Smrg smw = (SimpleMenuWidget)XtParent(w); 11167a84e134Smrg current_entry = (SmeObject)w; 11177a84e134Smrg } 11187a84e134Smrg 11197a84e134Smrg allow_change_size = (!XtIsRealized((Widget)smw) 11207a84e134Smrg || smw->shell.allow_shell_resize); 11217a84e134Smrg 11227a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11237a84e134Smrg i < smw->composite.num_children; 11247a84e134Smrg i++) { 11257a84e134Smrg XtWidgetGeometry preferred; 11267a84e134Smrg 11277a84e134Smrg kid = smw->composite.children[i]; 11287a84e134Smrg if (!XtIsManaged(kid)) 11297a84e134Smrg continue; 11307a84e134Smrg if (smw->simple_menu.row_height != 0) 11317a84e134Smrg XtHeight(kid) = smw->simple_menu.row_height; 11327a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11337a84e134Smrg if (preferred.request_mode & CWWidth) 11347a84e134Smrg XtWidth(kid) = preferred.width; 11357a84e134Smrg } 11367a84e134Smrg 11377a84e134Smrg if (smw->simple_menu.label 11387a84e134Smrg && XtIsManaged((Widget)smw->simple_menu.label)) { 11397a84e134Smrg XtWidgetGeometry preferred; 11407a84e134Smrg 11417a84e134Smrg kid = (Widget)smw->simple_menu.label; 11427a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11437a84e134Smrg if (preferred.request_mode & CWWidth) 11447a84e134Smrg XtWidth(kid) = preferred.width; 11457a84e134Smrg if (preferred.request_mode & CWHeight) 11467a84e134Smrg XtHeight(kid) = preferred.height; 11477a84e134Smrg } 11487a84e134Smrg 11497a84e134Smrg /* reset */ 11507a84e134Smrg if (!smw->simple_menu.menu_width) 11517a84e134Smrg XtWidth(smw) = 0; 11527a84e134Smrg if (!smw->simple_menu.menu_height) 11537a84e134Smrg XtHeight(smw) = 0; 11547a84e134Smrg if (!XtWidth(smw) || !XtHeight(smw)) 11557a84e134Smrg MakeResizeRequest((Widget)smw); 11567a84e134Smrg 11577a84e134Smrg widths = (Dimension *)XtMalloc(sizeof(Dimension)); 11587a84e134Smrg#ifndef OLDXAW 11595ec34c4cSmrg hadd = (short)smw->simple_menu.left_margin; 11607a84e134Smrg#else 11617a84e134Smrg hadd = 0; 11627a84e134Smrg#endif 11635ec34c4cSmrg vadd = (short)smw->simple_menu.top_margin; 11647a84e134Smrg if (smw->simple_menu.label) 11655ec34c4cSmrg vadd = (short)(vadd + XtHeight(smw->simple_menu.label)); 11667a84e134Smrg 11677a84e134Smrg count = 1; 11685ec34c4cSmrg width = (Dimension)(tmp_w = tmp_h = (int)(n = 0)); 11695ec34c4cSmrg height = (Dimension)vadd; 11707a84e134Smrg 11717a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11727a84e134Smrg i < smw->composite.num_children; 11737a84e134Smrg i++) { 11747a84e134Smrg kid = smw->composite.children[i]; 11757a84e134Smrg if (!XtIsManaged(kid)) 11767a84e134Smrg continue; 11777a84e134Smrg width_kid = XtWidth(kid); 11787a84e134Smrg height_kid = XtHeight(kid); 11797a84e134Smrg 11807a84e134Smrg if (n && (height + height_kid + smw->simple_menu.bottom_margin 11817a84e134Smrg > XtHeight(smw))) { 11827a84e134Smrg ++count; 11837a84e134Smrg widths = (Dimension *)XtRealloc((char *)widths, 11845ec34c4cSmrg (Cardinal)(sizeof(Dimension) * count)); 11855ec34c4cSmrg widths[count - 1] = (Dimension)width_kid; 11865ec34c4cSmrg width = (Dimension)(width + tmp_w); 11877a84e134Smrg tmp_w = width_kid; 11885ec34c4cSmrg height = (Dimension)(height_kid + vadd); 11897a84e134Smrg } 11907a84e134Smrg else 11915ec34c4cSmrg height = (Dimension)(height + height_kid); 11927a84e134Smrg if (height > tmp_h) 11937a84e134Smrg tmp_h = height; 11947a84e134Smrg if (width_kid > tmp_w) 11955ec34c4cSmrg widths[count - 1] = (Dimension)(tmp_w = width_kid); 11967a84e134Smrg ++n; 11977a84e134Smrg } 11987a84e134Smrg 11995ec34c4cSmrg height = (tmp_h + smw->simple_menu.bottom_margin); 12005ec34c4cSmrg width = (Dimension)(width + tmp_w); 12017a84e134Smrg 12027a84e134Smrg if (smw->simple_menu.label && width < XtWidth(smw->simple_menu.label)) { 12037a84e134Smrg float inc; 12047a84e134Smrg 12055ec34c4cSmrg inc = (float)(XtWidth(smw->simple_menu.label) - width) / (float)count; 12067a84e134Smrg width = XtWidth(smw->simple_menu.label); 12077a84e134Smrg for (n = 0; n < count; n++) 12085ec34c4cSmrg widths[n] = (Dimension)(widths[n] + inc); 12097a84e134Smrg } 12107a84e134Smrg 12117a84e134Smrg#ifndef OLDXAW 12125ec34c4cSmrg width = (Dimension)(width + (hadd + smw->simple_menu.right_margin)); 12137a84e134Smrg#endif 12147a84e134Smrg 12155ec34c4cSmrg x_ins = (short)(n = count = 0); 12167a84e134Smrg tmp_w = widths[0]; 12177a84e134Smrg tmp_h = vadd; 12187a84e134Smrg 12197a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 12207a84e134Smrg i < smw->composite.num_children; 12217a84e134Smrg i++) { 12227a84e134Smrg kid = smw->composite.children[i]; 12237a84e134Smrg if (!XtIsManaged(kid)) 12247a84e134Smrg continue; 12257a84e134Smrg 12267a84e134Smrg height_kid = XtHeight(kid); 12277a84e134Smrg 12287a84e134Smrg if (n && (tmp_h + height_kid + smw->simple_menu.bottom_margin 12297a84e134Smrg > XtHeight(smw))) { 12305ec34c4cSmrg x_ins = (short)tmp_w; 12317a84e134Smrg y_ins = vadd; 12327a84e134Smrg ++count; 12337a84e134Smrg tmp_w += widths[count]; 12347a84e134Smrg tmp_h = height_kid + vadd; 12357a84e134Smrg } 12367a84e134Smrg else { 12375ec34c4cSmrg y_ins = (short)tmp_h; 12387a84e134Smrg tmp_h += height_kid; 12397a84e134Smrg } 12407a84e134Smrg ++n; 12417a84e134Smrg 12425ec34c4cSmrg XtX(kid) = (Position)(x_ins + hadd); 12437a84e134Smrg XtY(kid) = y_ins; 12447a84e134Smrg XtWidth(kid) = widths[count]; 12457a84e134Smrg } 12467a84e134Smrg 12477a84e134Smrg XtFree((char *)widths); 12487a84e134Smrg 12497a84e134Smrg if (allow_change_size) 12507a84e134Smrg MakeSetValuesRequest((Widget) smw, width, height); 12517a84e134Smrg 12527a84e134Smrg if (smw->simple_menu.label) { 12537a84e134Smrg XtX(smw->simple_menu.label) = 0; 12545ec34c4cSmrg XtY(smw->simple_menu.label) = (Position)smw->simple_menu.top_margin; 12555ec34c4cSmrg XtWidth(smw->simple_menu.label) = (Dimension)(XtWidth(smw) 12567a84e134Smrg#ifndef OLDXAW 12577a84e134Smrg - (smw->simple_menu.left_margin + smw->simple_menu.right_margin) 12587a84e134Smrg#endif 12595ec34c4cSmrg ); 12607a84e134Smrg } 12617a84e134Smrg if (current_entry) { 12627a84e134Smrg if (width_ret) 12637a84e134Smrg *width_ret = XtWidth(current_entry); 12647a84e134Smrg if (height_ret) 12657a84e134Smrg *height_ret = XtHeight(current_entry); 12667a84e134Smrg } 12677a84e134Smrg} 1268421c997bSmrg 12697a84e134Smrg/* 12707a84e134Smrg * Function: 12717a84e134Smrg * AddPositionAction 12727a84e134Smrg * 12737a84e134Smrg * Parameters: 12747a84e134Smrg * app_con - application context 12757a84e134Smrg * data - (not used) 12767a84e134Smrg * 12777a84e134Smrg * Description: 12787a84e134Smrg * Adds the XawPositionSimpleMenu action to the global 12797a84e134Smrg * action list for this appcon. 12807a84e134Smrg */ 12817a84e134Smrg/*ARGSUSED*/ 12827a84e134Smrgstatic void 12835ec34c4cSmrgAddPositionAction(XtAppContext app_con, XPointer data _X_UNUSED) 12847a84e134Smrg{ 12857a84e134Smrg static XtActionsRec pos_action[] = { 12867a84e134Smrg {"XawPositionSimpleMenu", PositionMenuAction}, 12877a84e134Smrg }; 12887a84e134Smrg 12897a84e134Smrg XtAppAddActions(app_con, pos_action, XtNumber(pos_action)); 12907a84e134Smrg} 12917a84e134Smrg 12927a84e134Smrg/* 12937a84e134Smrg * Function: 12947a84e134Smrg * FindMenu 12957a84e134Smrg * 12967a84e134Smrg * Parameters: 12977a84e134Smrg * widget - reference widget 12987a84e134Smrg * name - menu widget's name 12997a84e134Smrg * 13007a84e134Smrg * Description: 13017a84e134Smrg * Find the menu give a name and reference widget 13027a84e134Smrg * 13037a84e134Smrg * Returns: 13047a84e134Smrg * The menu widget or NULL. 13057a84e134Smrg */ 1306421c997bSmrgstatic Widget 13077a84e134SmrgFindMenu(Widget widget, String name) 13087a84e134Smrg{ 13097a84e134Smrg Widget w, menu; 1310421c997bSmrg 13117a84e134Smrg for (w = widget; w != NULL; w = XtParent(w)) 13127a84e134Smrg if ((menu = XtNameToWidget(w, name)) != NULL) 13137a84e134Smrg return (menu); 13147a84e134Smrg 13157a84e134Smrg return (NULL); 13167a84e134Smrg} 13177a84e134Smrg 13187a84e134Smrg/* 13197a84e134Smrg * Function: 13207a84e134Smrg * PositionMenu 13217a84e134Smrg * 13227a84e134Smrg * Parameters: 13237a84e134Smrg * w - simple menu widget 13247a84e134Smrg * location - pointer the the position or NULL 13257a84e134Smrg * 13267a84e134Smrg * Description: 13277a84e134Smrg * Places the menu 13287a84e134Smrg */ 13297a84e134Smrgstatic void 13307a84e134SmrgPositionMenu(Widget w, XPoint *location) 13317a84e134Smrg{ 13327a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 13337a84e134Smrg SmeObject entry; 13347a84e134Smrg XPoint t_point; 1335421c997bSmrg 13367a84e134Smrg if (location == NULL) { 13377a84e134Smrg Window temp1, temp2; 13387a84e134Smrg int root_x, root_y, tempX, tempY; 13397a84e134Smrg unsigned int tempM; 1340421c997bSmrg 13417a84e134Smrg location = &t_point; 13427a84e134Smrg if (XQueryPointer(XtDisplay(w), XtWindow(w), &temp1, &temp2, 13437a84e134Smrg &root_x, &root_y, &tempX, &tempY, &tempM) == False) { 13447a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 13457a84e134Smrg "Xaw Simple Menu Widget: " 13467a84e134Smrg "Could not find location of mouse pointer"); 13477a84e134Smrg return; 13487a84e134Smrg } 13497a84e134Smrg location->x = (short) root_x; 13507a84e134Smrg location->y = (short) root_y; 13517a84e134Smrg } 1352421c997bSmrg 13537a84e134Smrg /* 13547a84e134Smrg * The width will not be correct unless it is realized 13557a84e134Smrg */ 13567a84e134Smrg XtRealizeWidget(w); 1357421c997bSmrg 13585ec34c4cSmrg location->x = (short)(location->x - (XtWidth(w) >> 1)); 1359421c997bSmrg 13607a84e134Smrg if (smw->simple_menu.popup_entry == NULL) 13617a84e134Smrg entry = smw->simple_menu.label; 13627a84e134Smrg else 13637a84e134Smrg entry = smw->simple_menu.popup_entry; 13647a84e134Smrg 13657a84e134Smrg if (entry != NULL) 13665ec34c4cSmrg location->y = (short)(location->y - (XtY(entry) + (XtHeight(entry) >> 1))); 13677a84e134Smrg 13687a84e134Smrg MoveMenu(w, location->x, location->y); 13697a84e134Smrg} 13707a84e134Smrg 13717a84e134Smrg/* 13727a84e134Smrg * Function: 13737a84e134Smrg * MoveMenu 13747a84e134Smrg * 13757a84e134Smrg * Parameters: 13767a84e134Smrg * w - simple menu widget 13777a84e134Smrg * x - current location of the widget 13787a84e134Smrg * y - "" 13797a84e134Smrg * 13807a84e134Smrg * Description: 13817a84e134Smrg * Actually moves the menu, may force it to 13825b16253fSmrg * to be fully visible if menu_on_screen is True. 13837a84e134Smrg */ 13847a84e134Smrgstatic void 13857a84e134SmrgMoveMenu(Widget w, int x, int y) 13867a84e134Smrg{ 13877a84e134Smrg Arg arglist[2]; 13887a84e134Smrg Cardinal num_args = 0; 13897a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 1390421c997bSmrg 13917a84e134Smrg if (smw->simple_menu.menu_on_screen) { 13927a84e134Smrg int width = XtWidth(w) + (XtBorderWidth(w) << 1); 13937a84e134Smrg int height = XtHeight(w) + (XtBorderWidth(w) << 1); 1394421c997bSmrg 13957a84e134Smrg if (x >= 0) { 13967a84e134Smrg int scr_width = WidthOfScreen(XtScreen(w)); 13977a84e134Smrg 13987a84e134Smrg if (x + width > scr_width) 13997a84e134Smrg x = scr_width - width; 14007a84e134Smrg } 1401421c997bSmrg if (x < 0) 14027a84e134Smrg x = 0; 1403421c997bSmrg 14047a84e134Smrg if (y >= 0) { 14057a84e134Smrg int scr_height = HeightOfScreen(XtScreen(w)); 14067a84e134Smrg 14077a84e134Smrg if (y + height > scr_height) 14087a84e134Smrg y = scr_height - height; 14097a84e134Smrg } 14107a84e134Smrg if (y < 0) 14117a84e134Smrg y = 0; 14127a84e134Smrg } 1413421c997bSmrg 14147a84e134Smrg XtSetArg(arglist[num_args], XtNx, x); num_args++; 14157a84e134Smrg XtSetArg(arglist[num_args], XtNy, y); num_args++; 14167a84e134Smrg XtSetValues(w, arglist, num_args); 14177a84e134Smrg} 14187a84e134Smrg 14197a84e134Smrg/* 14207a84e134Smrg * Function: 14217a84e134Smrg * ChangeCursorOnGrab 14227a84e134Smrg * 14237a84e134Smrg * Parameters: 14247a84e134Smrg * w - menu widget 14257a84e134Smrg * temp1 - not used 14267a84e134Smrg * temp2 - "" 14277a84e134Smrg * 14287a84e134Smrg * Description: 14297a84e134Smrg * Changes the cursor on the active grab to the one 14307a84e134Smrg * specified in out resource list. 14317a84e134Smrg */ 14327a84e134Smrg/*ARGSUSED*/ 14337a84e134Smrgstatic void 14345ec34c4cSmrgChangeCursorOnGrab(Widget w, XtPointer temp1 _X_UNUSED, XtPointer temp2 _X_UNUSED) 14357a84e134Smrg{ 14367a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 1437421c997bSmrg 14387a84e134Smrg /* 14397a84e134Smrg * The event mask here is what is currently in the MIT implementation. 14407a84e134Smrg * There really needs to be a way to get the value of the mask out 14417a84e134Smrg * of the toolkit (CDP 5/26/89). 14427a84e134Smrg */ 14437a84e134Smrg XChangeActivePointerGrab(XtDisplay(w), ButtonPressMask | ButtonReleaseMask, 1444421c997bSmrg smw->simple_menu.cursor, 14457a84e134Smrg XtLastTimestampProcessed(XtDisplay(w))); 14467a84e134Smrg} 14477a84e134Smrg 14487a84e134Smrg/* 14497a84e134Smrg * Function: 14507a84e134Smrg * MakeSetValuesRequest 14517a84e134Smrg * 14527a84e134Smrg * Parameters: 14537a84e134Smrg * w - simple menu widget 14547a84e134Smrg * width - size requested 14557a84e134Smrg * height - "" 14567a84e134Smrg */ 14577a84e134Smrgstatic void 14587a84e134SmrgMakeSetValuesRequest(Widget w, unsigned int width, unsigned int height) 14597a84e134Smrg{ 14607a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 14617a84e134Smrg Arg arglist[2]; 14627a84e134Smrg Cardinal num_args = 0; 1463421c997bSmrg 14647a84e134Smrg if (!smw->simple_menu.recursive_set_values) { 14657a84e134Smrg if (XtWidth(smw) != width || XtHeight(smw) != height) { 14667a84e134Smrg smw->simple_menu.recursive_set_values = True; 14677a84e134Smrg XtSetArg(arglist[num_args], XtNwidth, width); num_args++; 14687a84e134Smrg XtSetArg(arglist[num_args], XtNheight, height); num_args++; 14697a84e134Smrg XtSetValues(w, arglist, num_args); 14707a84e134Smrg } 14717a84e134Smrg else if (XtIsRealized((Widget)smw)) 14727a84e134Smrg XawSimpleMenuRedisplay((Widget)smw, NULL, NULL); 14737a84e134Smrg } 14747a84e134Smrg smw->simple_menu.recursive_set_values = False; 14757a84e134Smrg} 14767a84e134Smrg 14777a84e134Smrgstatic SmeObject 14787a84e134SmrgDoGetEventEntry(Widget w, int x_loc, int y_loc) 14797a84e134Smrg{ 14807a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 14817a84e134Smrg SmeObject *entry; 14827a84e134Smrg 14837a84e134Smrg ForAllChildren(smw, entry) { 14847a84e134Smrg if (!XtIsManaged((Widget)*entry)) 14857a84e134Smrg continue; 14867a84e134Smrg 14877a84e134Smrg if (x_loc > XtX(*entry) 14887a84e134Smrg && x_loc <= XtX(*entry) + XtWidth(*entry) 14897a84e134Smrg && y_loc > XtY(*entry) 14907a84e134Smrg && y_loc <= XtY(*entry) + XtHeight(*entry)) { 14917a84e134Smrg if (*entry == smw->simple_menu.label) 14927a84e134Smrg return (NULL); /* cannot select the label */ 14937a84e134Smrg else 14947a84e134Smrg return (*entry); 14957a84e134Smrg } 14967a84e134Smrg } 1497421c997bSmrg 14987a84e134Smrg return (NULL); 14997a84e134Smrg} 15007a84e134Smrg 15017a84e134Smrg/* 15027a84e134Smrg * Function: 15037a84e134Smrg * GetEventEntry 15047a84e134Smrg * 15057a84e134Smrg * Parameters: 15067a84e134Smrg * w - simple menu widget 15077a84e134Smrg * event - X event 15087a84e134Smrg * 15097a84e134Smrg * Description: 15107a84e134Smrg * Gets an entry given an event that has X and Y coords. 15117a84e134Smrg * 15127a84e134Smrg * Returns: 15137a84e134Smrg * The entry that this point is in 15147a84e134Smrg */ 15157a84e134Smrgstatic SmeObject 15167a84e134SmrgGetEventEntry(Widget w, XEvent *event) 15177a84e134Smrg{ 15187a84e134Smrg int x_loc, y_loc, x_root; 15197a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 15207a84e134Smrg SmeObject entry; 15217a84e134Smrg int warp, move; 15227a84e134Smrg 15237a84e134Smrg switch (event->type) { 15247a84e134Smrg case MotionNotify: 15257a84e134Smrg x_loc = event->xmotion.x; 15267a84e134Smrg y_loc = event->xmotion.y; 15277a84e134Smrg x_root = event->xmotion.x_root; 15287a84e134Smrg break; 15297a84e134Smrg case EnterNotify: 15307a84e134Smrg case LeaveNotify: 15317a84e134Smrg x_loc = event->xcrossing.x; 15327a84e134Smrg y_loc = event->xcrossing.y; 15337a84e134Smrg x_root = event->xcrossing.x_root; 15347a84e134Smrg break; 15357a84e134Smrg case ButtonPress: 15367a84e134Smrg case ButtonRelease: 15377a84e134Smrg x_loc = event->xbutton.x; 15387a84e134Smrg y_loc = event->xbutton.y; 15397a84e134Smrg x_root = event->xbutton.x_root; 15407a84e134Smrg break; 15417a84e134Smrg default: 15427a84e134Smrg XtAppError(XtWidgetToApplicationContext(w), 15437a84e134Smrg "Unknown event type in GetEventEntry()."); 15447a84e134Smrg return (NULL); 15457a84e134Smrg } 1546421c997bSmrg 15477a84e134Smrg if (x_loc < 0 || x_loc >= XtWidth(smw) || 15487a84e134Smrg y_loc < 0 || y_loc >= XtHeight(smw)) 15497a84e134Smrg return (NULL); 15507a84e134Smrg 15517a84e134Smrg /* Move the menu if it's outside the screen, does not check 15527a84e134Smrg * smw->simple_menu.menu_on_screen because menus is bigger than screen 15537a84e134Smrg */ 15547a84e134Smrg if (x_root == WidthOfScreen(XtScreen(w)) - 1 && 15557a84e134Smrg XtX(w) + XtWidth(w) + (XtBorderWidth(w)) > x_root) { 15567a84e134Smrg warp = -8; 15577a84e134Smrg if (smw->simple_menu.entry_set) { 15587a84e134Smrg entry = DoGetEventEntry(w, 15597a84e134Smrg XtX(smw->simple_menu.entry_set) 15607a84e134Smrg + XtWidth(smw->simple_menu.entry_set) + 1, 15617a84e134Smrg y_loc); 15627a84e134Smrg Unhighlight(w, event, NULL, NULL); 15637a84e134Smrg if (entry) { 15647a84e134Smrg warp = -(int)XtWidth(entry) >> 1; 15657a84e134Smrg move = x_loc - XtWidth(entry) - XtX(entry) + XtBorderWidth(w); 15667a84e134Smrg } 15677a84e134Smrg else { 15687a84e134Smrg warp = 0; 15697a84e134Smrg move = WidthOfScreen(XtScreen(w)) - 15707a84e134Smrg (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); 15717a84e134Smrg } 15727a84e134Smrg } 15737a84e134Smrg else { 15747a84e134Smrg warp = 0; 15757a84e134Smrg move = WidthOfScreen(XtScreen(w)) - 15767a84e134Smrg (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); 15777a84e134Smrg } 15787a84e134Smrg } 15797a84e134Smrg else if (x_root == 0 && XtX(w) < 0) { 15807a84e134Smrg warp = 8; 15817a84e134Smrg if (smw->simple_menu.entry_set) { 15827a84e134Smrg entry = DoGetEventEntry(w, XtX(smw->simple_menu.entry_set) - 1, 15837a84e134Smrg y_loc); 15847a84e134Smrg Unhighlight(w, event, NULL, NULL); 15857a84e134Smrg if (entry) { 15867a84e134Smrg warp = XtWidth(entry) >> 1; 15877a84e134Smrg move = x_loc - XtX(entry); 15887a84e134Smrg } 15897a84e134Smrg else 15907a84e134Smrg move = x_loc + XtBorderWidth(w); 15917a84e134Smrg } 15927a84e134Smrg else 15937a84e134Smrg move = x_loc + XtBorderWidth(w); 15947a84e134Smrg } 15957a84e134Smrg else 15967a84e134Smrg move = warp = 0; 15977a84e134Smrg 15987a84e134Smrg if (move) 15995ec34c4cSmrg XtMoveWidget(w, (Position)(XtX(w) + move), XtY(w)); 16007a84e134Smrg if (warp) 16017a84e134Smrg XWarpPointer(XtDisplay(w), None, None, 0, 0, 0, 0, warp, 0); 16027a84e134Smrg 16037a84e134Smrg return (DoGetEventEntry(w, x_loc, y_loc)); 16047a84e134Smrg} 16057a84e134Smrg 16067a84e134Smrgstatic void 16077a84e134SmrgCalculateNewSize(Widget w, Dimension *width_return, Dimension *height_return) 16087a84e134Smrg{ 16097a84e134Smrg SimpleMenuWidget xaw = (SimpleMenuWidget)w; 16107a84e134Smrg Widget kid; 16117a84e134Smrg Cardinal i; 16127a84e134Smrg int width_kid, height_kid; 16137a84e134Smrg int width, height, tmp_w, tmp_h, max_dim; 16147a84e134Smrg short vadd, hadd; 16157a84e134Smrg int n, columns, test_h, num_children = 0; 16167a84e134Smrg Boolean try_layout = False; 16177a84e134Smrg 16187a84e134Smrg#ifndef OLDXAW 16195ec34c4cSmrg hadd = (short)(xaw->simple_menu.left_margin + xaw->simple_menu.right_margin); 16207a84e134Smrg#else 16217a84e134Smrg hadd = 0; 16227a84e134Smrg#endif 16235ec34c4cSmrg vadd = (short)(xaw->simple_menu.top_margin + xaw->simple_menu.bottom_margin); 16247a84e134Smrg if (xaw->simple_menu.label) 16255ec34c4cSmrg vadd = (short)(vadd + XtHeight(xaw->simple_menu.label)); 16267a84e134Smrg 16277a84e134Smrg if (*height_return) 16287a84e134Smrg max_dim = *height_return; 16297a84e134Smrg else if (!XtHeight(w)) { 16307a84e134Smrg max_dim = HeightOfScreen(XtScreen(w)); 16317a84e134Smrg try_layout = True; 16327a84e134Smrg } 16337a84e134Smrg else 16347a84e134Smrg max_dim = XtHeight(w); 16357a84e134Smrg max_dim -= vadd; 16367a84e134Smrg 16377a84e134Smrg width = height = tmp_w = tmp_h = n = test_h = 0; 16387a84e134Smrg columns = 1; 16397a84e134Smrg for (i = xaw->simple_menu.label ? 1 : 0; 16407a84e134Smrg i < xaw->composite.num_children; 16417a84e134Smrg i++) { 16427a84e134Smrg kid = xaw->composite.children[i]; 16437a84e134Smrg if (!XtIsManaged(kid)) 16447a84e134Smrg continue; 16457a84e134Smrg ++num_children; 16467a84e134Smrg width_kid = XtWidth(kid); 16477a84e134Smrg height_kid = XtHeight(kid); 16487a84e134Smrg 16497a84e134Smrg if (try_layout) { 16507a84e134Smrg if (!test_h) 16517a84e134Smrg test_h = height_kid; 16527a84e134Smrg else if (test_h != height_kid) 16537a84e134Smrg try_layout = False; 16547a84e134Smrg } 16557a84e134Smrg 16567a84e134Smrg if (n && (height + height_kid > max_dim)) { 16577a84e134Smrg ++columns; 16587a84e134Smrg width += tmp_w; 16597a84e134Smrg tmp_w = width_kid; 16607a84e134Smrg height = height_kid; 16617a84e134Smrg } 16627a84e134Smrg else 16637a84e134Smrg height += height_kid; 16647a84e134Smrg if (height > tmp_h) 16657a84e134Smrg tmp_h = height; 16667a84e134Smrg if (width_kid > tmp_w) 16677a84e134Smrg tmp_w = width_kid; 16687a84e134Smrg ++n; 16697a84e134Smrg } 16707a84e134Smrg 16717a84e134Smrg height = tmp_h + vadd; 16727a84e134Smrg width += tmp_w + hadd; 16737a84e134Smrg 16747a84e134Smrg if (xaw->simple_menu.label) 16757a84e134Smrg width = XawMax(width, XtWidth(xaw->simple_menu.label) + hadd); 16767a84e134Smrg 16775ec34c4cSmrg *width_return = (Dimension)width; 16785ec34c4cSmrg *height_return = (Dimension)height; 16797a84e134Smrg 16807a84e134Smrg if (try_layout && columns > 1 && num_children > 2) { 16817a84e134Smrg int space; 16827a84e134Smrg 16837a84e134Smrg height = test_h * (xaw->simple_menu.label ? 16847a84e134Smrg num_children - 1 : 16857a84e134Smrg num_children); 16867a84e134Smrg 16877a84e134Smrg max_dim -= max_dim % test_h; 16887a84e134Smrg space = max_dim - (height % max_dim); 16897a84e134Smrg if (space >= test_h * columns) { 16907a84e134Smrg height = max_dim - space / columns; 16917a84e134Smrg if (height % test_h) 16927a84e134Smrg height += test_h - (height % test_h); 16935ec34c4cSmrg *height_return = (Dimension)(height + vadd); 16947a84e134Smrg CalculateNewSize(w, width_return, height_return); 16957a84e134Smrg } 16967a84e134Smrg } 16977a84e134Smrg} 16987a84e134Smrg 16997a84e134Smrgstatic void 17007a84e134SmrgMakeResizeRequest(Widget w) 17017a84e134Smrg{ 17027a84e134Smrg int tries; 17037a84e134Smrg Dimension width, height; 1704421c997bSmrg 17057a84e134Smrg width = XtWidth(w); 17067a84e134Smrg height = XtHeight(w); 17077a84e134Smrg 17087a84e134Smrg for (tries = 0; tries < 100; tries++) { 17097a84e134Smrg CalculateNewSize(w, &width, &height); 17107a84e134Smrg if (width == XtWidth(w) && height == XtHeight(w)) 17117a84e134Smrg break; 17127a84e134Smrg if (XtMakeResizeRequest(w, width, height, &width, &height) == 17137a84e134Smrg XtGeometryNo) 17147a84e134Smrg break; 17157a84e134Smrg } 17167a84e134Smrg} 17177a84e134Smrg 17187a84e134Smrg#ifndef OLDXAW 17197a84e134Smrgstatic void 17207a84e134SmrgPopdown(Widget w, XEvent *event, String *params, Cardinal *num_params) 17217a84e134Smrg{ 17227a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 17237a84e134Smrg 17247a84e134Smrg while (XtParent(w) && 17257a84e134Smrg XtIsSubclass(XtParent(w), simpleMenuWidgetClass)) { 17267a84e134Smrg if (((SimpleMenuWidget)XtParent(w))->simple_menu.sub_menu == (Widget)w) { 17277a84e134Smrg w = XtParent(w); 17287a84e134Smrg smw = (SimpleMenuWidget)w; 17297a84e134Smrg smw->simple_menu.entry_set = NULL; 17307a84e134Smrg } 17317a84e134Smrg else 17327a84e134Smrg break; 17337a84e134Smrg } 17347a84e134Smrg 17357a84e134Smrg smw->simple_menu.state |= SMW_UNMAPPING; 17367a84e134Smrg if (smw->simple_menu.sub_menu) 17377a84e134Smrg PopdownSubMenu(smw); 17387a84e134Smrg XtCallActionProc(w, "XtMenuPopdown", event, params, *num_params); 17397a84e134Smrg} 17407a84e134Smrg 17417a84e134Smrgstatic void 17427a84e134SmrgPopupSubMenu(SimpleMenuWidget smw) 17437a84e134Smrg{ 17447a84e134Smrg Arg args[2]; 17457a84e134Smrg Cardinal num_args; 17467a84e134Smrg Widget menu; 17477a84e134Smrg SmeBSBObject entry = (SmeBSBObject)smw->simple_menu.entry_set; 17487a84e134Smrg Position menu_x, menu_y; 17497a84e134Smrg Bool popleft; 17507a84e134Smrg 17517a84e134Smrg if (entry->sme_bsb.menu_name == NULL) 17527a84e134Smrg return; 17537a84e134Smrg 17547a84e134Smrg if ((menu = FindMenu((Widget)smw, entry->sme_bsb.menu_name)) == NULL) 17557a84e134Smrg return; 17567a84e134Smrg 17577a84e134Smrg smw->simple_menu.sub_menu = menu; 17587a84e134Smrg 17597a84e134Smrg if (!XtIsRealized(menu)) 17607a84e134Smrg XtRealizeWidget(menu); 17617a84e134Smrg 17627a84e134Smrg popleft = (smw->simple_menu.state & SMW_POPLEFT) != 0; 17637a84e134Smrg 1764421c997bSmrg if (popleft) 17655ec34c4cSmrg XtTranslateCoords((Widget)smw, 17665ec34c4cSmrg (Position)(-(int)XtWidth(menu)), 17675ec34c4cSmrg (Position)(XtY(entry) - XtBorderWidth(menu)), 17685ec34c4cSmrg &menu_x, &menu_y); 17697a84e134Smrg else 17705ec34c4cSmrg XtTranslateCoords((Widget)smw, 17715ec34c4cSmrg (Position)XtWidth(smw), 17725ec34c4cSmrg (Position)(XtY(entry) - XtBorderWidth(menu)), 17735ec34c4cSmrg &menu_x, &menu_y); 17747a84e134Smrg 17757a84e134Smrg if (!popleft && menu_x >= 0) { 17767a84e134Smrg int scr_width = WidthOfScreen(XtScreen(menu)); 17777a84e134Smrg 17787a84e134Smrg if (menu_x + XtWidth(menu) > scr_width) { 17795ec34c4cSmrg menu_x = (Position)(menu_x - (XtWidth(menu) + XtWidth(smw))); 17807a84e134Smrg popleft = True; 17817a84e134Smrg } 17827a84e134Smrg } 17837a84e134Smrg else if (popleft && menu_x < 0) { 17847a84e134Smrg menu_x = 0; 17857a84e134Smrg popleft = False; 17867a84e134Smrg } 17877a84e134Smrg if (menu_y >= 0) { 17887a84e134Smrg int scr_height = HeightOfScreen(XtScreen(menu)); 17897a84e134Smrg 17907a84e134Smrg if (menu_y + XtHeight(menu) > scr_height) 17915ec34c4cSmrg menu_y = (Position)(scr_height - XtHeight(menu) - XtBorderWidth(menu)); 17927a84e134Smrg } 17937a84e134Smrg if (menu_y < 0) 17947a84e134Smrg menu_y = 0; 17957a84e134Smrg 17967a84e134Smrg num_args = 0; 17977a84e134Smrg XtSetArg(args[num_args], XtNx, menu_x); num_args++; 17987a84e134Smrg XtSetArg(args[num_args], XtNy, menu_y); num_args++; 17997a84e134Smrg XtSetValues(menu, args, num_args); 18007a84e134Smrg 18017a84e134Smrg if (popleft) 18027a84e134Smrg ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT; 18037a84e134Smrg else 18045ec34c4cSmrg ((SimpleMenuWidget)menu)->simple_menu.state &= (unsigned char)(~SMW_POPLEFT); 18057a84e134Smrg 18067a84e134Smrg XtPopup(menu, XtGrabNone); 18077a84e134Smrg} 18087a84e134Smrg 18097a84e134Smrgstatic void 18107a84e134SmrgPopdownSubMenu(SimpleMenuWidget smw) 18117a84e134Smrg{ 18127a84e134Smrg SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu; 18137a84e134Smrg 18147a84e134Smrg if (!menu) 18157a84e134Smrg return; 18167a84e134Smrg 18177a84e134Smrg menu->simple_menu.state |= SMW_UNMAPPING; 18187a84e134Smrg PopdownSubMenu(menu); 18197a84e134Smrg 18207a84e134Smrg XtPopdown((Widget)menu); 18217a84e134Smrg 18227a84e134Smrg smw->simple_menu.sub_menu = NULL; 18237a84e134Smrg} 18247a84e134Smrg 18257a84e134Smrg/*ARGSUSED*/ 18267a84e134Smrgstatic void 18275ec34c4cSmrgPopupCB(Widget w, XtPointer client_data _X_UNUSED, XtPointer call_data _X_UNUSED) 18287a84e134Smrg{ 18297a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 18307a84e134Smrg 18315ec34c4cSmrg smw->simple_menu.state &= (unsigned char)(~(SMW_UNMAPPING | SMW_POPLEFT)); 18327a84e134Smrg} 18337a84e134Smrg#endif /* OLDXAW */ 1834