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 */ 275efbcb2bfSmrg#ifndef OLDXAW 276efbcb2bfSmrg False, /* allows_change_managed_set */ 277efbcb2bfSmrg#endif 2787a84e134Smrg}; 2797a84e134Smrg 2807a84e134Smrg#define Superclass (&overrideShellClassRec) 2817a84e134SmrgSimpleMenuClassRec simpleMenuClassRec = { 2827a84e134Smrg /* core */ 2837a84e134Smrg { 2847a84e134Smrg (WidgetClass)Superclass, /* superclass */ 2857a84e134Smrg "SimpleMenu", /* class_name */ 2867a84e134Smrg sizeof(SimpleMenuRec), /* size */ 2877a84e134Smrg XawSimpleMenuClassInitialize, /* class_initialize */ 2887a84e134Smrg XawSimpleMenuClassPartInitialize, /* class_part_initialize */ 2897a84e134Smrg False, /* class_inited */ 2907a84e134Smrg XawSimpleMenuInitialize, /* initialize */ 2917a84e134Smrg NULL, /* initialize_hook */ 2927a84e134Smrg XawSimpleMenuRealize, /* realize */ 2937a84e134Smrg actionsList, /* actions */ 2947a84e134Smrg XtNumber(actionsList), /* num_actions */ 2957a84e134Smrg resources, /* resources */ 2967a84e134Smrg XtNumber(resources), /* num_resources */ 2977a84e134Smrg NULLQUARK, /* xrm_class */ 2987a84e134Smrg True, /* compress_motion */ 2997a84e134Smrg True, /* compress_exposure */ 3007a84e134Smrg True, /* compress_enterleave */ 3017a84e134Smrg False, /* visible_interest */ 3027a84e134Smrg NULL, /* destroy */ 3037a84e134Smrg XawSimpleMenuResize, /* resize */ 3047a84e134Smrg XawSimpleMenuRedisplay, /* expose */ 3057a84e134Smrg XawSimpleMenuSetValues, /* set_values */ 3067a84e134Smrg XawSimpleMenuSetValuesHook, /* set_values_hook */ 3077a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 3087a84e134Smrg NULL, /* get_values_hook */ 3097a84e134Smrg NULL, /* accept_focus */ 3107a84e134Smrg XtVersion, /* intrinsics version */ 3117a84e134Smrg NULL, /* callback offsets */ 3127a84e134Smrg defaultTranslations, /* tm_table */ 3137a84e134Smrg NULL, /* query_geometry */ 3147a84e134Smrg NULL, /* display_accelerator */ 3157a84e134Smrg NULL, /* extension */ 3167a84e134Smrg }, 3177a84e134Smrg /* composite */ 3187a84e134Smrg { 3197a84e134Smrg XawSimpleMenuGeometryManager, /* geometry_manager */ 3207a84e134Smrg XawSimpleMenuChangeManaged, /* change_managed */ 3217a84e134Smrg XtInheritInsertChild, /* insert_child */ 3227a84e134Smrg XtInheritDeleteChild, /* delete_child */ 3237a84e134Smrg NULL, /* extension */ 3247a84e134Smrg }, 3257a84e134Smrg /* shell */ 3267a84e134Smrg { 3277a84e134Smrg NULL, /* extension */ 3287a84e134Smrg }, 3297a84e134Smrg /* override */ 3307a84e134Smrg { 3317a84e134Smrg NULL, /* extension */ 3327a84e134Smrg }, 3337a84e134Smrg /* simple_menu */ 3347a84e134Smrg { 3357a84e134Smrg NULL, /* extension */ 3367a84e134Smrg }, 3377a84e134Smrg}; 3387a84e134Smrg 3397a84e134SmrgWidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec; 3407a84e134Smrg 3417a84e134Smrg/* 3427a84e134Smrg * Implementation 3437a84e134Smrg */ 3447a84e134Smrg/* 3457a84e134Smrg * Function: 3467a84e134Smrg * XawSimpleMenuClassInitialize 3477a84e134Smrg * 3487a84e134Smrg * Description: 3497a84e134Smrg * Class Initialize routine, called only once. 3507a84e134Smrg */ 3517a84e134Smrgstatic void 3527a84e134SmrgXawSimpleMenuClassInitialize(void) 3537a84e134Smrg{ 3547a84e134Smrg XawInitializeWidgetSet(); 3557a84e134Smrg XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, 3567a84e134Smrg NULL, 0); 3577a84e134Smrg XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString, 3587a84e134Smrg NULL, 0, XtCacheNone, NULL); 3597a84e134Smrg XmuAddInitializer(AddPositionAction, NULL); 3607a84e134Smrg} 3617a84e134Smrg 3627a84e134Smrg/* 3637a84e134Smrg * Function: 3647a84e134Smrg * XawSimpleMenuClassPartInitialize 3657a84e134Smrg * Arguments: wc - the widget class of the subclass. 3667a84e134Smrg * 3677a84e134Smrg * Description: 3687a84e134Smrg * Class Part Initialize routine, called for every subclass. Makes 3697a84e134Smrg * sure that the subclasses pick up the extension record. 3707a84e134Smrg */ 3717a84e134Smrgstatic void 3727a84e134SmrgXawSimpleMenuClassPartInitialize(WidgetClass wc) 3737a84e134Smrg{ 3747a84e134Smrg SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass)wc; 3757a84e134Smrg 3767a84e134Smrg /* 3777a84e134Smrg * Make sure that our subclass gets the extension rec too 3787a84e134Smrg */ 3797a84e134Smrg extension_rec.next_extension = smwc->composite_class.extension; 3807a84e134Smrg smwc->composite_class.extension = (XtPointer) &extension_rec; 3817a84e134Smrg} 3827a84e134Smrg 3837a84e134Smrg/* 3847a84e134Smrg * Function: 3857a84e134Smrg * XawSimpleMenuInitialize 3867a84e134Smrg * 3877a84e134Smrg * Parameters: 3887a84e134Smrg * request - widget requested by the argument list 3897a84e134Smrg * cnew - new widget with both resource and non resource values 3907a84e134Smrg * 3917a84e134Smrg * Description: 3927a84e134Smrg * Initializes the simple menu widget. 3937a84e134Smrg */ 3947a84e134Smrg/*ARGSUSED*/ 3957a84e134Smrgstatic void 3965ec34c4cSmrgXawSimpleMenuInitialize(Widget request _X_UNUSED, Widget cnew, 3975ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 3987a84e134Smrg{ 3997a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)cnew; 4007a84e134Smrg Dimension width, height; 4017a84e134Smrg 4027a84e134Smrg XmuCallInitializers(XtWidgetToApplicationContext(cnew)); 4037a84e134Smrg 404421c997bSmrg if (smw->simple_menu.label_class == NULL) 4057a84e134Smrg smw->simple_menu.label_class = smeBSBObjectClass; 4067a84e134Smrg 4077a84e134Smrg smw->simple_menu.label = NULL; 4087a84e134Smrg smw->simple_menu.entry_set = NULL; 4097a84e134Smrg smw->simple_menu.recursive_set_values = False; 4107a84e134Smrg#ifndef OLDXAW 4117a84e134Smrg smw->simple_menu.sub_menu = NULL; 4127a84e134Smrg smw->simple_menu.state = 0; 4137a84e134Smrg 4147a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, PopupCB, NULL); 4157a84e134Smrg#endif 4167a84e134Smrg 4177a84e134Smrg if (smw->simple_menu.label_string != NULL) 4187a84e134Smrg CreateLabel(cnew); 4197a84e134Smrg 4207a84e134Smrg width = height = 0; 4217a84e134Smrg CalculateNewSize(cnew, &width, &height); 4227a84e134Smrg 4237a84e134Smrg smw->simple_menu.menu_width = True; 4247a84e134Smrg 4257a84e134Smrg if (XtWidth(smw) == 0) { 4267a84e134Smrg smw->simple_menu.menu_width = False; 4277a84e134Smrg XtWidth(smw) = width; 4287a84e134Smrg } 4297a84e134Smrg 4307a84e134Smrg smw->simple_menu.menu_height = True; 4317a84e134Smrg 4327a84e134Smrg if (XtHeight(smw) == 0) { 4337a84e134Smrg smw->simple_menu.menu_height = False; 4347a84e134Smrg XtHeight(smw) = height; 4357a84e134Smrg } 4367a84e134Smrg 4377a84e134Smrg /* 4387a84e134Smrg * Add a popup_callback routine for changing the cursor 4397a84e134Smrg */ 4407a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, ChangeCursorOnGrab, NULL); 4417a84e134Smrg} 4427a84e134Smrg 4437a84e134Smrg/* 4447a84e134Smrg * Function: 4457a84e134Smrg * XawSimpleMenuRedisplay 4467a84e134Smrg * 4477a84e134Smrg * Parameters: 4487a84e134Smrg * w - simple menu widget 4497a84e134Smrg * event - X event that caused this redisplay 4507a84e134Smrg * region - region the needs to be repainted 4517a84e134Smrg * 4527a84e134Smrg * Description: 4537a84e134Smrg * Redisplays the contents of the widget. 4547a84e134Smrg */ 4557a84e134Smrg/*ARGSUSED*/ 4567a84e134Smrgstatic void 4575ec34c4cSmrgXawSimpleMenuRedisplay(Widget w, XEvent *event _X_UNUSED, Region region) 4587a84e134Smrg{ 4597a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 4607a84e134Smrg SmeObject *entry; 4617a84e134Smrg SmeObjectClass cclass; 4627a84e134Smrg 4637a84e134Smrg if (region == NULL) 4647a84e134Smrg XClearWindow(XtDisplay(w), XtWindow(w)); 4657a84e134Smrg 4667a84e134Smrg#ifndef OLDXAW 4677a84e134Smrg if (smw->simple_menu.display_list) 4687a84e134Smrg XawRunDisplayList(w, smw->simple_menu.display_list, event, region); 4697a84e134Smrg#endif 4707a84e134Smrg 4717a84e134Smrg /* 4727a84e134Smrg * Check and Paint each of the entries - including the label 4737a84e134Smrg */ 4747a84e134Smrg ForAllChildren(smw, entry) { 4757a84e134Smrg if (!XtIsManaged((Widget)*entry)) 4767a84e134Smrg continue; 4777a84e134Smrg 478421c997bSmrg if (region != NULL) 4797a84e134Smrg switch(XRectInRegion(region, XtX(*entry),XtY(*entry), 4807a84e134Smrg XtWidth(*entry), XtHeight(*entry))) { 4817a84e134Smrg case RectangleIn: 4827a84e134Smrg case RectanglePart: 4837a84e134Smrg break; 4847a84e134Smrg default: 4857a84e134Smrg continue; 4867a84e134Smrg } 4877a84e134Smrg 4887a84e134Smrg cclass = (SmeObjectClass)(*entry)->object.widget_class; 4897a84e134Smrg 4907a84e134Smrg if (cclass->rect_class.expose != NULL) 4917a84e134Smrg (cclass->rect_class.expose)((Widget)*entry, NULL, NULL); 4927a84e134Smrg } 4937a84e134Smrg} 4947a84e134Smrg 4957a84e134Smrg/* 4967a84e134Smrg * Function: 4977a84e134Smrg * XawSimpleMenuRealize 4987a84e134Smrg * 4997a84e134Smrg * Parameters: 5007a84e134Smrg * w - simple menu widget 5017a84e134Smrg * mask - value mask for the window to create 5027a84e134Smrg * attrs - attributes for the window to create 5037a84e134Smrg * 5047a84e134Smrg * Description: 5057a84e134Smrg * Realizes the widget. 5067a84e134Smrg */ 5077a84e134Smrgstatic void 5087a84e134SmrgXawSimpleMenuRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attrs) 5097a84e134Smrg{ 5107a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 5117a84e134Smrg#ifndef OLDXAW 5127a84e134Smrg XawPixmap *pixmap; 5137a84e134Smrg#endif 5147a84e134Smrg 5157a84e134Smrg attrs->cursor = smw->simple_menu.cursor; 5167a84e134Smrg *mask |= CWCursor; 5177a84e134Smrg if (smw->simple_menu.backing_store == Always || 5187a84e134Smrg smw->simple_menu.backing_store == NotUseful || 5197a84e134Smrg smw->simple_menu.backing_store == WhenMapped) { 5207a84e134Smrg *mask |= CWBackingStore; 5217a84e134Smrg attrs->backing_store = smw->simple_menu.backing_store; 5227a84e134Smrg } 5237a84e134Smrg else 5245ec34c4cSmrg *mask &= (XtValueMask)(~CWBackingStore); 5257a84e134Smrg 5267a84e134Smrg (*Superclass->core_class.realize)(w, mask, attrs); 5277a84e134Smrg 5287a84e134Smrg#ifndef OLDXAW 5297a84e134Smrg if (w->core.background_pixmap > XtUnspecifiedPixmap) { 5307a84e134Smrg pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), 5315ec34c4cSmrg w->core.colormap, (int)w->core.depth); 5327a84e134Smrg if (pixmap && pixmap->mask) 5337a84e134Smrg XawReshapeWidget(w, pixmap); 5347a84e134Smrg } 5357a84e134Smrg#endif 5367a84e134Smrg} 5377a84e134Smrg 5387a84e134Smrg/* 5397a84e134Smrg * Function: 5407a84e134Smrg * XawSimpleMenuResize 5417a84e134Smrg * 5427a84e134Smrg * Parameters: 5437a84e134Smrg * w - simple menu widget 5447a84e134Smrg * 5457a84e134Smrg * Description: 5467a84e134Smrg * Handle the menu being resized. 5477a84e134Smrg */ 5487a84e134Smrgstatic void 5497a84e134SmrgXawSimpleMenuResize(Widget w) 5507a84e134Smrg{ 5517a84e134Smrg if (!XtIsRealized(w)) 5527a84e134Smrg return; 5537a84e134Smrg 5547a84e134Smrg Layout(w, NULL, NULL); 5557a84e134Smrg 5567a84e134Smrg XawSimpleMenuRedisplay(w, NULL, NULL); 5577a84e134Smrg} 5587a84e134Smrg 5597a84e134Smrg/* 5607a84e134Smrg * Function: 5617a84e134Smrg * XawSimpleMenuSetValues 5627a84e134Smrg * 5637a84e134Smrg * Parameters: 5647a84e134Smrg * current - current state of the widget 5657a84e134Smrg * request - what was requested 5667a84e134Smrg * cnew - what the widget will become 5677a84e134Smrg * 5687a84e134Smrg * Description: 5697a84e134Smrg * Relayout the menu when one of the resources is changed. 5707a84e134Smrg */ 5717a84e134Smrg/*ARGSUSED*/ 5727a84e134Smrgstatic Boolean 5735ec34c4cSmrgXawSimpleMenuSetValues(Widget current, Widget request _X_UNUSED, Widget cnew, 5745ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 5757a84e134Smrg{ 5767a84e134Smrg SimpleMenuWidget smw_old = (SimpleMenuWidget)current; 5777a84e134Smrg SimpleMenuWidget smw_new = (SimpleMenuWidget)cnew; 5787a84e134Smrg Boolean ret_val = False, layout = False; 5797a84e134Smrg 5807a84e134Smrg if (!XtIsRealized(current)) 5817a84e134Smrg return (False); 5827a84e134Smrg 5837a84e134Smrg if (!smw_new->simple_menu.recursive_set_values) { 5847a84e134Smrg if (XtWidth(smw_new) != XtWidth(smw_old)) { 5857a84e134Smrg smw_new->simple_menu.menu_width = XtWidth(smw_new) != 0; 5867a84e134Smrg layout = True; 5877a84e134Smrg } 5887a84e134Smrg if (XtHeight(smw_new) != XtHeight(smw_old)) { 5897a84e134Smrg smw_new->simple_menu.menu_height = XtHeight(smw_new) != 0; 5907a84e134Smrg layout = True; 5917a84e134Smrg } 5927a84e134Smrg } 5937a84e134Smrg 5947a84e134Smrg if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor) 5957a84e134Smrg XDefineCursor(XtDisplay(cnew), XtWindow(cnew), 5967a84e134Smrg smw_new->simple_menu.cursor); 5977a84e134Smrg 5987a84e134Smrg if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string) { 5997a84e134Smrg if (smw_new->simple_menu.label_string == NULL) /* Destroy */ 6007a84e134Smrg XtDestroyWidget((Widget)smw_old->simple_menu.label); 6017a84e134Smrg else if (smw_old->simple_menu.label_string == NULL) /* Create */ 6027a84e134Smrg CreateLabel(cnew); 6037a84e134Smrg else { /* Change */ 6047a84e134Smrg Arg arglist[1]; 605421c997bSmrg 6067a84e134Smrg XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string); 6077a84e134Smrg XtSetValues((Widget)smw_new->simple_menu.label, arglist, ONE); 6087a84e134Smrg } 6097a84e134Smrg } 6107a84e134Smrg 6117a84e134Smrg if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class) 6127a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(cnew), 6137a84e134Smrg "No Dynamic class change of the SimpleMenu Label."); 614421c997bSmrg 6157a84e134Smrg if (smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin 6167a84e134Smrg || smw_old->simple_menu.bottom_margin 6177a84e134Smrg != smw_new->simple_menu.bottom_margin) { 6187a84e134Smrg layout = True; 6197a84e134Smrg ret_val = True; 6207a84e134Smrg } 6217a84e134Smrg 6227a84e134Smrg#ifndef OLDXAW 6237a84e134Smrg if (smw_old->core.background_pixmap != smw_new->core.background_pixmap) { 6247a84e134Smrg XawPixmap *opix, *npix; 6257a84e134Smrg 6267a84e134Smrg opix = XawPixmapFromXPixmap(smw_old->core.background_pixmap, 6277a84e134Smrg XtScreen(smw_old), smw_old->core.colormap, 6285ec34c4cSmrg (int)smw_old->core.depth); 6297a84e134Smrg npix = XawPixmapFromXPixmap(smw_new->core.background_pixmap, 6307a84e134Smrg XtScreen(smw_new), smw_new->core.colormap, 6315ec34c4cSmrg (int)smw_new->core.depth); 6327a84e134Smrg if ((npix && npix->mask) || (opix && opix->mask)) 6337a84e134Smrg XawReshapeWidget(cnew, npix); 6347a84e134Smrg } 6357a84e134Smrg#endif 6367a84e134Smrg 6377a84e134Smrg if (layout) 6387a84e134Smrg Layout(cnew, NULL, NULL); 6397a84e134Smrg 6407a84e134Smrg return (ret_val); 6417a84e134Smrg} 6427a84e134Smrg 643421c997bSmrg/* 6447a84e134Smrg * Function: 6457a84e134Smrg * XawSimpleMenuSetValuesHook 6467a84e134Smrg * 6477a84e134Smrg * Parameters: 6487a84e134Smrg * w - menu widget 6497a84e134Smrg * arglist - argument list passed to XtSetValues 6507a84e134Smrg * num_args - number of args 6517a84e134Smrg * 6527a84e134Smrg * Description: 6537a84e134Smrg * To handle a special case, this is passed the actual arguments. 6547a84e134Smrg */ 6557a84e134Smrgstatic Boolean 6567a84e134SmrgXawSimpleMenuSetValuesHook(Widget w, ArgList arglist, Cardinal *num_args) 6577a84e134Smrg{ 6587a84e134Smrg Cardinal i; 6597a84e134Smrg Dimension width, height; 660421c997bSmrg 6617a84e134Smrg width = XtWidth(w); 6627a84e134Smrg height = XtHeight(w); 663421c997bSmrg 6647a84e134Smrg for (i = 0 ; i < *num_args ; i++) { 6657a84e134Smrg if (streq(arglist[i].name, XtNwidth)) 6667a84e134Smrg width = (Dimension)arglist[i].value; 6677a84e134Smrg if (streq(arglist[i].name, XtNheight)) 6687a84e134Smrg height = (Dimension) arglist[i].value; 6697a84e134Smrg } 6707a84e134Smrg 6717a84e134Smrg if (width != XtWidth(w) || height != XtHeight(w)) 6727a84e134Smrg MakeSetValuesRequest(w, width, height); 6737a84e134Smrg 6747a84e134Smrg return (False); 6757a84e134Smrg} 6767a84e134Smrg 6777a84e134Smrg/* 6787a84e134Smrg * Geometry Management routines 6797a84e134Smrg */ 6807a84e134Smrg/* 6817a84e134Smrg * Function: 6827a84e134Smrg * XawSimpleMenuGeometryManager 6837a84e134Smrg * 6847a84e134Smrg * Parameters: 6857a84e134Smrg * w - Menu Entry making the request 6867a84e134Smrg * request - requested new geometry 6877a84e134Smrg * reply - the allowed geometry. 6887a84e134Smrg * 6897a84e134Smrg * Description: 6907a84e134Smrg * This is the SimpleMenu Widget's Geometry Manager. 6917a84e134Smrg * 6927a84e134Smrg * Returns: 6937a84e134Smrg * XtGeometry{Yes, No, Almost} 6947a84e134Smrg */ 6957a84e134Smrgstatic XtGeometryResult 6967a84e134SmrgXawSimpleMenuGeometryManager(Widget w, XtWidgetGeometry *request, 6977a84e134Smrg XtWidgetGeometry *reply) 6987a84e134Smrg{ 6997a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)XtParent(w); 7007a84e134Smrg SmeObject entry = (SmeObject)w; 7017a84e134Smrg XtGeometryMask mode = request->request_mode; 7027a84e134Smrg XtGeometryResult answer; 7037a84e134Smrg Dimension old_height, old_width; 7047a84e134Smrg 7057a84e134Smrg if (!(mode & CWWidth) && !(mode & CWHeight)) 7067a84e134Smrg return (XtGeometryNo); 7077a84e134Smrg 7087a84e134Smrg reply->width = request->width; 7097a84e134Smrg reply->height = request->height; 7107a84e134Smrg 7117a84e134Smrg old_width = XtWidth(entry); 7127a84e134Smrg old_height = XtHeight(entry); 7137a84e134Smrg 7147a84e134Smrg Layout(w, &reply->width, &reply->height); 7157a84e134Smrg 7167a84e134Smrg /* 7177a84e134Smrg * Since we are an override shell and have no parent there is no one to 7187a84e134Smrg * ask to see if this geom change is okay, so I am just going to assume 7197a84e134Smrg * we can do whatever we want. If you subclass be very careful with this 7207a84e134Smrg * assumption, it could bite you. 7217a84e134Smrg * 7227a84e134Smrg * Chris D. Peterson - Sept. 1989. 7237a84e134Smrg */ 7247a84e134Smrg if ((!(mode & CWWidth) || reply->width == request->width) 7257a84e134Smrg && (!(mode & CWHeight) || reply->height == request->height)) { 7267a84e134Smrg if (mode & XtCWQueryOnly) { /* Actually perform the layout */ 7277a84e134Smrg XtWidth(entry) = old_width; 7287a84e134Smrg XtHeight(entry) = old_height; 7297a84e134Smrg } 7307a84e134Smrg else 7317a84e134Smrg Layout((Widget)smw, NULL, NULL); 7327a84e134Smrg answer = XtGeometryDone; 7337a84e134Smrg } 7347a84e134Smrg else { 7357a84e134Smrg XtWidth(entry) = old_width; 7367a84e134Smrg XtHeight(entry) = old_height; 7377a84e134Smrg 7387a84e134Smrg if ((reply->width == request->width && !(mode & CWHeight)) 7397a84e134Smrg || (reply->height == request->height && !(mode & CWWidth)) 7407a84e134Smrg || (reply->width == request->width 7417a84e134Smrg && reply->height == request->height)) 7427a84e134Smrg answer = XtGeometryNo; 7437a84e134Smrg else { 7447a84e134Smrg answer = XtGeometryAlmost; 7457a84e134Smrg reply->request_mode = 0; 7467a84e134Smrg if (reply->width != request->width) 7477a84e134Smrg reply->request_mode |= CWWidth; 7487a84e134Smrg if (reply->height != request->height) 7497a84e134Smrg reply->request_mode |= CWHeight; 7507a84e134Smrg } 7517a84e134Smrg } 7527a84e134Smrg 7537a84e134Smrg return (answer); 7547a84e134Smrg} 7557a84e134Smrg 7567a84e134Smrg/* 7577a84e134Smrg * Function: 7587a84e134Smrg * XawSimpleMenuChangeManaged 7597a84e134Smrg * 7607a84e134Smrg * Parameters: 7617a84e134Smrg * w - simple menu widget 7627a84e134Smrg * 7637a84e134Smrg * Description: 7647a84e134Smrg * Called whenever a new child is managed. 7657a84e134Smrg */ 7667a84e134Smrgstatic void 7677a84e134SmrgXawSimpleMenuChangeManaged(Widget w) 7687a84e134Smrg{ 7697a84e134Smrg Layout(w, NULL, NULL); 7707a84e134Smrg} 7717a84e134Smrg 7727a84e134Smrg/* 7737a84e134Smrg * Global Action Routines 774421c997bSmrg * 7757a84e134Smrg * These actions routines will be added to the application's 7767a84e134Smrg * global action list 7777a84e134Smrg */ 7787a84e134Smrg/* 7797a84e134Smrg * Function: 7807a84e134Smrg * PositionMenuAction 781421c997bSmrg * 7827a84e134Smrg * Parameters: 7837a84e134Smrg * w - a widget (no the simple menu widget) 7847a84e134Smrg * event - the event that caused this action 7857a84e134Smrg * params - parameters passed to the routine. 7867a84e134Smrg * we expect the name of the menu here. 7877a84e134Smrg * num_params - "" 7887a84e134Smrg * 7897a84e134Smrg * Description: 7907a84e134Smrg * Positions the simple menu widget. 7917a84e134Smrg */ 7927a84e134Smrg/*ARGSUSED*/ 7937a84e134Smrgstatic void 7947a84e134SmrgPositionMenuAction(Widget w, XEvent *event, 7957a84e134Smrg String *params, Cardinal *num_params) 796421c997bSmrg{ 7977a84e134Smrg Widget menu; 7987a84e134Smrg XPoint loc; 7997a84e134Smrg 8007a84e134Smrg if (*num_params != 1) { 8017a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 8027a84e134Smrg "SimpleMenuWidget: position menu action expects " 8037a84e134Smrg "only one parameter which is the name of the menu."); 8047a84e134Smrg return; 8057a84e134Smrg } 8067a84e134Smrg 8077a84e134Smrg if ((menu = FindMenu(w, params[0])) == NULL) { 8087a84e134Smrg char error_buf[BUFSIZ]; 8097a84e134Smrg 810421c997bSmrg snprintf(error_buf, sizeof(error_buf), 811421c997bSmrg "SimpleMenuWidget: could not find menu named %s.", 812421c997bSmrg params[0]); 8137a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), error_buf); 8147a84e134Smrg return; 8157a84e134Smrg } 816421c997bSmrg 8177a84e134Smrg switch (event->type) { 8187a84e134Smrg case ButtonPress: 8197a84e134Smrg case ButtonRelease: 8205ec34c4cSmrg loc.x = (short)event->xbutton.x_root; 8215ec34c4cSmrg loc.y = (short)event->xbutton.y_root; 8227a84e134Smrg PositionMenu(menu, &loc); 8237a84e134Smrg break; 8247a84e134Smrg case EnterNotify: 8257a84e134Smrg case LeaveNotify: 8265ec34c4cSmrg loc.x = (short)event->xcrossing.x_root; 8275ec34c4cSmrg loc.y = (short)event->xcrossing.y_root; 8287a84e134Smrg PositionMenu(menu, &loc); 8297a84e134Smrg break; 8307a84e134Smrg case MotionNotify: 8315ec34c4cSmrg loc.x = (short)event->xmotion.x_root; 8325ec34c4cSmrg loc.y = (short)event->xmotion.y_root; 8337a84e134Smrg PositionMenu(menu, &loc); 8347a84e134Smrg break; 8357a84e134Smrg default: 8367a84e134Smrg PositionMenu(menu, NULL); 8377a84e134Smrg break; 8387a84e134Smrg } 839421c997bSmrg} 8407a84e134Smrg 8417a84e134Smrg/* 8427a84e134Smrg * Widget Action Routines 8437a84e134Smrg */ 8447a84e134Smrg/* 8457a84e134Smrg * Function: 8467a84e134Smrg * Unhighlight 8477a84e134Smrg * 8487a84e134Smrg * Parameters: 8497a84e134Smrg * w - simple menu widget 8507a84e134Smrg * event - event that caused this action 8517a84e134Smrg * params - not used 8527a84e134Smrg * num_params - "" 853421c997bSmrg * 8547a84e134Smrg * Description: 8557a84e134Smrg * Unhighlights current entry. 8567a84e134Smrg */ 8577a84e134Smrg/*ARGSUSED*/ 8587a84e134Smrgstatic void 8595ec34c4cSmrgUnhighlight(Widget w, XEvent *event _X_UNUSED, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 860421c997bSmrg{ 8617a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8627a84e134Smrg SmeObject entry = smw->simple_menu.entry_set; 863421c997bSmrg 8647a84e134Smrg if (entry == NULL) 8657a84e134Smrg return; 8667a84e134Smrg 8677a84e134Smrg#ifndef OLDXAW 8687a84e134Smrg if (!smw->simple_menu.sub_menu) 8697a84e134Smrg#endif 8707a84e134Smrg { 8717a84e134Smrg SmeObjectClass cclass; 8727a84e134Smrg 8737a84e134Smrg smw->simple_menu.entry_set = NULL; 8747a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 8757a84e134Smrg (cclass->sme_class.unhighlight)((Widget)entry); 8767a84e134Smrg } 8777a84e134Smrg} 8787a84e134Smrg 8797a84e134Smrg/* 8807a84e134Smrg * Function: 8817a84e134Smrg * Highlight 8827a84e134Smrg * 8837a84e134Smrg * Parameters: 8847a84e134Smrg * w - simple menu widget 8857a84e134Smrg * event - event that caused this action 8867a84e134Smrg * params - not used 8877a84e134Smrg * num_params - "" 8887a84e134Smrg * 8897a84e134Smrg * Description: 8907a84e134Smrg * Highlights current entry. 8917a84e134Smrg */ 8927a84e134Smrg/*ARGSUSED*/ 8937a84e134Smrgstatic void 8947a84e134SmrgHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) 8957a84e134Smrg{ 8967a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8977a84e134Smrg SmeObject entry; 8987a84e134Smrg 8997a84e134Smrg if (!XtIsSensitive(w)) 9007a84e134Smrg return; 9017a84e134Smrg 9027a84e134Smrg entry = GetEventEntry(w, event); 9037a84e134Smrg 9047a84e134Smrg if (entry == smw->simple_menu.entry_set) 9057a84e134Smrg return; 9067a84e134Smrg 9077a84e134Smrg#ifndef OLDXAW 9087a84e134Smrg if (!smw->simple_menu.sub_menu) 9097a84e134Smrg#endif 9107a84e134Smrg Unhighlight(w, event, params, num_params); 9117a84e134Smrg 9127a84e134Smrg if (entry == NULL) 9137a84e134Smrg return; 9147a84e134Smrg 9157a84e134Smrg if (!XtIsSensitive((Widget)entry)) 9167a84e134Smrg return; 9177a84e134Smrg 9187a84e134Smrg#ifndef OLDXAW 9197a84e134Smrg if (smw->simple_menu.sub_menu) 9207a84e134Smrg PopdownSubMenu(smw); 9217a84e134Smrg#endif 9227a84e134Smrg 9237a84e134Smrg Unhighlight(w, event, params, num_params); 9247a84e134Smrg 9257a84e134Smrg#ifndef OLDXAW 9267a84e134Smrg if (!(smw->simple_menu.state & SMW_UNMAPPING)) 9277a84e134Smrg#endif 9287a84e134Smrg { 9297a84e134Smrg SmeObjectClass cclass; 9307a84e134Smrg 9317a84e134Smrg smw->simple_menu.entry_set = entry; 9327a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 9337a84e134Smrg 9347a84e134Smrg (cclass->sme_class.highlight)((Widget)entry); 9357a84e134Smrg 9367a84e134Smrg#ifndef OLDXAW 9377a84e134Smrg if (XtIsSubclass((Widget)entry, smeBSBObjectClass)) 9387a84e134Smrg PopupSubMenu(smw); 9397a84e134Smrg#endif 9407a84e134Smrg } 9417a84e134Smrg} 9427a84e134Smrg 9437a84e134Smrg/* 9447a84e134Smrg * Function: 9457a84e134Smrg * Notify 9467a84e134Smrg * 9477a84e134Smrg * Parameters: 9487a84e134Smrg * w - simple menu widget 9497a84e134Smrg * event - event that caused this action 9507a84e134Smrg * params - not used 9517a84e134Smrg * num_params - "" 9527a84e134Smrg * 9537a84e134Smrg * Description: 9547a84e134Smrg * Notify user of current entry. 9557a84e134Smrg */ 9567a84e134Smrg/*ARGSUSED*/ 9577a84e134Smrgstatic void 9585ec34c4cSmrgNotify(Widget w, XEvent *event, String *params _X_UNUSED, Cardinal *num_params _X_UNUSED) 9597a84e134Smrg{ 9607a84e134Smrg SmeObject entry; 9617a84e134Smrg SmeObjectClass cclass; 9627a84e134Smrg 9637a84e134Smrg /* may be a propagated event from a sub menu, need to check it */ 9647a84e134Smrg if (XtWindow(w) != event->xany.window) 9657a84e134Smrg return; 9667a84e134Smrg entry = GetEventEntry(w, event); 9677a84e134Smrg if (entry == NULL || !XtIsSensitive((Widget)entry)) 9687a84e134Smrg return; 9697a84e134Smrg 9707a84e134Smrg cclass = (SmeObjectClass) entry->object.widget_class; 9717a84e134Smrg (cclass->sme_class.notify)((Widget)entry); 9727a84e134Smrg} 9737a84e134Smrg 9747a84e134Smrg/* 9757a84e134Smrg * Public Functions 9767a84e134Smrg */ 9777a84e134Smrg/* 9787a84e134Smrg * Function: 9797a84e134Smrg * XawSimpleMenuAddGlobalActions 9807a84e134Smrg * 9817a84e134Smrg * Arguments: 9827a84e134Smrg * app_con - appcontext 9837a84e134Smrg * 9847a84e134Smrg * Description: 9857a84e134Smrg * Adds the global actions to the simple menu widget. 9867a84e134Smrg */ 9877a84e134Smrgvoid 9887a84e134SmrgXawSimpleMenuAddGlobalActions(XtAppContext app_con) 9897a84e134Smrg{ 9907a84e134Smrg XtInitializeWidgetClass(simpleMenuWidgetClass); 9917a84e134Smrg XmuCallInitializers(app_con); 992421c997bSmrg} 9937a84e134Smrg 9947a84e134Smrg/* 9957a84e134Smrg * Function: 9967a84e134Smrg * XawSimpleMenuGetActiveEntry 9977a84e134Smrg * 9987a84e134Smrg * Parameters: 9997a84e134Smrg * w - smw widget 10007a84e134Smrg * 10017a84e134Smrg * Description: 10027a84e134Smrg * Gets the currently active (set) entry. 10037a84e134Smrg * 10047a84e134Smrg * Returns: 10057a84e134Smrg * The currently set entry or NULL if none is set 10067a84e134Smrg */ 10077a84e134SmrgWidget 10087a84e134SmrgXawSimpleMenuGetActiveEntry(Widget w) 10097a84e134Smrg{ 10107a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10117a84e134Smrg 10127a84e134Smrg return ((Widget)smw->simple_menu.entry_set); 1013421c997bSmrg} 10147a84e134Smrg 10157a84e134Smrg/* 10167a84e134Smrg * Function: 10177a84e134Smrg * XawSimpleMenuClearActiveEntry 10187a84e134Smrg * 10197a84e134Smrg * Parameters: 10207a84e134Smrg * w - smw widget 10217a84e134Smrg * 10227a84e134Smrg * Description: 10237a84e134Smrg * Unsets the currently active (set) entry. 10247a84e134Smrg */ 10257a84e134Smrgvoid 10267a84e134SmrgXawSimpleMenuClearActiveEntry(Widget w) 10277a84e134Smrg{ 10287a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10297a84e134Smrg 10307a84e134Smrg smw->simple_menu.entry_set = NULL; 1031421c997bSmrg} 10327a84e134Smrg 10337a84e134Smrg/* 10347a84e134Smrg * Private Functions 10357a84e134Smrg */ 10367a84e134Smrg/* 10377a84e134Smrg * Function: 10387a84e134Smrg * CreateLabel 10397a84e134Smrg * 10407a84e134Smrg * Parameters: 10417a84e134Smrg * w - smw widget 1042421c997bSmrg * 10437a84e134Smrg * Description: 10447a84e134Smrg * Creates the label object and makes sure it is the first child in 10457a84e134Smrg * in the list. 10467a84e134Smrg */ 10477a84e134Smrgstatic void 10487a84e134SmrgCreateLabel(Widget w) 10497a84e134Smrg{ 10507a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10517a84e134Smrg Widget *child, *next_child; 10527a84e134Smrg int i; 10537a84e134Smrg Arg args[2]; 10547a84e134Smrg 10557a84e134Smrg if (smw->simple_menu.label_string == NULL || 10567a84e134Smrg smw->simple_menu.label != NULL) { 10577a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 10587a84e134Smrg "Xaw Simple Menu Widget: label string is NULL or " 10597a84e134Smrg "label already exists, no label is being created."); 10607a84e134Smrg return; 10617a84e134Smrg } 10627a84e134Smrg 10637a84e134Smrg XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string); 10647a84e134Smrg XtSetArg(args[1], XtNjustify, XtJustifyCenter); 1065421c997bSmrg smw->simple_menu.label = (SmeObject) 1066421c997bSmrg XtCreateManagedWidget("menuLabel", 10677a84e134Smrg smw->simple_menu.label_class, w, args, TWO); 10687a84e134Smrg 10697a84e134Smrg next_child = NULL; 10707a84e134Smrg for (child = smw->composite.children + smw->composite.num_children, 10715ec34c4cSmrg i = (int)smw->composite.num_children; i > 0; i--, child--) { 10727a84e134Smrg if (next_child != NULL) 10737a84e134Smrg *next_child = *child; 10747a84e134Smrg next_child = child; 10757a84e134Smrg } 1076efbcb2bfSmrg 1077efbcb2bfSmrg if (child != NULL) 1078efbcb2bfSmrg *child = (Widget)smw->simple_menu.label; 10797a84e134Smrg} 10807a84e134Smrg 10817a84e134Smrg/* 10827a84e134Smrg * Function: 10837a84e134Smrg * Layout 10847a84e134Smrg * 10857a84e134Smrg * Arguments: 10867a84e134Smrg * w - See below 10877a84e134Smrg * width_ret - returned width 10887a84e134Smrg * height_ret - returned height 10897a84e134Smrg * 10907a84e134Smrg * Note: 10917a84e134Smrg * if width == NULL || height == NULL then it assumes the you do not care 10927a84e134Smrg * about the return values, and just want a relayout. 10937a84e134Smrg * 10947a84e134Smrg * if this is not the case then it will set width_ret and height_ret 10955b16253fSmrg * to be width and height that the child would get if it were laid out 10967a84e134Smrg * at this time. 10977a84e134Smrg * 10987a84e134Smrg * "w" can be the simple menu widget or any of its object children. 10997a84e134Smrg */ 11007a84e134Smrgstatic void 11017a84e134SmrgLayout(Widget w, Dimension *width_ret, Dimension *height_ret) 11027a84e134Smrg{ 11037a84e134Smrg SmeObject current_entry; 11047a84e134Smrg SimpleMenuWidget smw; 11057a84e134Smrg Dimension width, height; 11067a84e134Smrg Boolean allow_change_size; 11077a84e134Smrg Widget kid; 11087a84e134Smrg Cardinal i, count, n; 11097a84e134Smrg int width_kid, height_kid, tmp_w, tmp_h; 11107a84e134Smrg short vadd, hadd, x_ins, y_ins; 11117a84e134Smrg Dimension *widths; 11127a84e134Smrg 11137a84e134Smrg if (XtIsSubclass(w, simpleMenuWidgetClass)) { 11147a84e134Smrg smw = (SimpleMenuWidget)w; 11157a84e134Smrg current_entry = NULL; 11167a84e134Smrg } 11177a84e134Smrg else { 11187a84e134Smrg smw = (SimpleMenuWidget)XtParent(w); 11197a84e134Smrg current_entry = (SmeObject)w; 11207a84e134Smrg } 11217a84e134Smrg 11227a84e134Smrg allow_change_size = (!XtIsRealized((Widget)smw) 11237a84e134Smrg || smw->shell.allow_shell_resize); 11247a84e134Smrg 11257a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11267a84e134Smrg i < smw->composite.num_children; 11277a84e134Smrg i++) { 11287a84e134Smrg XtWidgetGeometry preferred; 11297a84e134Smrg 11307a84e134Smrg kid = smw->composite.children[i]; 11317a84e134Smrg if (!XtIsManaged(kid)) 11327a84e134Smrg continue; 11337a84e134Smrg if (smw->simple_menu.row_height != 0) 11347a84e134Smrg XtHeight(kid) = smw->simple_menu.row_height; 11357a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11367a84e134Smrg if (preferred.request_mode & CWWidth) 11377a84e134Smrg XtWidth(kid) = preferred.width; 11387a84e134Smrg } 11397a84e134Smrg 11407a84e134Smrg if (smw->simple_menu.label 11417a84e134Smrg && XtIsManaged((Widget)smw->simple_menu.label)) { 11427a84e134Smrg XtWidgetGeometry preferred; 11437a84e134Smrg 11447a84e134Smrg kid = (Widget)smw->simple_menu.label; 11457a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11467a84e134Smrg if (preferred.request_mode & CWWidth) 11477a84e134Smrg XtWidth(kid) = preferred.width; 11487a84e134Smrg if (preferred.request_mode & CWHeight) 11497a84e134Smrg XtHeight(kid) = preferred.height; 11507a84e134Smrg } 11517a84e134Smrg 11527a84e134Smrg /* reset */ 11537a84e134Smrg if (!smw->simple_menu.menu_width) 11547a84e134Smrg XtWidth(smw) = 0; 11557a84e134Smrg if (!smw->simple_menu.menu_height) 11567a84e134Smrg XtHeight(smw) = 0; 11577a84e134Smrg if (!XtWidth(smw) || !XtHeight(smw)) 11587a84e134Smrg MakeResizeRequest((Widget)smw); 11597a84e134Smrg 11607a84e134Smrg widths = (Dimension *)XtMalloc(sizeof(Dimension)); 11617a84e134Smrg#ifndef OLDXAW 11625ec34c4cSmrg hadd = (short)smw->simple_menu.left_margin; 11637a84e134Smrg#else 11647a84e134Smrg hadd = 0; 11657a84e134Smrg#endif 11665ec34c4cSmrg vadd = (short)smw->simple_menu.top_margin; 11677a84e134Smrg if (smw->simple_menu.label) 11685ec34c4cSmrg vadd = (short)(vadd + XtHeight(smw->simple_menu.label)); 11697a84e134Smrg 11707a84e134Smrg count = 1; 11715ec34c4cSmrg width = (Dimension)(tmp_w = tmp_h = (int)(n = 0)); 11725ec34c4cSmrg height = (Dimension)vadd; 11737a84e134Smrg 11747a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11757a84e134Smrg i < smw->composite.num_children; 11767a84e134Smrg i++) { 11777a84e134Smrg kid = smw->composite.children[i]; 11787a84e134Smrg if (!XtIsManaged(kid)) 11797a84e134Smrg continue; 11807a84e134Smrg width_kid = XtWidth(kid); 11817a84e134Smrg height_kid = XtHeight(kid); 11827a84e134Smrg 11837a84e134Smrg if (n && (height + height_kid + smw->simple_menu.bottom_margin 11847a84e134Smrg > XtHeight(smw))) { 11857a84e134Smrg ++count; 11867a84e134Smrg widths = (Dimension *)XtRealloc((char *)widths, 11875ec34c4cSmrg (Cardinal)(sizeof(Dimension) * count)); 11885ec34c4cSmrg widths[count - 1] = (Dimension)width_kid; 11895ec34c4cSmrg width = (Dimension)(width + tmp_w); 11907a84e134Smrg tmp_w = width_kid; 11915ec34c4cSmrg height = (Dimension)(height_kid + vadd); 11927a84e134Smrg } 11937a84e134Smrg else 11945ec34c4cSmrg height = (Dimension)(height + height_kid); 11957a84e134Smrg if (height > tmp_h) 11967a84e134Smrg tmp_h = height; 11977a84e134Smrg if (width_kid > tmp_w) 11985ec34c4cSmrg widths[count - 1] = (Dimension)(tmp_w = width_kid); 11997a84e134Smrg ++n; 12007a84e134Smrg } 12017a84e134Smrg 1202efbcb2bfSmrg height = (Dimension)(tmp_h + smw->simple_menu.bottom_margin); 12035ec34c4cSmrg width = (Dimension)(width + tmp_w); 12047a84e134Smrg 12057a84e134Smrg if (smw->simple_menu.label && width < XtWidth(smw->simple_menu.label)) { 12067a84e134Smrg float inc; 12077a84e134Smrg 12085ec34c4cSmrg inc = (float)(XtWidth(smw->simple_menu.label) - width) / (float)count; 12097a84e134Smrg width = XtWidth(smw->simple_menu.label); 12107a84e134Smrg for (n = 0; n < count; n++) 12115ec34c4cSmrg widths[n] = (Dimension)(widths[n] + inc); 12127a84e134Smrg } 12137a84e134Smrg 12147a84e134Smrg#ifndef OLDXAW 12155ec34c4cSmrg width = (Dimension)(width + (hadd + smw->simple_menu.right_margin)); 12167a84e134Smrg#endif 12177a84e134Smrg 12185ec34c4cSmrg x_ins = (short)(n = count = 0); 12197a84e134Smrg tmp_w = widths[0]; 12207a84e134Smrg tmp_h = vadd; 12217a84e134Smrg 12227a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 12237a84e134Smrg i < smw->composite.num_children; 12247a84e134Smrg i++) { 12257a84e134Smrg kid = smw->composite.children[i]; 12267a84e134Smrg if (!XtIsManaged(kid)) 12277a84e134Smrg continue; 12287a84e134Smrg 12297a84e134Smrg height_kid = XtHeight(kid); 12307a84e134Smrg 12317a84e134Smrg if (n && (tmp_h + height_kid + smw->simple_menu.bottom_margin 12327a84e134Smrg > XtHeight(smw))) { 12335ec34c4cSmrg x_ins = (short)tmp_w; 12347a84e134Smrg y_ins = vadd; 12357a84e134Smrg ++count; 12367a84e134Smrg tmp_w += widths[count]; 12377a84e134Smrg tmp_h = height_kid + vadd; 12387a84e134Smrg } 12397a84e134Smrg else { 12405ec34c4cSmrg y_ins = (short)tmp_h; 12417a84e134Smrg tmp_h += height_kid; 12427a84e134Smrg } 12437a84e134Smrg ++n; 12447a84e134Smrg 12455ec34c4cSmrg XtX(kid) = (Position)(x_ins + hadd); 12467a84e134Smrg XtY(kid) = y_ins; 12477a84e134Smrg XtWidth(kid) = widths[count]; 12487a84e134Smrg } 12497a84e134Smrg 12507a84e134Smrg XtFree((char *)widths); 12517a84e134Smrg 12527a84e134Smrg if (allow_change_size) 12537a84e134Smrg MakeSetValuesRequest((Widget) smw, width, height); 12547a84e134Smrg 12557a84e134Smrg if (smw->simple_menu.label) { 12567a84e134Smrg XtX(smw->simple_menu.label) = 0; 12575ec34c4cSmrg XtY(smw->simple_menu.label) = (Position)smw->simple_menu.top_margin; 12585ec34c4cSmrg XtWidth(smw->simple_menu.label) = (Dimension)(XtWidth(smw) 12597a84e134Smrg#ifndef OLDXAW 12607a84e134Smrg - (smw->simple_menu.left_margin + smw->simple_menu.right_margin) 12617a84e134Smrg#endif 12625ec34c4cSmrg ); 12637a84e134Smrg } 12647a84e134Smrg if (current_entry) { 12657a84e134Smrg if (width_ret) 12667a84e134Smrg *width_ret = XtWidth(current_entry); 12677a84e134Smrg if (height_ret) 12687a84e134Smrg *height_ret = XtHeight(current_entry); 12697a84e134Smrg } 12707a84e134Smrg} 1271421c997bSmrg 12727a84e134Smrg/* 12737a84e134Smrg * Function: 12747a84e134Smrg * AddPositionAction 12757a84e134Smrg * 12767a84e134Smrg * Parameters: 12777a84e134Smrg * app_con - application context 12787a84e134Smrg * data - (not used) 12797a84e134Smrg * 12807a84e134Smrg * Description: 12817a84e134Smrg * Adds the XawPositionSimpleMenu action to the global 12827a84e134Smrg * action list for this appcon. 12837a84e134Smrg */ 12847a84e134Smrg/*ARGSUSED*/ 12857a84e134Smrgstatic void 12865ec34c4cSmrgAddPositionAction(XtAppContext app_con, XPointer data _X_UNUSED) 12877a84e134Smrg{ 12887a84e134Smrg static XtActionsRec pos_action[] = { 12897a84e134Smrg {"XawPositionSimpleMenu", PositionMenuAction}, 12907a84e134Smrg }; 12917a84e134Smrg 12927a84e134Smrg XtAppAddActions(app_con, pos_action, XtNumber(pos_action)); 12937a84e134Smrg} 12947a84e134Smrg 12957a84e134Smrg/* 12967a84e134Smrg * Function: 12977a84e134Smrg * FindMenu 12987a84e134Smrg * 12997a84e134Smrg * Parameters: 13007a84e134Smrg * widget - reference widget 13017a84e134Smrg * name - menu widget's name 13027a84e134Smrg * 13037a84e134Smrg * Description: 13047a84e134Smrg * Find the menu give a name and reference widget 13057a84e134Smrg * 13067a84e134Smrg * Returns: 13077a84e134Smrg * The menu widget or NULL. 13087a84e134Smrg */ 1309421c997bSmrgstatic Widget 13107a84e134SmrgFindMenu(Widget widget, String name) 13117a84e134Smrg{ 1312efbcb2bfSmrg Widget w; 1313421c997bSmrg 1314efbcb2bfSmrg for (w = widget; w != NULL; w = XtParent(w)) { 1315efbcb2bfSmrg Widget menu = XtNameToWidget(w, name); 13167a84e134Smrg 1317efbcb2bfSmrg if (menu != NULL) 1318efbcb2bfSmrg return (menu); 1319efbcb2bfSmrg } 13207a84e134Smrg return (NULL); 13217a84e134Smrg} 13227a84e134Smrg 13237a84e134Smrg/* 13247a84e134Smrg * Function: 13257a84e134Smrg * PositionMenu 13267a84e134Smrg * 13277a84e134Smrg * Parameters: 13287a84e134Smrg * w - simple menu widget 13297a84e134Smrg * location - pointer the the position or NULL 13307a84e134Smrg * 13317a84e134Smrg * Description: 13327a84e134Smrg * Places the menu 13337a84e134Smrg */ 13347a84e134Smrgstatic void 13357a84e134SmrgPositionMenu(Widget w, XPoint *location) 13367a84e134Smrg{ 13377a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 13387a84e134Smrg SmeObject entry; 13397a84e134Smrg XPoint t_point; 1340421c997bSmrg 13417a84e134Smrg if (location == NULL) { 13427a84e134Smrg Window temp1, temp2; 13437a84e134Smrg int root_x, root_y, tempX, tempY; 13447a84e134Smrg unsigned int tempM; 1345421c997bSmrg 13467a84e134Smrg location = &t_point; 13477a84e134Smrg if (XQueryPointer(XtDisplay(w), XtWindow(w), &temp1, &temp2, 13487a84e134Smrg &root_x, &root_y, &tempX, &tempY, &tempM) == False) { 13497a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 13507a84e134Smrg "Xaw Simple Menu Widget: " 13517a84e134Smrg "Could not find location of mouse pointer"); 13527a84e134Smrg return; 13537a84e134Smrg } 13547a84e134Smrg location->x = (short) root_x; 13557a84e134Smrg location->y = (short) root_y; 13567a84e134Smrg } 1357421c997bSmrg 13587a84e134Smrg /* 13597a84e134Smrg * The width will not be correct unless it is realized 13607a84e134Smrg */ 13617a84e134Smrg XtRealizeWidget(w); 1362421c997bSmrg 13635ec34c4cSmrg location->x = (short)(location->x - (XtWidth(w) >> 1)); 1364421c997bSmrg 13657a84e134Smrg if (smw->simple_menu.popup_entry == NULL) 13667a84e134Smrg entry = smw->simple_menu.label; 13677a84e134Smrg else 13687a84e134Smrg entry = smw->simple_menu.popup_entry; 13697a84e134Smrg 13707a84e134Smrg if (entry != NULL) 13715ec34c4cSmrg location->y = (short)(location->y - (XtY(entry) + (XtHeight(entry) >> 1))); 13727a84e134Smrg 13737a84e134Smrg MoveMenu(w, location->x, location->y); 13747a84e134Smrg} 13757a84e134Smrg 13767a84e134Smrg/* 13777a84e134Smrg * Function: 13787a84e134Smrg * MoveMenu 13797a84e134Smrg * 13807a84e134Smrg * Parameters: 13817a84e134Smrg * w - simple menu widget 13827a84e134Smrg * x - current location of the widget 13837a84e134Smrg * y - "" 13847a84e134Smrg * 13857a84e134Smrg * Description: 13867a84e134Smrg * Actually moves the menu, may force it to 13875b16253fSmrg * to be fully visible if menu_on_screen is True. 13887a84e134Smrg */ 13897a84e134Smrgstatic void 13907a84e134SmrgMoveMenu(Widget w, int x, int y) 13917a84e134Smrg{ 13927a84e134Smrg Arg arglist[2]; 13937a84e134Smrg Cardinal num_args = 0; 13947a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 1395421c997bSmrg 13967a84e134Smrg if (smw->simple_menu.menu_on_screen) { 13977a84e134Smrg int width = XtWidth(w) + (XtBorderWidth(w) << 1); 13987a84e134Smrg int height = XtHeight(w) + (XtBorderWidth(w) << 1); 1399421c997bSmrg 14007a84e134Smrg if (x >= 0) { 14017a84e134Smrg int scr_width = WidthOfScreen(XtScreen(w)); 14027a84e134Smrg 14037a84e134Smrg if (x + width > scr_width) 14047a84e134Smrg x = scr_width - width; 14057a84e134Smrg } 1406421c997bSmrg if (x < 0) 14077a84e134Smrg x = 0; 1408421c997bSmrg 14097a84e134Smrg if (y >= 0) { 14107a84e134Smrg int scr_height = HeightOfScreen(XtScreen(w)); 14117a84e134Smrg 14127a84e134Smrg if (y + height > scr_height) 14137a84e134Smrg y = scr_height - height; 14147a84e134Smrg } 14157a84e134Smrg if (y < 0) 14167a84e134Smrg y = 0; 14177a84e134Smrg } 1418421c997bSmrg 14197a84e134Smrg XtSetArg(arglist[num_args], XtNx, x); num_args++; 14207a84e134Smrg XtSetArg(arglist[num_args], XtNy, y); num_args++; 14217a84e134Smrg XtSetValues(w, arglist, num_args); 14227a84e134Smrg} 14237a84e134Smrg 14247a84e134Smrg/* 14257a84e134Smrg * Function: 14267a84e134Smrg * ChangeCursorOnGrab 14277a84e134Smrg * 14287a84e134Smrg * Parameters: 14297a84e134Smrg * w - menu widget 14307a84e134Smrg * temp1 - not used 14317a84e134Smrg * temp2 - "" 14327a84e134Smrg * 14337a84e134Smrg * Description: 14347a84e134Smrg * Changes the cursor on the active grab to the one 14357a84e134Smrg * specified in out resource list. 14367a84e134Smrg */ 14377a84e134Smrg/*ARGSUSED*/ 14387a84e134Smrgstatic void 14395ec34c4cSmrgChangeCursorOnGrab(Widget w, XtPointer temp1 _X_UNUSED, XtPointer temp2 _X_UNUSED) 14407a84e134Smrg{ 14417a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 1442421c997bSmrg 14437a84e134Smrg /* 14447a84e134Smrg * The event mask here is what is currently in the MIT implementation. 14457a84e134Smrg * There really needs to be a way to get the value of the mask out 14467a84e134Smrg * of the toolkit (CDP 5/26/89). 14477a84e134Smrg */ 14487a84e134Smrg XChangeActivePointerGrab(XtDisplay(w), ButtonPressMask | ButtonReleaseMask, 1449421c997bSmrg smw->simple_menu.cursor, 14507a84e134Smrg XtLastTimestampProcessed(XtDisplay(w))); 14517a84e134Smrg} 14527a84e134Smrg 14537a84e134Smrg/* 14547a84e134Smrg * Function: 14557a84e134Smrg * MakeSetValuesRequest 14567a84e134Smrg * 14577a84e134Smrg * Parameters: 14587a84e134Smrg * w - simple menu widget 14597a84e134Smrg * width - size requested 14607a84e134Smrg * height - "" 14617a84e134Smrg */ 14627a84e134Smrgstatic void 14637a84e134SmrgMakeSetValuesRequest(Widget w, unsigned int width, unsigned int height) 14647a84e134Smrg{ 14657a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 1466421c997bSmrg 14677a84e134Smrg if (!smw->simple_menu.recursive_set_values) { 14687a84e134Smrg if (XtWidth(smw) != width || XtHeight(smw) != height) { 1469efbcb2bfSmrg Arg arglist[2]; 1470efbcb2bfSmrg Cardinal num_args = 0; 1471efbcb2bfSmrg 14727a84e134Smrg smw->simple_menu.recursive_set_values = True; 14737a84e134Smrg XtSetArg(arglist[num_args], XtNwidth, width); num_args++; 14747a84e134Smrg XtSetArg(arglist[num_args], XtNheight, height); num_args++; 14757a84e134Smrg XtSetValues(w, arglist, num_args); 14767a84e134Smrg } 14777a84e134Smrg else if (XtIsRealized((Widget)smw)) 14787a84e134Smrg XawSimpleMenuRedisplay((Widget)smw, NULL, NULL); 14797a84e134Smrg } 14807a84e134Smrg smw->simple_menu.recursive_set_values = False; 14817a84e134Smrg} 14827a84e134Smrg 14837a84e134Smrgstatic SmeObject 14847a84e134SmrgDoGetEventEntry(Widget w, int x_loc, int y_loc) 14857a84e134Smrg{ 14867a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 14877a84e134Smrg SmeObject *entry; 14887a84e134Smrg 14897a84e134Smrg ForAllChildren(smw, entry) { 14907a84e134Smrg if (!XtIsManaged((Widget)*entry)) 14917a84e134Smrg continue; 14927a84e134Smrg 14937a84e134Smrg if (x_loc > XtX(*entry) 14947a84e134Smrg && x_loc <= XtX(*entry) + XtWidth(*entry) 14957a84e134Smrg && y_loc > XtY(*entry) 14967a84e134Smrg && y_loc <= XtY(*entry) + XtHeight(*entry)) { 14977a84e134Smrg if (*entry == smw->simple_menu.label) 14987a84e134Smrg return (NULL); /* cannot select the label */ 14997a84e134Smrg else 15007a84e134Smrg return (*entry); 15017a84e134Smrg } 15027a84e134Smrg } 1503421c997bSmrg 15047a84e134Smrg return (NULL); 15057a84e134Smrg} 15067a84e134Smrg 15077a84e134Smrg/* 15087a84e134Smrg * Function: 15097a84e134Smrg * GetEventEntry 15107a84e134Smrg * 15117a84e134Smrg * Parameters: 15127a84e134Smrg * w - simple menu widget 15137a84e134Smrg * event - X event 15147a84e134Smrg * 15157a84e134Smrg * Description: 15167a84e134Smrg * Gets an entry given an event that has X and Y coords. 15177a84e134Smrg * 15187a84e134Smrg * Returns: 15197a84e134Smrg * The entry that this point is in 15207a84e134Smrg */ 15217a84e134Smrgstatic SmeObject 15227a84e134SmrgGetEventEntry(Widget w, XEvent *event) 15237a84e134Smrg{ 15247a84e134Smrg int x_loc, y_loc, x_root; 15257a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 15267a84e134Smrg SmeObject entry; 15277a84e134Smrg int warp, move; 15287a84e134Smrg 15297a84e134Smrg switch (event->type) { 15307a84e134Smrg case MotionNotify: 15317a84e134Smrg x_loc = event->xmotion.x; 15327a84e134Smrg y_loc = event->xmotion.y; 15337a84e134Smrg x_root = event->xmotion.x_root; 15347a84e134Smrg break; 15357a84e134Smrg case EnterNotify: 15367a84e134Smrg case LeaveNotify: 15377a84e134Smrg x_loc = event->xcrossing.x; 15387a84e134Smrg y_loc = event->xcrossing.y; 15397a84e134Smrg x_root = event->xcrossing.x_root; 15407a84e134Smrg break; 15417a84e134Smrg case ButtonPress: 15427a84e134Smrg case ButtonRelease: 15437a84e134Smrg x_loc = event->xbutton.x; 15447a84e134Smrg y_loc = event->xbutton.y; 15457a84e134Smrg x_root = event->xbutton.x_root; 15467a84e134Smrg break; 15477a84e134Smrg default: 15487a84e134Smrg XtAppError(XtWidgetToApplicationContext(w), 15497a84e134Smrg "Unknown event type in GetEventEntry()."); 15507a84e134Smrg return (NULL); 15517a84e134Smrg } 1552421c997bSmrg 15537a84e134Smrg if (x_loc < 0 || x_loc >= XtWidth(smw) || 15547a84e134Smrg y_loc < 0 || y_loc >= XtHeight(smw)) 15557a84e134Smrg return (NULL); 15567a84e134Smrg 15577a84e134Smrg /* Move the menu if it's outside the screen, does not check 15587a84e134Smrg * smw->simple_menu.menu_on_screen because menus is bigger than screen 15597a84e134Smrg */ 15607a84e134Smrg if (x_root == WidthOfScreen(XtScreen(w)) - 1 && 15617a84e134Smrg XtX(w) + XtWidth(w) + (XtBorderWidth(w)) > x_root) { 15627a84e134Smrg if (smw->simple_menu.entry_set) { 15637a84e134Smrg entry = DoGetEventEntry(w, 15647a84e134Smrg XtX(smw->simple_menu.entry_set) 15657a84e134Smrg + XtWidth(smw->simple_menu.entry_set) + 1, 15667a84e134Smrg y_loc); 15677a84e134Smrg Unhighlight(w, event, NULL, NULL); 15687a84e134Smrg if (entry) { 15697a84e134Smrg warp = -(int)XtWidth(entry) >> 1; 15707a84e134Smrg move = x_loc - XtWidth(entry) - XtX(entry) + XtBorderWidth(w); 15717a84e134Smrg } 15727a84e134Smrg else { 15737a84e134Smrg warp = 0; 15747a84e134Smrg move = WidthOfScreen(XtScreen(w)) - 15757a84e134Smrg (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); 15767a84e134Smrg } 15777a84e134Smrg } 15787a84e134Smrg else { 15797a84e134Smrg warp = 0; 15807a84e134Smrg move = WidthOfScreen(XtScreen(w)) - 15817a84e134Smrg (XtX(w) + XtWidth(w) + (XtBorderWidth(w) << 1)); 15827a84e134Smrg } 15837a84e134Smrg } 15847a84e134Smrg else if (x_root == 0 && XtX(w) < 0) { 15857a84e134Smrg warp = 8; 15867a84e134Smrg if (smw->simple_menu.entry_set) { 15877a84e134Smrg entry = DoGetEventEntry(w, XtX(smw->simple_menu.entry_set) - 1, 15887a84e134Smrg y_loc); 15897a84e134Smrg Unhighlight(w, event, NULL, NULL); 15907a84e134Smrg if (entry) { 15917a84e134Smrg warp = XtWidth(entry) >> 1; 15927a84e134Smrg move = x_loc - XtX(entry); 15937a84e134Smrg } 15947a84e134Smrg else 15957a84e134Smrg move = x_loc + XtBorderWidth(w); 15967a84e134Smrg } 15977a84e134Smrg else 15987a84e134Smrg move = x_loc + XtBorderWidth(w); 15997a84e134Smrg } 16007a84e134Smrg else 16017a84e134Smrg move = warp = 0; 16027a84e134Smrg 16037a84e134Smrg if (move) 16045ec34c4cSmrg XtMoveWidget(w, (Position)(XtX(w) + move), XtY(w)); 16057a84e134Smrg if (warp) 16067a84e134Smrg XWarpPointer(XtDisplay(w), None, None, 0, 0, 0, 0, warp, 0); 16077a84e134Smrg 16087a84e134Smrg return (DoGetEventEntry(w, x_loc, y_loc)); 16097a84e134Smrg} 16107a84e134Smrg 16117a84e134Smrgstatic void 16127a84e134SmrgCalculateNewSize(Widget w, Dimension *width_return, Dimension *height_return) 16137a84e134Smrg{ 16147a84e134Smrg SimpleMenuWidget xaw = (SimpleMenuWidget)w; 16157a84e134Smrg Widget kid; 16167a84e134Smrg Cardinal i; 16177a84e134Smrg int width_kid, height_kid; 16187a84e134Smrg int width, height, tmp_w, tmp_h, max_dim; 16197a84e134Smrg short vadd, hadd; 16207a84e134Smrg int n, columns, test_h, num_children = 0; 16217a84e134Smrg Boolean try_layout = False; 16227a84e134Smrg 16237a84e134Smrg#ifndef OLDXAW 16245ec34c4cSmrg hadd = (short)(xaw->simple_menu.left_margin + xaw->simple_menu.right_margin); 16257a84e134Smrg#else 16267a84e134Smrg hadd = 0; 16277a84e134Smrg#endif 16285ec34c4cSmrg vadd = (short)(xaw->simple_menu.top_margin + xaw->simple_menu.bottom_margin); 16297a84e134Smrg if (xaw->simple_menu.label) 16305ec34c4cSmrg vadd = (short)(vadd + XtHeight(xaw->simple_menu.label)); 16317a84e134Smrg 16327a84e134Smrg if (*height_return) 16337a84e134Smrg max_dim = *height_return; 16347a84e134Smrg else if (!XtHeight(w)) { 16357a84e134Smrg max_dim = HeightOfScreen(XtScreen(w)); 16367a84e134Smrg try_layout = True; 16377a84e134Smrg } 16387a84e134Smrg else 16397a84e134Smrg max_dim = XtHeight(w); 16407a84e134Smrg max_dim -= vadd; 16417a84e134Smrg 16427a84e134Smrg width = height = tmp_w = tmp_h = n = test_h = 0; 16437a84e134Smrg columns = 1; 16447a84e134Smrg for (i = xaw->simple_menu.label ? 1 : 0; 16457a84e134Smrg i < xaw->composite.num_children; 16467a84e134Smrg i++) { 16477a84e134Smrg kid = xaw->composite.children[i]; 16487a84e134Smrg if (!XtIsManaged(kid)) 16497a84e134Smrg continue; 16507a84e134Smrg ++num_children; 16517a84e134Smrg width_kid = XtWidth(kid); 16527a84e134Smrg height_kid = XtHeight(kid); 16537a84e134Smrg 16547a84e134Smrg if (try_layout) { 16557a84e134Smrg if (!test_h) 16567a84e134Smrg test_h = height_kid; 16577a84e134Smrg else if (test_h != height_kid) 16587a84e134Smrg try_layout = False; 16597a84e134Smrg } 16607a84e134Smrg 16617a84e134Smrg if (n && (height + height_kid > max_dim)) { 16627a84e134Smrg ++columns; 16637a84e134Smrg width += tmp_w; 16647a84e134Smrg tmp_w = width_kid; 16657a84e134Smrg height = height_kid; 16667a84e134Smrg } 16677a84e134Smrg else 16687a84e134Smrg height += height_kid; 16697a84e134Smrg if (height > tmp_h) 16707a84e134Smrg tmp_h = height; 16717a84e134Smrg if (width_kid > tmp_w) 16727a84e134Smrg tmp_w = width_kid; 16737a84e134Smrg ++n; 16747a84e134Smrg } 16757a84e134Smrg 16767a84e134Smrg height = tmp_h + vadd; 16777a84e134Smrg width += tmp_w + hadd; 16787a84e134Smrg 16797a84e134Smrg if (xaw->simple_menu.label) 16807a84e134Smrg width = XawMax(width, XtWidth(xaw->simple_menu.label) + hadd); 16817a84e134Smrg 16825ec34c4cSmrg *width_return = (Dimension)width; 16835ec34c4cSmrg *height_return = (Dimension)height; 16847a84e134Smrg 16857a84e134Smrg if (try_layout && columns > 1 && num_children > 2) { 16867a84e134Smrg int space; 16877a84e134Smrg 16887a84e134Smrg height = test_h * (xaw->simple_menu.label ? 16897a84e134Smrg num_children - 1 : 16907a84e134Smrg num_children); 16917a84e134Smrg 16927a84e134Smrg max_dim -= max_dim % test_h; 16937a84e134Smrg space = max_dim - (height % max_dim); 16947a84e134Smrg if (space >= test_h * columns) { 16957a84e134Smrg height = max_dim - space / columns; 16967a84e134Smrg if (height % test_h) 16977a84e134Smrg height += test_h - (height % test_h); 16985ec34c4cSmrg *height_return = (Dimension)(height + vadd); 16997a84e134Smrg CalculateNewSize(w, width_return, height_return); 17007a84e134Smrg } 17017a84e134Smrg } 17027a84e134Smrg} 17037a84e134Smrg 17047a84e134Smrgstatic void 17057a84e134SmrgMakeResizeRequest(Widget w) 17067a84e134Smrg{ 17077a84e134Smrg int tries; 17087a84e134Smrg Dimension width, height; 1709421c997bSmrg 17107a84e134Smrg width = XtWidth(w); 17117a84e134Smrg height = XtHeight(w); 17127a84e134Smrg 17137a84e134Smrg for (tries = 0; tries < 100; tries++) { 17147a84e134Smrg CalculateNewSize(w, &width, &height); 17157a84e134Smrg if (width == XtWidth(w) && height == XtHeight(w)) 17167a84e134Smrg break; 17177a84e134Smrg if (XtMakeResizeRequest(w, width, height, &width, &height) == 17187a84e134Smrg XtGeometryNo) 17197a84e134Smrg break; 17207a84e134Smrg } 17217a84e134Smrg} 17227a84e134Smrg 17237a84e134Smrg#ifndef OLDXAW 17247a84e134Smrgstatic void 17257a84e134SmrgPopdown(Widget w, XEvent *event, String *params, Cardinal *num_params) 17267a84e134Smrg{ 17277a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 17287a84e134Smrg 17297a84e134Smrg while (XtParent(w) && 17307a84e134Smrg XtIsSubclass(XtParent(w), simpleMenuWidgetClass)) { 17317a84e134Smrg if (((SimpleMenuWidget)XtParent(w))->simple_menu.sub_menu == (Widget)w) { 17327a84e134Smrg w = XtParent(w); 17337a84e134Smrg smw = (SimpleMenuWidget)w; 17347a84e134Smrg smw->simple_menu.entry_set = NULL; 17357a84e134Smrg } 17367a84e134Smrg else 17377a84e134Smrg break; 17387a84e134Smrg } 17397a84e134Smrg 17407a84e134Smrg smw->simple_menu.state |= SMW_UNMAPPING; 17417a84e134Smrg if (smw->simple_menu.sub_menu) 17427a84e134Smrg PopdownSubMenu(smw); 17437a84e134Smrg XtCallActionProc(w, "XtMenuPopdown", event, params, *num_params); 17447a84e134Smrg} 17457a84e134Smrg 17467a84e134Smrgstatic void 17477a84e134SmrgPopupSubMenu(SimpleMenuWidget smw) 17487a84e134Smrg{ 17497a84e134Smrg Arg args[2]; 17507a84e134Smrg Cardinal num_args; 17517a84e134Smrg Widget menu; 17527a84e134Smrg SmeBSBObject entry = (SmeBSBObject)smw->simple_menu.entry_set; 17537a84e134Smrg Position menu_x, menu_y; 17547a84e134Smrg Bool popleft; 17557a84e134Smrg 17567a84e134Smrg if (entry->sme_bsb.menu_name == NULL) 17577a84e134Smrg return; 17587a84e134Smrg 17597a84e134Smrg if ((menu = FindMenu((Widget)smw, entry->sme_bsb.menu_name)) == NULL) 17607a84e134Smrg return; 17617a84e134Smrg 17627a84e134Smrg smw->simple_menu.sub_menu = menu; 17637a84e134Smrg 17647a84e134Smrg if (!XtIsRealized(menu)) 17657a84e134Smrg XtRealizeWidget(menu); 17667a84e134Smrg 17677a84e134Smrg popleft = (smw->simple_menu.state & SMW_POPLEFT) != 0; 17687a84e134Smrg 1769421c997bSmrg if (popleft) 17705ec34c4cSmrg XtTranslateCoords((Widget)smw, 17715ec34c4cSmrg (Position)(-(int)XtWidth(menu)), 17725ec34c4cSmrg (Position)(XtY(entry) - XtBorderWidth(menu)), 17735ec34c4cSmrg &menu_x, &menu_y); 17747a84e134Smrg else 17755ec34c4cSmrg XtTranslateCoords((Widget)smw, 17765ec34c4cSmrg (Position)XtWidth(smw), 17775ec34c4cSmrg (Position)(XtY(entry) - XtBorderWidth(menu)), 17785ec34c4cSmrg &menu_x, &menu_y); 17797a84e134Smrg 17807a84e134Smrg if (!popleft && menu_x >= 0) { 17817a84e134Smrg int scr_width = WidthOfScreen(XtScreen(menu)); 17827a84e134Smrg 17837a84e134Smrg if (menu_x + XtWidth(menu) > scr_width) { 17845ec34c4cSmrg menu_x = (Position)(menu_x - (XtWidth(menu) + XtWidth(smw))); 17857a84e134Smrg popleft = True; 17867a84e134Smrg } 17877a84e134Smrg } 17887a84e134Smrg else if (popleft && menu_x < 0) { 17897a84e134Smrg menu_x = 0; 17907a84e134Smrg popleft = False; 17917a84e134Smrg } 17927a84e134Smrg if (menu_y >= 0) { 17937a84e134Smrg int scr_height = HeightOfScreen(XtScreen(menu)); 17947a84e134Smrg 17957a84e134Smrg if (menu_y + XtHeight(menu) > scr_height) 17965ec34c4cSmrg menu_y = (Position)(scr_height - XtHeight(menu) - XtBorderWidth(menu)); 17977a84e134Smrg } 17987a84e134Smrg if (menu_y < 0) 17997a84e134Smrg menu_y = 0; 18007a84e134Smrg 18017a84e134Smrg num_args = 0; 18027a84e134Smrg XtSetArg(args[num_args], XtNx, menu_x); num_args++; 18037a84e134Smrg XtSetArg(args[num_args], XtNy, menu_y); num_args++; 18047a84e134Smrg XtSetValues(menu, args, num_args); 18057a84e134Smrg 18067a84e134Smrg if (popleft) 18077a84e134Smrg ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT; 18087a84e134Smrg else 18095ec34c4cSmrg ((SimpleMenuWidget)menu)->simple_menu.state &= (unsigned char)(~SMW_POPLEFT); 18107a84e134Smrg 18117a84e134Smrg XtPopup(menu, XtGrabNone); 18127a84e134Smrg} 18137a84e134Smrg 18147a84e134Smrgstatic void 18157a84e134SmrgPopdownSubMenu(SimpleMenuWidget smw) 18167a84e134Smrg{ 18177a84e134Smrg SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu; 18187a84e134Smrg 18197a84e134Smrg if (!menu) 18207a84e134Smrg return; 18217a84e134Smrg 18227a84e134Smrg menu->simple_menu.state |= SMW_UNMAPPING; 18237a84e134Smrg PopdownSubMenu(menu); 18247a84e134Smrg 18257a84e134Smrg XtPopdown((Widget)menu); 18267a84e134Smrg 18277a84e134Smrg smw->simple_menu.sub_menu = NULL; 18287a84e134Smrg} 18297a84e134Smrg 18307a84e134Smrg/*ARGSUSED*/ 18317a84e134Smrgstatic void 18325ec34c4cSmrgPopupCB(Widget w, XtPointer client_data _X_UNUSED, XtPointer call_data _X_UNUSED) 18337a84e134Smrg{ 18347a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 18357a84e134Smrg 18365ec34c4cSmrg smw->simple_menu.state &= (unsigned char)(~(SMW_UNMAPPING | SMW_POPLEFT)); 18377a84e134Smrg} 18387a84e134Smrg#endif /* OLDXAW */ 1839