SimpleMenu.c revision 7a84e134
17a84e134Smrg/* $Xorg: SimpleMenu.c,v 1.4 2001/02/09 02:03:45 xorgcvs Exp $ */ 27a84e134Smrg 37a84e134Smrg/* 47a84e134SmrgCopyright 1989, 1994, 1998 The Open Group 57a84e134Smrg 67a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its 77a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that 87a84e134Smrgthe above copyright notice appear in all copies and that both that 97a84e134Smrgcopyright notice and this permission notice appear in supporting 107a84e134Smrgdocumentation. 117a84e134Smrg 127a84e134SmrgThe above copyright notice and this permission notice shall be included in 137a84e134Smrgall copies or substantial portions of the Software. 147a84e134Smrg 157a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 187a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 197a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 207a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 217a84e134Smrg 227a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be 237a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings 247a84e134Smrgin this Software without prior written authorization from The Open Group. 257a84e134Smrg */ 267a84e134Smrg 277a84e134Smrg/* $XFree86: xc/lib/Xaw/SimpleMenu.c,v 3.21 2001/03/23 23:59:15 paulo Exp $ */ 287a84e134Smrg 297a84e134Smrg/* 307a84e134Smrg * SimpleMenu.c - Source code file for SimpleMenu widget. 317a84e134Smrg * 327a84e134Smrg * Date: April 3, 1989 337a84e134Smrg * 347a84e134Smrg * By: Chris D. Peterson 357a84e134Smrg * MIT X Consortium 367a84e134Smrg * kit@expo.lcs.mit.edu 377a84e134Smrg */ 387a84e134Smrg 397a84e134Smrg#ifdef HAVE_CONFIG_H 407a84e134Smrg#include <config.h> 417a84e134Smrg#endif 427a84e134Smrg#include <stdio.h> 437a84e134Smrg#include <X11/IntrinsicP.h> 447a84e134Smrg#include <X11/StringDefs.h> 457a84e134Smrg#include <X11/Xmu/Initer.h> 467a84e134Smrg#include <X11/Xmu/SysUtil.h> 477a84e134Smrg#include <X11/Xaw/Cardinals.h> 487a84e134Smrg#include <X11/Xaw/SimpleMenP.h> 497a84e134Smrg#include <X11/Xaw/SmeBSBP.h> 507a84e134Smrg#include <X11/Xaw/XawInit.h> 517a84e134Smrg#include "Private.h" 527a84e134Smrg 537a84e134Smrg#define streq(a, b) (strcmp((a), (b)) == 0) 547a84e134Smrg 557a84e134Smrg#define ForAllChildren(smw, childP) \ 567a84e134Smrgfor ((childP) = (SmeObject *)(smw)->composite.children; \ 577a84e134Smrg (childP) < (SmeObject *)((smw)->composite.children \ 587a84e134Smrg + (smw)->composite.num_children); \ 597a84e134Smrg (childP)++) 607a84e134Smrg 617a84e134Smrg#ifndef OLDXAW 627a84e134Smrg#define SMW_UNMAPPING 0x01 637a84e134Smrg#define SMW_POPLEFT 0x02 647a84e134Smrg#endif 657a84e134Smrg 667a84e134Smrg/* 677a84e134Smrg * Class Methods 687a84e134Smrg */ 697a84e134Smrgstatic void XawSimpleMenuChangeManaged(Widget); 707a84e134Smrgstatic void XawSimpleMenuClassInitialize(void); 717a84e134Smrgstatic void XawSimpleMenuClassPartInitialize(WidgetClass); 727a84e134Smrgstatic XtGeometryResult XawSimpleMenuGeometryManager(Widget, XtWidgetGeometry*, 737a84e134Smrg XtWidgetGeometry*); 747a84e134Smrgstatic void XawSimpleMenuInitialize(Widget, Widget, ArgList, Cardinal*); 757a84e134Smrgstatic void XawSimpleMenuRealize(Widget, XtValueMask*, XSetWindowAttributes*); 767a84e134Smrgstatic void XawSimpleMenuRedisplay(Widget, XEvent*, Region); 777a84e134Smrgstatic void XawSimpleMenuResize(Widget); 787a84e134Smrgstatic Boolean XawSimpleMenuSetValues(Widget, Widget, Widget, 797a84e134Smrg ArgList, Cardinal*); 807a84e134Smrgstatic Boolean XawSimpleMenuSetValuesHook(Widget, ArgList, Cardinal*); 817a84e134Smrg#ifndef OLDXAW 827a84e134Smrgstatic void PopupSubMenu(SimpleMenuWidget); 837a84e134Smrgstatic void PopdownSubMenu(SimpleMenuWidget); 847a84e134Smrgstatic void PopupCB(Widget, XtPointer, XtPointer); 857a84e134Smrg#endif 867a84e134Smrg 877a84e134Smrg/* 887a84e134Smrg * Prototypes 897a84e134Smrg */ 907a84e134Smrgstatic void AddPositionAction(XtAppContext, XPointer); 917a84e134Smrgstatic void CalculateNewSize(Widget, Dimension*, Dimension*); 927a84e134Smrgstatic void ChangeCursorOnGrab(Widget, XtPointer, XtPointer); 937a84e134Smrgstatic void CreateLabel(Widget); 947a84e134Smrgstatic SmeObject DoGetEventEntry(Widget, int, int); 957a84e134Smrgstatic Widget FindMenu(Widget, String); 967a84e134Smrgstatic SmeObject GetEventEntry(Widget, XEvent*); 977a84e134Smrgstatic void Layout(Widget, Dimension*, Dimension*); 987a84e134Smrgstatic void MakeResizeRequest(Widget); 997a84e134Smrgstatic void MakeSetValuesRequest(Widget, unsigned int, unsigned int); 1007a84e134Smrgstatic void MoveMenu(Widget, int, int); 1017a84e134Smrgstatic void PositionMenu(Widget, XPoint*); 1027a84e134Smrg 1037a84e134Smrg/* 1047a84e134Smrg * Actions 1057a84e134Smrg */ 1067a84e134Smrgstatic void Highlight(Widget, XEvent*, String*, Cardinal*); 1077a84e134Smrgstatic void Notify(Widget, XEvent*, String*, Cardinal*); 1087a84e134Smrg#ifndef OLDXAW 1097a84e134Smrgstatic void Popdown(Widget, XEvent*, String*, Cardinal*); 1107a84e134Smrg#endif 1117a84e134Smrgstatic void PositionMenuAction(Widget, XEvent*, String*, Cardinal*); 1127a84e134Smrgstatic void Unhighlight(Widget, XEvent*, String*, Cardinal*); 1137a84e134Smrg 1147a84e134Smrg/* 1157a84e134Smrg * Initialization 1167a84e134Smrg */ 1177a84e134Smrg#define offset(field) XtOffsetOf(SimpleMenuRec, simple_menu.field) 1187a84e134Smrg 1197a84e134Smrgstatic XtResource resources[] = { 1207a84e134Smrg /* label */ 1217a84e134Smrg { 1227a84e134Smrg XtNlabel, 1237a84e134Smrg XtCLabel, 1247a84e134Smrg XtRString, 1257a84e134Smrg sizeof(String), 1267a84e134Smrg offset(label_string), 1277a84e134Smrg XtRString, 1287a84e134Smrg NULL 1297a84e134Smrg }, 1307a84e134Smrg { 1317a84e134Smrg XtNlabelClass, 1327a84e134Smrg XtCLabelClass, 1337a84e134Smrg XtRPointer, 1347a84e134Smrg sizeof(WidgetClass), 1357a84e134Smrg offset(label_class), 1367a84e134Smrg XtRImmediate, 1377a84e134Smrg NULL 1387a84e134Smrg }, 1397a84e134Smrg 1407a84e134Smrg /* layout */ 1417a84e134Smrg { 1427a84e134Smrg XtNrowHeight, 1437a84e134Smrg XtCRowHeight, 1447a84e134Smrg XtRDimension, 1457a84e134Smrg sizeof(Dimension), 1467a84e134Smrg offset(row_height), 1477a84e134Smrg XtRImmediate, 1487a84e134Smrg (XtPointer)0 1497a84e134Smrg }, 1507a84e134Smrg { 1517a84e134Smrg XtNtopMargin, 1527a84e134Smrg XtCVerticalMargins, 1537a84e134Smrg XtRDimension, 1547a84e134Smrg sizeof(Dimension), 1557a84e134Smrg offset(top_margin), 1567a84e134Smrg XtRImmediate, 1577a84e134Smrg (XtPointer)0 1587a84e134Smrg }, 1597a84e134Smrg { 1607a84e134Smrg XtNbottomMargin, 1617a84e134Smrg XtCVerticalMargins, 1627a84e134Smrg XtRDimension, 1637a84e134Smrg sizeof(Dimension), 1647a84e134Smrg offset(bottom_margin), 1657a84e134Smrg XtRImmediate, 1667a84e134Smrg (XtPointer)0 1677a84e134Smrg }, 1687a84e134Smrg#ifndef OLDXAW 1697a84e134Smrg { 1707a84e134Smrg XtNleftMargin, 1717a84e134Smrg XtCHorizontalMargins, 1727a84e134Smrg XtRDimension, 1737a84e134Smrg sizeof(Dimension), 1747a84e134Smrg offset(left_margin), 1757a84e134Smrg XtRImmediate, 1767a84e134Smrg (XtPointer)0 1777a84e134Smrg }, 1787a84e134Smrg { 1797a84e134Smrg XtNrightMargin, 1807a84e134Smrg XtCHorizontalMargins, 1817a84e134Smrg XtRDimension, 1827a84e134Smrg sizeof(Dimension), 1837a84e134Smrg offset(right_margin), 1847a84e134Smrg XtRImmediate, 1857a84e134Smrg (XtPointer)0 1867a84e134Smrg }, 1877a84e134Smrg#endif 1887a84e134Smrg 1897a84e134Smrg /* misc */ 1907a84e134Smrg { 1917a84e134Smrg XtNallowShellResize, 1927a84e134Smrg XtCAllowShellResize, 1937a84e134Smrg XtRBoolean, 1947a84e134Smrg sizeof(Boolean), 1957a84e134Smrg XtOffsetOf(SimpleMenuRec, shell.allow_shell_resize), 1967a84e134Smrg XtRImmediate, 1977a84e134Smrg (XtPointer)True 1987a84e134Smrg }, 1997a84e134Smrg { 2007a84e134Smrg XtNcursor, 2017a84e134Smrg XtCCursor, 2027a84e134Smrg XtRCursor, 2037a84e134Smrg sizeof(Cursor), 2047a84e134Smrg offset(cursor), 2057a84e134Smrg XtRImmediate, 2067a84e134Smrg (XtPointer)None 2077a84e134Smrg }, 2087a84e134Smrg { 2097a84e134Smrg XtNmenuOnScreen, 2107a84e134Smrg XtCMenuOnScreen, 2117a84e134Smrg XtRBoolean, 2127a84e134Smrg sizeof(Boolean), 2137a84e134Smrg offset(menu_on_screen), 2147a84e134Smrg XtRImmediate, 2157a84e134Smrg (XtPointer)True 2167a84e134Smrg }, 2177a84e134Smrg { 2187a84e134Smrg XtNpopupOnEntry, 2197a84e134Smrg XtCPopupOnEntry, 2207a84e134Smrg XtRWidget, 2217a84e134Smrg sizeof(Widget), 2227a84e134Smrg offset(popup_entry), 2237a84e134Smrg XtRWidget, 2247a84e134Smrg NULL 2257a84e134Smrg }, 2267a84e134Smrg { 2277a84e134Smrg XtNbackingStore, 2287a84e134Smrg XtCBackingStore, 2297a84e134Smrg XtRBackingStore, 2307a84e134Smrg sizeof(int), 2317a84e134Smrg offset(backing_store), 2327a84e134Smrg XtRImmediate, 2337a84e134Smrg (XtPointer)(Always + WhenMapped + NotUseful) 2347a84e134Smrg }, 2357a84e134Smrg#ifndef OLDXAW 2367a84e134Smrg { 2377a84e134Smrg XawNdisplayList, 2387a84e134Smrg XawCDisplayList, 2397a84e134Smrg XawRDisplayList, 2407a84e134Smrg sizeof(XawDisplayList*), 2417a84e134Smrg offset(display_list), 2427a84e134Smrg XtRImmediate, 2437a84e134Smrg NULL 2447a84e134Smrg }, 2457a84e134Smrg#endif 2467a84e134Smrg}; 2477a84e134Smrg#undef offset 2487a84e134Smrg 2497a84e134Smrgstatic char defaultTranslations[] = 2507a84e134Smrg"<Enter>:" "highlight()\n" 2517a84e134Smrg"<Leave>:" "unhighlight()\n" 2527a84e134Smrg"<BtnMotion>:" "highlight()\n" 2537a84e134Smrg#ifndef OLDXAW 2547a84e134Smrg"<BtnUp>:" "popdown() notify() unhighlight()\n" 2557a84e134Smrg#else 2567a84e134Smrg"<BtnUp>:" "MenuPopdown() notify() unhighlight()\n" 2577a84e134Smrg#endif 2587a84e134Smrg; 2597a84e134Smrg 2607a84e134Smrgstatic XtActionsRec actionsList[] = 2617a84e134Smrg{ 2627a84e134Smrg {"notify", Notify}, 2637a84e134Smrg {"highlight", Highlight}, 2647a84e134Smrg {"unhighlight", Unhighlight}, 2657a84e134Smrg#ifndef OLDXAW 2667a84e134Smrg {"popdown", Popdown}, 2677a84e134Smrg {"set-values", XawSetValuesAction}, 2687a84e134Smrg {"get-values", XawGetValuesAction}, 2697a84e134Smrg {"declare", XawDeclareAction}, 2707a84e134Smrg {"call-proc", XawCallProcAction}, 2717a84e134Smrg#endif 2727a84e134Smrg}; 2737a84e134Smrg 2747a84e134Smrgstatic CompositeClassExtensionRec extension_rec = { 2757a84e134Smrg NULL, /* next_extension */ 2767a84e134Smrg NULLQUARK, /* record_type */ 2777a84e134Smrg XtCompositeExtensionVersion, /* version */ 2787a84e134Smrg sizeof(CompositeClassExtensionRec), /* record_size */ 2797a84e134Smrg True, /* accepts_objects */ 2807a84e134Smrg}; 2817a84e134Smrg 2827a84e134Smrg#define Superclass (&overrideShellClassRec) 2837a84e134SmrgSimpleMenuClassRec simpleMenuClassRec = { 2847a84e134Smrg /* core */ 2857a84e134Smrg { 2867a84e134Smrg (WidgetClass)Superclass, /* superclass */ 2877a84e134Smrg "SimpleMenu", /* class_name */ 2887a84e134Smrg sizeof(SimpleMenuRec), /* size */ 2897a84e134Smrg XawSimpleMenuClassInitialize, /* class_initialize */ 2907a84e134Smrg XawSimpleMenuClassPartInitialize, /* class_part_initialize */ 2917a84e134Smrg False, /* class_inited */ 2927a84e134Smrg XawSimpleMenuInitialize, /* initialize */ 2937a84e134Smrg NULL, /* initialize_hook */ 2947a84e134Smrg XawSimpleMenuRealize, /* realize */ 2957a84e134Smrg actionsList, /* actions */ 2967a84e134Smrg XtNumber(actionsList), /* num_actions */ 2977a84e134Smrg resources, /* resources */ 2987a84e134Smrg XtNumber(resources), /* num_resources */ 2997a84e134Smrg NULLQUARK, /* xrm_class */ 3007a84e134Smrg True, /* compress_motion */ 3017a84e134Smrg True, /* compress_exposure */ 3027a84e134Smrg True, /* compress_enterleave */ 3037a84e134Smrg False, /* visible_interest */ 3047a84e134Smrg NULL, /* destroy */ 3057a84e134Smrg XawSimpleMenuResize, /* resize */ 3067a84e134Smrg XawSimpleMenuRedisplay, /* expose */ 3077a84e134Smrg XawSimpleMenuSetValues, /* set_values */ 3087a84e134Smrg XawSimpleMenuSetValuesHook, /* set_values_hook */ 3097a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 3107a84e134Smrg NULL, /* get_values_hook */ 3117a84e134Smrg NULL, /* accept_focus */ 3127a84e134Smrg XtVersion, /* intrinsics version */ 3137a84e134Smrg NULL, /* callback offsets */ 3147a84e134Smrg defaultTranslations, /* tm_table */ 3157a84e134Smrg NULL, /* query_geometry */ 3167a84e134Smrg NULL, /* display_accelerator */ 3177a84e134Smrg NULL, /* extension */ 3187a84e134Smrg }, 3197a84e134Smrg /* composite */ 3207a84e134Smrg { 3217a84e134Smrg XawSimpleMenuGeometryManager, /* geometry_manager */ 3227a84e134Smrg XawSimpleMenuChangeManaged, /* change_managed */ 3237a84e134Smrg XtInheritInsertChild, /* insert_child */ 3247a84e134Smrg XtInheritDeleteChild, /* delete_child */ 3257a84e134Smrg NULL, /* extension */ 3267a84e134Smrg }, 3277a84e134Smrg /* shell */ 3287a84e134Smrg { 3297a84e134Smrg NULL, /* extension */ 3307a84e134Smrg }, 3317a84e134Smrg /* override */ 3327a84e134Smrg { 3337a84e134Smrg NULL, /* extension */ 3347a84e134Smrg }, 3357a84e134Smrg /* simple_menu */ 3367a84e134Smrg { 3377a84e134Smrg NULL, /* extension */ 3387a84e134Smrg }, 3397a84e134Smrg}; 3407a84e134Smrg 3417a84e134SmrgWidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec; 3427a84e134Smrg 3437a84e134Smrg/* 3447a84e134Smrg * Implementation 3457a84e134Smrg */ 3467a84e134Smrg/* 3477a84e134Smrg * Function: 3487a84e134Smrg * XawSimpleMenuClassInitialize 3497a84e134Smrg * 3507a84e134Smrg * Description: 3517a84e134Smrg * Class Initialize routine, called only once. 3527a84e134Smrg */ 3537a84e134Smrgstatic void 3547a84e134SmrgXawSimpleMenuClassInitialize(void) 3557a84e134Smrg{ 3567a84e134Smrg XawInitializeWidgetSet(); 3577a84e134Smrg XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, 3587a84e134Smrg NULL, 0); 3597a84e134Smrg XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString, 3607a84e134Smrg NULL, 0, XtCacheNone, NULL); 3617a84e134Smrg XmuAddInitializer(AddPositionAction, NULL); 3627a84e134Smrg} 3637a84e134Smrg 3647a84e134Smrg/* 3657a84e134Smrg * Function: 3667a84e134Smrg * XawSimpleMenuClassPartInitialize 3677a84e134Smrg * Arguments: wc - the widget class of the subclass. 3687a84e134Smrg * 3697a84e134Smrg * Description: 3707a84e134Smrg * Class Part Initialize routine, called for every subclass. Makes 3717a84e134Smrg * sure that the subclasses pick up the extension record. 3727a84e134Smrg */ 3737a84e134Smrgstatic void 3747a84e134SmrgXawSimpleMenuClassPartInitialize(WidgetClass wc) 3757a84e134Smrg{ 3767a84e134Smrg SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass)wc; 3777a84e134Smrg 3787a84e134Smrg /* 3797a84e134Smrg * Make sure that our subclass gets the extension rec too 3807a84e134Smrg */ 3817a84e134Smrg extension_rec.next_extension = smwc->composite_class.extension; 3827a84e134Smrg smwc->composite_class.extension = (XtPointer) &extension_rec; 3837a84e134Smrg} 3847a84e134Smrg 3857a84e134Smrg/* 3867a84e134Smrg * Function: 3877a84e134Smrg * XawSimpleMenuInitialize 3887a84e134Smrg * 3897a84e134Smrg * Parameters: 3907a84e134Smrg * request - widget requested by the argument list 3917a84e134Smrg * cnew - new widget with both resource and non resource values 3927a84e134Smrg * 3937a84e134Smrg * Description: 3947a84e134Smrg * Initializes the simple menu widget. 3957a84e134Smrg */ 3967a84e134Smrg/*ARGSUSED*/ 3977a84e134Smrgstatic void 3987a84e134SmrgXawSimpleMenuInitialize(Widget request, Widget cnew, 3997a84e134Smrg ArgList args, Cardinal *num_args) 4007a84e134Smrg{ 4017a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)cnew; 4027a84e134Smrg Dimension width, height; 4037a84e134Smrg 4047a84e134Smrg XmuCallInitializers(XtWidgetToApplicationContext(cnew)); 4057a84e134Smrg 4067a84e134Smrg if (smw->simple_menu.label_class == NULL) 4077a84e134Smrg smw->simple_menu.label_class = smeBSBObjectClass; 4087a84e134Smrg 4097a84e134Smrg smw->simple_menu.label = NULL; 4107a84e134Smrg smw->simple_menu.entry_set = NULL; 4117a84e134Smrg smw->simple_menu.recursive_set_values = False; 4127a84e134Smrg#ifndef OLDXAW 4137a84e134Smrg smw->simple_menu.sub_menu = NULL; 4147a84e134Smrg smw->simple_menu.state = 0; 4157a84e134Smrg 4167a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, PopupCB, NULL); 4177a84e134Smrg#endif 4187a84e134Smrg 4197a84e134Smrg if (smw->simple_menu.label_string != NULL) 4207a84e134Smrg CreateLabel(cnew); 4217a84e134Smrg 4227a84e134Smrg width = height = 0; 4237a84e134Smrg CalculateNewSize(cnew, &width, &height); 4247a84e134Smrg 4257a84e134Smrg smw->simple_menu.menu_width = True; 4267a84e134Smrg 4277a84e134Smrg if (XtWidth(smw) == 0) { 4287a84e134Smrg smw->simple_menu.menu_width = False; 4297a84e134Smrg XtWidth(smw) = width; 4307a84e134Smrg } 4317a84e134Smrg 4327a84e134Smrg smw->simple_menu.menu_height = True; 4337a84e134Smrg 4347a84e134Smrg if (XtHeight(smw) == 0) { 4357a84e134Smrg smw->simple_menu.menu_height = False; 4367a84e134Smrg XtHeight(smw) = height; 4377a84e134Smrg } 4387a84e134Smrg 4397a84e134Smrg /* 4407a84e134Smrg * Add a popup_callback routine for changing the cursor 4417a84e134Smrg */ 4427a84e134Smrg XtAddCallback(cnew, XtNpopupCallback, ChangeCursorOnGrab, NULL); 4437a84e134Smrg} 4447a84e134Smrg 4457a84e134Smrg/* 4467a84e134Smrg * Function: 4477a84e134Smrg * XawSimpleMenuRedisplay 4487a84e134Smrg * 4497a84e134Smrg * Parameters: 4507a84e134Smrg * w - simple menu widget 4517a84e134Smrg * event - X event that caused this redisplay 4527a84e134Smrg * region - region the needs to be repainted 4537a84e134Smrg * 4547a84e134Smrg * Description: 4557a84e134Smrg * Redisplays the contents of the widget. 4567a84e134Smrg */ 4577a84e134Smrg/*ARGSUSED*/ 4587a84e134Smrgstatic void 4597a84e134SmrgXawSimpleMenuRedisplay(Widget w, XEvent *event, Region region) 4607a84e134Smrg{ 4617a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 4627a84e134Smrg SmeObject *entry; 4637a84e134Smrg SmeObjectClass cclass; 4647a84e134Smrg 4657a84e134Smrg if (region == NULL) 4667a84e134Smrg XClearWindow(XtDisplay(w), XtWindow(w)); 4677a84e134Smrg 4687a84e134Smrg#ifndef OLDXAW 4697a84e134Smrg if (smw->simple_menu.display_list) 4707a84e134Smrg XawRunDisplayList(w, smw->simple_menu.display_list, event, region); 4717a84e134Smrg#endif 4727a84e134Smrg 4737a84e134Smrg /* 4747a84e134Smrg * Check and Paint each of the entries - including the label 4757a84e134Smrg */ 4767a84e134Smrg ForAllChildren(smw, entry) { 4777a84e134Smrg if (!XtIsManaged((Widget)*entry)) 4787a84e134Smrg continue; 4797a84e134Smrg 4807a84e134Smrg if (region != NULL) 4817a84e134Smrg switch(XRectInRegion(region, XtX(*entry),XtY(*entry), 4827a84e134Smrg XtWidth(*entry), XtHeight(*entry))) { 4837a84e134Smrg case RectangleIn: 4847a84e134Smrg case RectanglePart: 4857a84e134Smrg break; 4867a84e134Smrg default: 4877a84e134Smrg continue; 4887a84e134Smrg } 4897a84e134Smrg 4907a84e134Smrg cclass = (SmeObjectClass)(*entry)->object.widget_class; 4917a84e134Smrg 4927a84e134Smrg if (cclass->rect_class.expose != NULL) 4937a84e134Smrg (cclass->rect_class.expose)((Widget)*entry, NULL, NULL); 4947a84e134Smrg } 4957a84e134Smrg} 4967a84e134Smrg 4977a84e134Smrg/* 4987a84e134Smrg * Function: 4997a84e134Smrg * XawSimpleMenuRealize 5007a84e134Smrg * 5017a84e134Smrg * Parameters: 5027a84e134Smrg * w - simple menu widget 5037a84e134Smrg * mask - value mask for the window to create 5047a84e134Smrg * attrs - attributes for the window to create 5057a84e134Smrg * 5067a84e134Smrg * Description: 5077a84e134Smrg * Realizes the widget. 5087a84e134Smrg */ 5097a84e134Smrgstatic void 5107a84e134SmrgXawSimpleMenuRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attrs) 5117a84e134Smrg{ 5127a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 5137a84e134Smrg#ifndef OLDXAW 5147a84e134Smrg XawPixmap *pixmap; 5157a84e134Smrg#endif 5167a84e134Smrg 5177a84e134Smrg attrs->cursor = smw->simple_menu.cursor; 5187a84e134Smrg *mask |= CWCursor; 5197a84e134Smrg if (smw->simple_menu.backing_store == Always || 5207a84e134Smrg smw->simple_menu.backing_store == NotUseful || 5217a84e134Smrg smw->simple_menu.backing_store == WhenMapped) { 5227a84e134Smrg *mask |= CWBackingStore; 5237a84e134Smrg attrs->backing_store = smw->simple_menu.backing_store; 5247a84e134Smrg } 5257a84e134Smrg else 5267a84e134Smrg *mask &= ~CWBackingStore; 5277a84e134Smrg 5287a84e134Smrg (*Superclass->core_class.realize)(w, mask, attrs); 5297a84e134Smrg 5307a84e134Smrg#ifndef OLDXAW 5317a84e134Smrg if (w->core.background_pixmap > XtUnspecifiedPixmap) { 5327a84e134Smrg pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w), 5337a84e134Smrg w->core.colormap, w->core.depth); 5347a84e134Smrg if (pixmap && pixmap->mask) 5357a84e134Smrg XawReshapeWidget(w, pixmap); 5367a84e134Smrg } 5377a84e134Smrg#endif 5387a84e134Smrg} 5397a84e134Smrg 5407a84e134Smrg/* 5417a84e134Smrg * Function: 5427a84e134Smrg * XawSimpleMenuResize 5437a84e134Smrg * 5447a84e134Smrg * Parameters: 5457a84e134Smrg * w - simple menu widget 5467a84e134Smrg * 5477a84e134Smrg * Description: 5487a84e134Smrg * Handle the menu being resized. 5497a84e134Smrg */ 5507a84e134Smrgstatic void 5517a84e134SmrgXawSimpleMenuResize(Widget w) 5527a84e134Smrg{ 5537a84e134Smrg if (!XtIsRealized(w)) 5547a84e134Smrg return; 5557a84e134Smrg 5567a84e134Smrg Layout(w, NULL, NULL); 5577a84e134Smrg 5587a84e134Smrg XawSimpleMenuRedisplay(w, NULL, NULL); 5597a84e134Smrg} 5607a84e134Smrg 5617a84e134Smrg/* 5627a84e134Smrg * Function: 5637a84e134Smrg * XawSimpleMenuSetValues 5647a84e134Smrg * 5657a84e134Smrg * Parameters: 5667a84e134Smrg * current - current state of the widget 5677a84e134Smrg * request - what was requested 5687a84e134Smrg * cnew - what the widget will become 5697a84e134Smrg * 5707a84e134Smrg * Description: 5717a84e134Smrg * Relayout the menu when one of the resources is changed. 5727a84e134Smrg */ 5737a84e134Smrg/*ARGSUSED*/ 5747a84e134Smrgstatic Boolean 5757a84e134SmrgXawSimpleMenuSetValues(Widget current, Widget request, Widget cnew, 5767a84e134Smrg ArgList args, Cardinal *num_args) 5777a84e134Smrg{ 5787a84e134Smrg SimpleMenuWidget smw_old = (SimpleMenuWidget)current; 5797a84e134Smrg SimpleMenuWidget smw_new = (SimpleMenuWidget)cnew; 5807a84e134Smrg Boolean ret_val = False, layout = False; 5817a84e134Smrg 5827a84e134Smrg if (!XtIsRealized(current)) 5837a84e134Smrg return (False); 5847a84e134Smrg 5857a84e134Smrg if (!smw_new->simple_menu.recursive_set_values) { 5867a84e134Smrg if (XtWidth(smw_new) != XtWidth(smw_old)) { 5877a84e134Smrg smw_new->simple_menu.menu_width = XtWidth(smw_new) != 0; 5887a84e134Smrg layout = True; 5897a84e134Smrg } 5907a84e134Smrg if (XtHeight(smw_new) != XtHeight(smw_old)) { 5917a84e134Smrg smw_new->simple_menu.menu_height = XtHeight(smw_new) != 0; 5927a84e134Smrg layout = True; 5937a84e134Smrg } 5947a84e134Smrg } 5957a84e134Smrg 5967a84e134Smrg if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor) 5977a84e134Smrg XDefineCursor(XtDisplay(cnew), XtWindow(cnew), 5987a84e134Smrg smw_new->simple_menu.cursor); 5997a84e134Smrg 6007a84e134Smrg if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string) { 6017a84e134Smrg if (smw_new->simple_menu.label_string == NULL) /* Destroy */ 6027a84e134Smrg XtDestroyWidget((Widget)smw_old->simple_menu.label); 6037a84e134Smrg else if (smw_old->simple_menu.label_string == NULL) /* Create */ 6047a84e134Smrg CreateLabel(cnew); 6057a84e134Smrg else { /* Change */ 6067a84e134Smrg Arg arglist[1]; 6077a84e134Smrg 6087a84e134Smrg XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string); 6097a84e134Smrg XtSetValues((Widget)smw_new->simple_menu.label, arglist, ONE); 6107a84e134Smrg } 6117a84e134Smrg } 6127a84e134Smrg 6137a84e134Smrg if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class) 6147a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(cnew), 6157a84e134Smrg "No Dynamic class change of the SimpleMenu Label."); 6167a84e134Smrg 6177a84e134Smrg if (smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin 6187a84e134Smrg || smw_old->simple_menu.bottom_margin 6197a84e134Smrg != smw_new->simple_menu.bottom_margin) { 6207a84e134Smrg layout = True; 6217a84e134Smrg ret_val = True; 6227a84e134Smrg } 6237a84e134Smrg 6247a84e134Smrg#ifndef OLDXAW 6257a84e134Smrg if (smw_old->core.background_pixmap != smw_new->core.background_pixmap) { 6267a84e134Smrg XawPixmap *opix, *npix; 6277a84e134Smrg 6287a84e134Smrg opix = XawPixmapFromXPixmap(smw_old->core.background_pixmap, 6297a84e134Smrg XtScreen(smw_old), smw_old->core.colormap, 6307a84e134Smrg smw_old->core.depth); 6317a84e134Smrg npix = XawPixmapFromXPixmap(smw_new->core.background_pixmap, 6327a84e134Smrg XtScreen(smw_new), smw_new->core.colormap, 6337a84e134Smrg smw_new->core.depth); 6347a84e134Smrg if ((npix && npix->mask) || (opix && opix->mask)) 6357a84e134Smrg XawReshapeWidget(cnew, npix); 6367a84e134Smrg } 6377a84e134Smrg#endif 6387a84e134Smrg 6397a84e134Smrg if (layout) 6407a84e134Smrg Layout(cnew, NULL, NULL); 6417a84e134Smrg 6427a84e134Smrg return (ret_val); 6437a84e134Smrg} 6447a84e134Smrg 6457a84e134Smrg/* 6467a84e134Smrg * Function: 6477a84e134Smrg * XawSimpleMenuSetValuesHook 6487a84e134Smrg * 6497a84e134Smrg * Parameters: 6507a84e134Smrg * w - menu widget 6517a84e134Smrg * arglist - argument list passed to XtSetValues 6527a84e134Smrg * num_args - number of args 6537a84e134Smrg * 6547a84e134Smrg * Description: 6557a84e134Smrg * To handle a special case, this is passed the actual arguments. 6567a84e134Smrg */ 6577a84e134Smrgstatic Boolean 6587a84e134SmrgXawSimpleMenuSetValuesHook(Widget w, ArgList arglist, Cardinal *num_args) 6597a84e134Smrg{ 6607a84e134Smrg Cardinal i; 6617a84e134Smrg Dimension width, height; 6627a84e134Smrg 6637a84e134Smrg width = XtWidth(w); 6647a84e134Smrg height = XtHeight(w); 6657a84e134Smrg 6667a84e134Smrg for (i = 0 ; i < *num_args ; i++) { 6677a84e134Smrg if (streq(arglist[i].name, XtNwidth)) 6687a84e134Smrg width = (Dimension)arglist[i].value; 6697a84e134Smrg if (streq(arglist[i].name, XtNheight)) 6707a84e134Smrg height = (Dimension) arglist[i].value; 6717a84e134Smrg } 6727a84e134Smrg 6737a84e134Smrg if (width != XtWidth(w) || height != XtHeight(w)) 6747a84e134Smrg MakeSetValuesRequest(w, width, height); 6757a84e134Smrg 6767a84e134Smrg return (False); 6777a84e134Smrg} 6787a84e134Smrg 6797a84e134Smrg/* 6807a84e134Smrg * Geometry Management routines 6817a84e134Smrg */ 6827a84e134Smrg/* 6837a84e134Smrg * Function: 6847a84e134Smrg * XawSimpleMenuGeometryManager 6857a84e134Smrg * 6867a84e134Smrg * Parameters: 6877a84e134Smrg * w - Menu Entry making the request 6887a84e134Smrg * request - requested new geometry 6897a84e134Smrg * reply - the allowed geometry. 6907a84e134Smrg * 6917a84e134Smrg * Description: 6927a84e134Smrg * This is the SimpleMenu Widget's Geometry Manager. 6937a84e134Smrg * 6947a84e134Smrg * Returns: 6957a84e134Smrg * XtGeometry{Yes, No, Almost} 6967a84e134Smrg */ 6977a84e134Smrgstatic XtGeometryResult 6987a84e134SmrgXawSimpleMenuGeometryManager(Widget w, XtWidgetGeometry *request, 6997a84e134Smrg XtWidgetGeometry *reply) 7007a84e134Smrg{ 7017a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)XtParent(w); 7027a84e134Smrg SmeObject entry = (SmeObject)w; 7037a84e134Smrg XtGeometryMask mode = request->request_mode; 7047a84e134Smrg XtGeometryResult answer; 7057a84e134Smrg Dimension old_height, old_width; 7067a84e134Smrg 7077a84e134Smrg if (!(mode & CWWidth) && !(mode & CWHeight)) 7087a84e134Smrg return (XtGeometryNo); 7097a84e134Smrg 7107a84e134Smrg reply->width = request->width; 7117a84e134Smrg reply->height = request->height; 7127a84e134Smrg 7137a84e134Smrg old_width = XtWidth(entry); 7147a84e134Smrg old_height = XtHeight(entry); 7157a84e134Smrg 7167a84e134Smrg Layout(w, &reply->width, &reply->height); 7177a84e134Smrg 7187a84e134Smrg /* 7197a84e134Smrg * Since we are an override shell and have no parent there is no one to 7207a84e134Smrg * ask to see if this geom change is okay, so I am just going to assume 7217a84e134Smrg * we can do whatever we want. If you subclass be very careful with this 7227a84e134Smrg * assumption, it could bite you. 7237a84e134Smrg * 7247a84e134Smrg * Chris D. Peterson - Sept. 1989. 7257a84e134Smrg */ 7267a84e134Smrg if ((!(mode & CWWidth) || reply->width == request->width) 7277a84e134Smrg && (!(mode & CWHeight) || reply->height == request->height)) { 7287a84e134Smrg if (mode & XtCWQueryOnly) { /* Actually perform the layout */ 7297a84e134Smrg XtWidth(entry) = old_width; 7307a84e134Smrg XtHeight(entry) = old_height; 7317a84e134Smrg } 7327a84e134Smrg else 7337a84e134Smrg Layout((Widget)smw, NULL, NULL); 7347a84e134Smrg answer = XtGeometryDone; 7357a84e134Smrg } 7367a84e134Smrg else { 7377a84e134Smrg XtWidth(entry) = old_width; 7387a84e134Smrg XtHeight(entry) = old_height; 7397a84e134Smrg 7407a84e134Smrg if ((reply->width == request->width && !(mode & CWHeight)) 7417a84e134Smrg || (reply->height == request->height && !(mode & CWWidth)) 7427a84e134Smrg || (reply->width == request->width 7437a84e134Smrg && reply->height == request->height)) 7447a84e134Smrg answer = XtGeometryNo; 7457a84e134Smrg else { 7467a84e134Smrg answer = XtGeometryAlmost; 7477a84e134Smrg reply->request_mode = 0; 7487a84e134Smrg if (reply->width != request->width) 7497a84e134Smrg reply->request_mode |= CWWidth; 7507a84e134Smrg if (reply->height != request->height) 7517a84e134Smrg reply->request_mode |= CWHeight; 7527a84e134Smrg } 7537a84e134Smrg } 7547a84e134Smrg 7557a84e134Smrg return (answer); 7567a84e134Smrg} 7577a84e134Smrg 7587a84e134Smrg/* 7597a84e134Smrg * Function: 7607a84e134Smrg * XawSimpleMenuChangeManaged 7617a84e134Smrg * 7627a84e134Smrg * Parameters: 7637a84e134Smrg * w - simple menu widget 7647a84e134Smrg * 7657a84e134Smrg * Description: 7667a84e134Smrg * Called whenever a new child is managed. 7677a84e134Smrg */ 7687a84e134Smrgstatic void 7697a84e134SmrgXawSimpleMenuChangeManaged(Widget w) 7707a84e134Smrg{ 7717a84e134Smrg Layout(w, NULL, NULL); 7727a84e134Smrg} 7737a84e134Smrg 7747a84e134Smrg/* 7757a84e134Smrg * Global Action Routines 7767a84e134Smrg * 7777a84e134Smrg * These actions routines will be added to the application's 7787a84e134Smrg * global action list 7797a84e134Smrg */ 7807a84e134Smrg/* 7817a84e134Smrg * Function: 7827a84e134Smrg * PositionMenuAction 7837a84e134Smrg * 7847a84e134Smrg * Parameters: 7857a84e134Smrg * w - a widget (no the simple menu widget) 7867a84e134Smrg * event - the event that caused this action 7877a84e134Smrg * params - parameters passed to the routine. 7887a84e134Smrg * we expect the name of the menu here. 7897a84e134Smrg * num_params - "" 7907a84e134Smrg * 7917a84e134Smrg * Description: 7927a84e134Smrg * Positions the simple menu widget. 7937a84e134Smrg */ 7947a84e134Smrg/*ARGSUSED*/ 7957a84e134Smrgstatic void 7967a84e134SmrgPositionMenuAction(Widget w, XEvent *event, 7977a84e134Smrg String *params, Cardinal *num_params) 7987a84e134Smrg{ 7997a84e134Smrg Widget menu; 8007a84e134Smrg XPoint loc; 8017a84e134Smrg 8027a84e134Smrg if (*num_params != 1) { 8037a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 8047a84e134Smrg "SimpleMenuWidget: position menu action expects " 8057a84e134Smrg "only one parameter which is the name of the menu."); 8067a84e134Smrg return; 8077a84e134Smrg } 8087a84e134Smrg 8097a84e134Smrg if ((menu = FindMenu(w, params[0])) == NULL) { 8107a84e134Smrg char error_buf[BUFSIZ]; 8117a84e134Smrg 8127a84e134Smrg (void)XmuSnprintf(error_buf, sizeof(error_buf), 8137a84e134Smrg "SimpleMenuWidget: could not find menu named %s.", 8147a84e134Smrg params[0]); 8157a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), error_buf); 8167a84e134Smrg return; 8177a84e134Smrg } 8187a84e134Smrg 8197a84e134Smrg switch (event->type) { 8207a84e134Smrg case ButtonPress: 8217a84e134Smrg case ButtonRelease: 8227a84e134Smrg loc.x = event->xbutton.x_root; 8237a84e134Smrg loc.y = event->xbutton.y_root; 8247a84e134Smrg PositionMenu(menu, &loc); 8257a84e134Smrg break; 8267a84e134Smrg case EnterNotify: 8277a84e134Smrg case LeaveNotify: 8287a84e134Smrg loc.x = event->xcrossing.x_root; 8297a84e134Smrg loc.y = event->xcrossing.y_root; 8307a84e134Smrg PositionMenu(menu, &loc); 8317a84e134Smrg break; 8327a84e134Smrg case MotionNotify: 8337a84e134Smrg loc.x = event->xmotion.x_root; 8347a84e134Smrg loc.y = event->xmotion.y_root; 8357a84e134Smrg PositionMenu(menu, &loc); 8367a84e134Smrg break; 8377a84e134Smrg default: 8387a84e134Smrg PositionMenu(menu, NULL); 8397a84e134Smrg break; 8407a84e134Smrg } 8417a84e134Smrg} 8427a84e134Smrg 8437a84e134Smrg/* 8447a84e134Smrg * Widget Action Routines 8457a84e134Smrg */ 8467a84e134Smrg/* 8477a84e134Smrg * Function: 8487a84e134Smrg * Unhighlight 8497a84e134Smrg * 8507a84e134Smrg * Parameters: 8517a84e134Smrg * w - simple menu widget 8527a84e134Smrg * event - event that caused this action 8537a84e134Smrg * params - not used 8547a84e134Smrg * num_params - "" 8557a84e134Smrg * 8567a84e134Smrg * Description: 8577a84e134Smrg * Unhighlights current entry. 8587a84e134Smrg */ 8597a84e134Smrg/*ARGSUSED*/ 8607a84e134Smrgstatic void 8617a84e134SmrgUnhighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) 8627a84e134Smrg{ 8637a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8647a84e134Smrg SmeObject entry = smw->simple_menu.entry_set; 8657a84e134Smrg 8667a84e134Smrg if (entry == NULL) 8677a84e134Smrg return; 8687a84e134Smrg 8697a84e134Smrg#ifndef OLDXAW 8707a84e134Smrg if (!smw->simple_menu.sub_menu) 8717a84e134Smrg#endif 8727a84e134Smrg { 8737a84e134Smrg SmeObjectClass cclass; 8747a84e134Smrg 8757a84e134Smrg smw->simple_menu.entry_set = NULL; 8767a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 8777a84e134Smrg (cclass->sme_class.unhighlight)((Widget)entry); 8787a84e134Smrg } 8797a84e134Smrg} 8807a84e134Smrg 8817a84e134Smrg/* 8827a84e134Smrg * Function: 8837a84e134Smrg * Highlight 8847a84e134Smrg * 8857a84e134Smrg * Parameters: 8867a84e134Smrg * w - simple menu widget 8877a84e134Smrg * event - event that caused this action 8887a84e134Smrg * params - not used 8897a84e134Smrg * num_params - "" 8907a84e134Smrg * 8917a84e134Smrg * Description: 8927a84e134Smrg * Highlights current entry. 8937a84e134Smrg */ 8947a84e134Smrg/*ARGSUSED*/ 8957a84e134Smrgstatic void 8967a84e134SmrgHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) 8977a84e134Smrg{ 8987a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 8997a84e134Smrg SmeObject entry; 9007a84e134Smrg 9017a84e134Smrg if (!XtIsSensitive(w)) 9027a84e134Smrg return; 9037a84e134Smrg 9047a84e134Smrg entry = GetEventEntry(w, event); 9057a84e134Smrg 9067a84e134Smrg if (entry == smw->simple_menu.entry_set) 9077a84e134Smrg return; 9087a84e134Smrg 9097a84e134Smrg#ifndef OLDXAW 9107a84e134Smrg if (!smw->simple_menu.sub_menu) 9117a84e134Smrg#endif 9127a84e134Smrg Unhighlight(w, event, params, num_params); 9137a84e134Smrg 9147a84e134Smrg if (entry == NULL) 9157a84e134Smrg return; 9167a84e134Smrg 9177a84e134Smrg if (!XtIsSensitive((Widget)entry)) 9187a84e134Smrg return; 9197a84e134Smrg 9207a84e134Smrg#ifndef OLDXAW 9217a84e134Smrg if (smw->simple_menu.sub_menu) 9227a84e134Smrg PopdownSubMenu(smw); 9237a84e134Smrg#endif 9247a84e134Smrg 9257a84e134Smrg Unhighlight(w, event, params, num_params); 9267a84e134Smrg 9277a84e134Smrg#ifndef OLDXAW 9287a84e134Smrg if (!(smw->simple_menu.state & SMW_UNMAPPING)) 9297a84e134Smrg#endif 9307a84e134Smrg { 9317a84e134Smrg SmeObjectClass cclass; 9327a84e134Smrg 9337a84e134Smrg smw->simple_menu.entry_set = entry; 9347a84e134Smrg cclass = (SmeObjectClass)entry->object.widget_class; 9357a84e134Smrg 9367a84e134Smrg (cclass->sme_class.highlight)((Widget)entry); 9377a84e134Smrg 9387a84e134Smrg#ifndef OLDXAW 9397a84e134Smrg if (XtIsSubclass((Widget)entry, smeBSBObjectClass)) 9407a84e134Smrg PopupSubMenu(smw); 9417a84e134Smrg#endif 9427a84e134Smrg } 9437a84e134Smrg} 9447a84e134Smrg 9457a84e134Smrg/* 9467a84e134Smrg * Function: 9477a84e134Smrg * Notify 9487a84e134Smrg * 9497a84e134Smrg * Parameters: 9507a84e134Smrg * w - simple menu widget 9517a84e134Smrg * event - event that caused this action 9527a84e134Smrg * params - not used 9537a84e134Smrg * num_params - "" 9547a84e134Smrg * 9557a84e134Smrg * Description: 9567a84e134Smrg * Notify user of current entry. 9577a84e134Smrg */ 9587a84e134Smrg/*ARGSUSED*/ 9597a84e134Smrgstatic void 9607a84e134SmrgNotify(Widget w, XEvent *event, String *params, Cardinal *num_params) 9617a84e134Smrg{ 9627a84e134Smrg SmeObject entry; 9637a84e134Smrg SmeObjectClass cclass; 9647a84e134Smrg 9657a84e134Smrg /* may be a propagated event from a sub menu, need to check it */ 9667a84e134Smrg if (XtWindow(w) != event->xany.window) 9677a84e134Smrg return; 9687a84e134Smrg entry = GetEventEntry(w, event); 9697a84e134Smrg if (entry == NULL || !XtIsSensitive((Widget)entry)) 9707a84e134Smrg return; 9717a84e134Smrg 9727a84e134Smrg cclass = (SmeObjectClass) entry->object.widget_class; 9737a84e134Smrg (cclass->sme_class.notify)((Widget)entry); 9747a84e134Smrg} 9757a84e134Smrg 9767a84e134Smrg/* 9777a84e134Smrg * Public Functions 9787a84e134Smrg */ 9797a84e134Smrg/* 9807a84e134Smrg * Function: 9817a84e134Smrg * XawSimpleMenuAddGlobalActions 9827a84e134Smrg * 9837a84e134Smrg * Arguments: 9847a84e134Smrg * app_con - appcontext 9857a84e134Smrg * 9867a84e134Smrg * Description: 9877a84e134Smrg * Adds the global actions to the simple menu widget. 9887a84e134Smrg */ 9897a84e134Smrgvoid 9907a84e134SmrgXawSimpleMenuAddGlobalActions(XtAppContext app_con) 9917a84e134Smrg{ 9927a84e134Smrg XtInitializeWidgetClass(simpleMenuWidgetClass); 9937a84e134Smrg XmuCallInitializers(app_con); 9947a84e134Smrg} 9957a84e134Smrg 9967a84e134Smrg/* 9977a84e134Smrg * Function: 9987a84e134Smrg * XawSimpleMenuGetActiveEntry 9997a84e134Smrg * 10007a84e134Smrg * Parameters: 10017a84e134Smrg * w - smw widget 10027a84e134Smrg * 10037a84e134Smrg * Description: 10047a84e134Smrg * Gets the currently active (set) entry. 10057a84e134Smrg * 10067a84e134Smrg * Returns: 10077a84e134Smrg * The currently set entry or NULL if none is set 10087a84e134Smrg */ 10097a84e134SmrgWidget 10107a84e134SmrgXawSimpleMenuGetActiveEntry(Widget w) 10117a84e134Smrg{ 10127a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10137a84e134Smrg 10147a84e134Smrg return ((Widget)smw->simple_menu.entry_set); 10157a84e134Smrg} 10167a84e134Smrg 10177a84e134Smrg/* 10187a84e134Smrg * Function: 10197a84e134Smrg * XawSimpleMenuClearActiveEntry 10207a84e134Smrg * 10217a84e134Smrg * Parameters: 10227a84e134Smrg * w - smw widget 10237a84e134Smrg * 10247a84e134Smrg * Description: 10257a84e134Smrg * Unsets the currently active (set) entry. 10267a84e134Smrg */ 10277a84e134Smrgvoid 10287a84e134SmrgXawSimpleMenuClearActiveEntry(Widget w) 10297a84e134Smrg{ 10307a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10317a84e134Smrg 10327a84e134Smrg smw->simple_menu.entry_set = NULL; 10337a84e134Smrg} 10347a84e134Smrg 10357a84e134Smrg/* 10367a84e134Smrg * Private Functions 10377a84e134Smrg */ 10387a84e134Smrg/* 10397a84e134Smrg * Function: 10407a84e134Smrg * CreateLabel 10417a84e134Smrg * 10427a84e134Smrg * Parameters: 10437a84e134Smrg * w - smw widget 10447a84e134Smrg * 10457a84e134Smrg * Description: 10467a84e134Smrg * Creates the label object and makes sure it is the first child in 10477a84e134Smrg * in the list. 10487a84e134Smrg */ 10497a84e134Smrgstatic void 10507a84e134SmrgCreateLabel(Widget w) 10517a84e134Smrg{ 10527a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 10537a84e134Smrg Widget *child, *next_child; 10547a84e134Smrg int i; 10557a84e134Smrg Arg args[2]; 10567a84e134Smrg 10577a84e134Smrg if (smw->simple_menu.label_string == NULL || 10587a84e134Smrg smw->simple_menu.label != NULL) { 10597a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), 10607a84e134Smrg "Xaw Simple Menu Widget: label string is NULL or " 10617a84e134Smrg "label already exists, no label is being created."); 10627a84e134Smrg return; 10637a84e134Smrg } 10647a84e134Smrg 10657a84e134Smrg XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string); 10667a84e134Smrg XtSetArg(args[1], XtNjustify, XtJustifyCenter); 10677a84e134Smrg smw->simple_menu.label = (SmeObject) 10687a84e134Smrg XtCreateManagedWidget("menuLabel", 10697a84e134Smrg smw->simple_menu.label_class, w, args, TWO); 10707a84e134Smrg 10717a84e134Smrg next_child = NULL; 10727a84e134Smrg for (child = smw->composite.children + smw->composite.num_children, 10737a84e134Smrg i = smw->composite.num_children; i > 0; i--, child--) { 10747a84e134Smrg if (next_child != NULL) 10757a84e134Smrg *next_child = *child; 10767a84e134Smrg next_child = child; 10777a84e134Smrg } 10787a84e134Smrg *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 10957a84e134Smrg * to be width and height that the child would get if it were layed 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 height = 0; 11147a84e134Smrg 11157a84e134Smrg if (XtIsSubclass(w, simpleMenuWidgetClass)) { 11167a84e134Smrg smw = (SimpleMenuWidget)w; 11177a84e134Smrg current_entry = NULL; 11187a84e134Smrg } 11197a84e134Smrg else { 11207a84e134Smrg smw = (SimpleMenuWidget)XtParent(w); 11217a84e134Smrg current_entry = (SmeObject)w; 11227a84e134Smrg } 11237a84e134Smrg 11247a84e134Smrg allow_change_size = (!XtIsRealized((Widget)smw) 11257a84e134Smrg || smw->shell.allow_shell_resize); 11267a84e134Smrg 11277a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11287a84e134Smrg i < smw->composite.num_children; 11297a84e134Smrg i++) { 11307a84e134Smrg XtWidgetGeometry preferred; 11317a84e134Smrg 11327a84e134Smrg kid = smw->composite.children[i]; 11337a84e134Smrg if (!XtIsManaged(kid)) 11347a84e134Smrg continue; 11357a84e134Smrg if (smw->simple_menu.row_height != 0) 11367a84e134Smrg XtHeight(kid) = smw->simple_menu.row_height; 11377a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11387a84e134Smrg if (preferred.request_mode & CWWidth) 11397a84e134Smrg XtWidth(kid) = preferred.width; 11407a84e134Smrg } 11417a84e134Smrg 11427a84e134Smrg if (smw->simple_menu.label 11437a84e134Smrg && XtIsManaged((Widget)smw->simple_menu.label)) { 11447a84e134Smrg XtWidgetGeometry preferred; 11457a84e134Smrg 11467a84e134Smrg kid = (Widget)smw->simple_menu.label; 11477a84e134Smrg XtQueryGeometry(kid, NULL, &preferred); 11487a84e134Smrg if (preferred.request_mode & CWWidth) 11497a84e134Smrg XtWidth(kid) = preferred.width; 11507a84e134Smrg if (preferred.request_mode & CWHeight) 11517a84e134Smrg XtHeight(kid) = preferred.height; 11527a84e134Smrg } 11537a84e134Smrg 11547a84e134Smrg /* reset */ 11557a84e134Smrg if (!smw->simple_menu.menu_width) 11567a84e134Smrg XtWidth(smw) = 0; 11577a84e134Smrg if (!smw->simple_menu.menu_height) 11587a84e134Smrg XtHeight(smw) = 0; 11597a84e134Smrg if (!XtWidth(smw) || !XtHeight(smw)) 11607a84e134Smrg MakeResizeRequest((Widget)smw); 11617a84e134Smrg 11627a84e134Smrg widths = (Dimension *)XtMalloc(sizeof(Dimension)); 11637a84e134Smrg#ifndef OLDXAW 11647a84e134Smrg hadd = smw->simple_menu.left_margin; 11657a84e134Smrg#else 11667a84e134Smrg hadd = 0; 11677a84e134Smrg#endif 11687a84e134Smrg vadd = smw->simple_menu.top_margin; 11697a84e134Smrg if (smw->simple_menu.label) 11707a84e134Smrg vadd += XtHeight(smw->simple_menu.label); 11717a84e134Smrg 11727a84e134Smrg count = 1; 11737a84e134Smrg width = tmp_w = tmp_h = n = 0; 11747a84e134Smrg height = vadd; 11757a84e134Smrg 11767a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 11777a84e134Smrg i < smw->composite.num_children; 11787a84e134Smrg i++) { 11797a84e134Smrg kid = smw->composite.children[i]; 11807a84e134Smrg if (!XtIsManaged(kid)) 11817a84e134Smrg continue; 11827a84e134Smrg width_kid = XtWidth(kid); 11837a84e134Smrg height_kid = XtHeight(kid); 11847a84e134Smrg 11857a84e134Smrg if (n && (height + height_kid + smw->simple_menu.bottom_margin 11867a84e134Smrg > XtHeight(smw))) { 11877a84e134Smrg ++count; 11887a84e134Smrg widths = (Dimension *)XtRealloc((char *)widths, 11897a84e134Smrg sizeof(Dimension) * count); 11907a84e134Smrg widths[count - 1] = width_kid; 11917a84e134Smrg width += tmp_w; 11927a84e134Smrg tmp_w = width_kid; 11937a84e134Smrg height = height_kid + vadd; 11947a84e134Smrg } 11957a84e134Smrg else 11967a84e134Smrg height += height_kid; 11977a84e134Smrg if (height > tmp_h) 11987a84e134Smrg tmp_h = height; 11997a84e134Smrg if (width_kid > tmp_w) 12007a84e134Smrg widths[count - 1] = tmp_w = width_kid; 12017a84e134Smrg ++n; 12027a84e134Smrg } 12037a84e134Smrg 12047a84e134Smrg height = tmp_h + smw->simple_menu.bottom_margin; 12057a84e134Smrg width += tmp_w; 12067a84e134Smrg 12077a84e134Smrg if (smw->simple_menu.label && width < XtWidth(smw->simple_menu.label)) { 12087a84e134Smrg float inc; 12097a84e134Smrg 12107a84e134Smrg inc = (XtWidth(smw->simple_menu.label) - width) / (float)count; 12117a84e134Smrg width = XtWidth(smw->simple_menu.label); 12127a84e134Smrg for (n = 0; n < count; n++) 12137a84e134Smrg widths[n] += inc; 12147a84e134Smrg } 12157a84e134Smrg 12167a84e134Smrg#ifndef OLDXAW 12177a84e134Smrg width += hadd + smw->simple_menu.right_margin; 12187a84e134Smrg#endif 12197a84e134Smrg 12207a84e134Smrg x_ins = n = count = 0; 12217a84e134Smrg tmp_w = widths[0]; 12227a84e134Smrg tmp_h = vadd; 12237a84e134Smrg 12247a84e134Smrg for (i = smw->simple_menu.label ? 1 : 0; 12257a84e134Smrg i < smw->composite.num_children; 12267a84e134Smrg i++) { 12277a84e134Smrg kid = smw->composite.children[i]; 12287a84e134Smrg if (!XtIsManaged(kid)) 12297a84e134Smrg continue; 12307a84e134Smrg 12317a84e134Smrg height_kid = XtHeight(kid); 12327a84e134Smrg 12337a84e134Smrg if (n && (tmp_h + height_kid + smw->simple_menu.bottom_margin 12347a84e134Smrg > XtHeight(smw))) { 12357a84e134Smrg x_ins = tmp_w; 12367a84e134Smrg y_ins = vadd; 12377a84e134Smrg ++count; 12387a84e134Smrg tmp_w += widths[count]; 12397a84e134Smrg tmp_h = height_kid + vadd; 12407a84e134Smrg } 12417a84e134Smrg else { 12427a84e134Smrg y_ins = tmp_h; 12437a84e134Smrg tmp_h += height_kid; 12447a84e134Smrg } 12457a84e134Smrg ++n; 12467a84e134Smrg 12477a84e134Smrg XtX(kid) = x_ins + hadd; 12487a84e134Smrg XtY(kid) = y_ins; 12497a84e134Smrg XtWidth(kid) = widths[count]; 12507a84e134Smrg } 12517a84e134Smrg 12527a84e134Smrg XtFree((char *)widths); 12537a84e134Smrg 12547a84e134Smrg if (allow_change_size) 12557a84e134Smrg MakeSetValuesRequest((Widget) smw, width, height); 12567a84e134Smrg 12577a84e134Smrg if (smw->simple_menu.label) { 12587a84e134Smrg XtX(smw->simple_menu.label) = 0; 12597a84e134Smrg XtY(smw->simple_menu.label) = smw->simple_menu.top_margin; 12607a84e134Smrg XtWidth(smw->simple_menu.label) = XtWidth(smw) 12617a84e134Smrg#ifndef OLDXAW 12627a84e134Smrg - (smw->simple_menu.left_margin + smw->simple_menu.right_margin) 12637a84e134Smrg#endif 12647a84e134Smrg ; 12657a84e134Smrg } 12667a84e134Smrg if (current_entry) { 12677a84e134Smrg if (width_ret) 12687a84e134Smrg *width_ret = XtWidth(current_entry); 12697a84e134Smrg if (height_ret) 12707a84e134Smrg *height_ret = XtHeight(current_entry); 12717a84e134Smrg } 12727a84e134Smrg} 12737a84e134Smrg 12747a84e134Smrg/* 12757a84e134Smrg * Function: 12767a84e134Smrg * AddPositionAction 12777a84e134Smrg * 12787a84e134Smrg * Parameters: 12797a84e134Smrg * app_con - application context 12807a84e134Smrg * data - (not used) 12817a84e134Smrg * 12827a84e134Smrg * Description: 12837a84e134Smrg * Adds the XawPositionSimpleMenu action to the global 12847a84e134Smrg * action list for this appcon. 12857a84e134Smrg */ 12867a84e134Smrg/*ARGSUSED*/ 12877a84e134Smrgstatic void 12887a84e134SmrgAddPositionAction(XtAppContext app_con, XPointer data) 12897a84e134Smrg{ 12907a84e134Smrg static XtActionsRec pos_action[] = { 12917a84e134Smrg {"XawPositionSimpleMenu", PositionMenuAction}, 12927a84e134Smrg }; 12937a84e134Smrg 12947a84e134Smrg XtAppAddActions(app_con, pos_action, XtNumber(pos_action)); 12957a84e134Smrg} 12967a84e134Smrg 12977a84e134Smrg/* 12987a84e134Smrg * Function: 12997a84e134Smrg * FindMenu 13007a84e134Smrg * 13017a84e134Smrg * Parameters: 13027a84e134Smrg * widget - reference widget 13037a84e134Smrg * name - menu widget's name 13047a84e134Smrg * 13057a84e134Smrg * Description: 13067a84e134Smrg * Find the menu give a name and reference widget 13077a84e134Smrg * 13087a84e134Smrg * Returns: 13097a84e134Smrg * The menu widget or NULL. 13107a84e134Smrg */ 13117a84e134Smrgstatic Widget 13127a84e134SmrgFindMenu(Widget widget, String name) 13137a84e134Smrg{ 13147a84e134Smrg Widget w, menu; 13157a84e134Smrg 13167a84e134Smrg for (w = widget; w != NULL; w = XtParent(w)) 13177a84e134Smrg if ((menu = XtNameToWidget(w, name)) != NULL) 13187a84e134Smrg return (menu); 13197a84e134Smrg 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; 13407a84e134Smrg 13417a84e134Smrg if (location == NULL) { 13427a84e134Smrg Window temp1, temp2; 13437a84e134Smrg int root_x, root_y, tempX, tempY; 13447a84e134Smrg unsigned int tempM; 13457a84e134Smrg 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 } 13577a84e134Smrg 13587a84e134Smrg /* 13597a84e134Smrg * The width will not be correct unless it is realized 13607a84e134Smrg */ 13617a84e134Smrg XtRealizeWidget(w); 13627a84e134Smrg 13637a84e134Smrg location->x -= XtWidth(w) >> 1; 13647a84e134Smrg 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) 13717a84e134Smrg 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 13877a84e134Smrg * to be fully visable 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; 13957a84e134Smrg 13967a84e134Smrg if (smw->simple_menu.menu_on_screen) { 13977a84e134Smrg int width = XtWidth(w) + (XtBorderWidth(w) << 1); 13987a84e134Smrg int height = XtHeight(w) + (XtBorderWidth(w) << 1); 13997a84e134Smrg 14007a84e134Smrg if (x >= 0) { 14017a84e134Smrg int scr_width = WidthOfScreen(XtScreen(w)); 14027a84e134Smrg 14037a84e134Smrg if (x + width > scr_width) 14047a84e134Smrg x = scr_width - width; 14057a84e134Smrg } 14067a84e134Smrg if (x < 0) 14077a84e134Smrg x = 0; 14087a84e134Smrg 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 } 14187a84e134Smrg 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 14397a84e134SmrgChangeCursorOnGrab(Widget w, XtPointer temp1, XtPointer temp2) 14407a84e134Smrg{ 14417a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 14427a84e134Smrg 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, 14497a84e134Smrg 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; 14667a84e134Smrg Arg arglist[2]; 14677a84e134Smrg Cardinal num_args = 0; 14687a84e134Smrg 14697a84e134Smrg if (!smw->simple_menu.recursive_set_values) { 14707a84e134Smrg if (XtWidth(smw) != width || XtHeight(smw) != height) { 14717a84e134Smrg smw->simple_menu.recursive_set_values = True; 14727a84e134Smrg XtSetArg(arglist[num_args], XtNwidth, width); num_args++; 14737a84e134Smrg XtSetArg(arglist[num_args], XtNheight, height); num_args++; 14747a84e134Smrg XtSetValues(w, arglist, num_args); 14757a84e134Smrg } 14767a84e134Smrg else if (XtIsRealized((Widget)smw)) 14777a84e134Smrg XawSimpleMenuRedisplay((Widget)smw, NULL, NULL); 14787a84e134Smrg } 14797a84e134Smrg smw->simple_menu.recursive_set_values = False; 14807a84e134Smrg} 14817a84e134Smrg 14827a84e134Smrgstatic SmeObject 14837a84e134SmrgDoGetEventEntry(Widget w, int x_loc, int y_loc) 14847a84e134Smrg{ 14857a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 14867a84e134Smrg SmeObject *entry; 14877a84e134Smrg 14887a84e134Smrg ForAllChildren(smw, entry) { 14897a84e134Smrg if (!XtIsManaged((Widget)*entry)) 14907a84e134Smrg continue; 14917a84e134Smrg 14927a84e134Smrg if (x_loc > XtX(*entry) 14937a84e134Smrg && x_loc <= XtX(*entry) + XtWidth(*entry) 14947a84e134Smrg && y_loc > XtY(*entry) 14957a84e134Smrg && y_loc <= XtY(*entry) + XtHeight(*entry)) { 14967a84e134Smrg if (*entry == smw->simple_menu.label) 14977a84e134Smrg return (NULL); /* cannot select the label */ 14987a84e134Smrg else 14997a84e134Smrg return (*entry); 15007a84e134Smrg } 15017a84e134Smrg } 15027a84e134Smrg 15037a84e134Smrg return (NULL); 15047a84e134Smrg} 15057a84e134Smrg 15067a84e134Smrg/* 15077a84e134Smrg * Function: 15087a84e134Smrg * GetEventEntry 15097a84e134Smrg * 15107a84e134Smrg * Parameters: 15117a84e134Smrg * w - simple menu widget 15127a84e134Smrg * event - X event 15137a84e134Smrg * 15147a84e134Smrg * Description: 15157a84e134Smrg * Gets an entry given an event that has X and Y coords. 15167a84e134Smrg * 15177a84e134Smrg * Returns: 15187a84e134Smrg * The entry that this point is in 15197a84e134Smrg */ 15207a84e134Smrgstatic SmeObject 15217a84e134SmrgGetEventEntry(Widget w, XEvent *event) 15227a84e134Smrg{ 15237a84e134Smrg int x_loc, y_loc, x_root; 15247a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 15257a84e134Smrg SmeObject entry; 15267a84e134Smrg int warp, move; 15277a84e134Smrg 15287a84e134Smrg switch (event->type) { 15297a84e134Smrg case MotionNotify: 15307a84e134Smrg x_loc = event->xmotion.x; 15317a84e134Smrg y_loc = event->xmotion.y; 15327a84e134Smrg x_root = event->xmotion.x_root; 15337a84e134Smrg break; 15347a84e134Smrg case EnterNotify: 15357a84e134Smrg case LeaveNotify: 15367a84e134Smrg x_loc = event->xcrossing.x; 15377a84e134Smrg y_loc = event->xcrossing.y; 15387a84e134Smrg x_root = event->xcrossing.x_root; 15397a84e134Smrg break; 15407a84e134Smrg case ButtonPress: 15417a84e134Smrg case ButtonRelease: 15427a84e134Smrg x_loc = event->xbutton.x; 15437a84e134Smrg y_loc = event->xbutton.y; 15447a84e134Smrg x_root = event->xbutton.x_root; 15457a84e134Smrg break; 15467a84e134Smrg default: 15477a84e134Smrg XtAppError(XtWidgetToApplicationContext(w), 15487a84e134Smrg "Unknown event type in GetEventEntry()."); 15497a84e134Smrg return (NULL); 15507a84e134Smrg } 15517a84e134Smrg 15527a84e134Smrg if (x_loc < 0 || x_loc >= XtWidth(smw) || 15537a84e134Smrg y_loc < 0 || y_loc >= XtHeight(smw)) 15547a84e134Smrg return (NULL); 15557a84e134Smrg 15567a84e134Smrg /* Move the menu if it's outside the screen, does not check 15577a84e134Smrg * smw->simple_menu.menu_on_screen because menus is bigger than screen 15587a84e134Smrg */ 15597a84e134Smrg if (x_root == WidthOfScreen(XtScreen(w)) - 1 && 15607a84e134Smrg XtX(w) + XtWidth(w) + (XtBorderWidth(w)) > x_root) { 15617a84e134Smrg warp = -8; 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) 16047a84e134Smrg XtMoveWidget(w, 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 16247a84e134Smrg hadd = xaw->simple_menu.left_margin + xaw->simple_menu.right_margin; 16257a84e134Smrg#else 16267a84e134Smrg hadd = 0; 16277a84e134Smrg#endif 16287a84e134Smrg vadd = xaw->simple_menu.top_margin + xaw->simple_menu.bottom_margin; 16297a84e134Smrg if (xaw->simple_menu.label) 16307a84e134Smrg 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 16827a84e134Smrg *width_return = width; 16837a84e134Smrg *height_return = 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); 16987a84e134Smrg *height_return = 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; 17097a84e134Smrg 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 17697a84e134Smrg if (popleft) 17707a84e134Smrg XtTranslateCoords((Widget)smw, -(int)XtWidth(menu), 17717a84e134Smrg XtY(entry) - XtBorderWidth(menu), &menu_x, &menu_y); 17727a84e134Smrg else 17737a84e134Smrg XtTranslateCoords((Widget)smw, XtWidth(smw), XtY(entry) 17747a84e134Smrg - XtBorderWidth(menu), &menu_x, &menu_y); 17757a84e134Smrg 17767a84e134Smrg if (!popleft && menu_x >= 0) { 17777a84e134Smrg int scr_width = WidthOfScreen(XtScreen(menu)); 17787a84e134Smrg 17797a84e134Smrg if (menu_x + XtWidth(menu) > scr_width) { 17807a84e134Smrg menu_x -= XtWidth(menu) + XtWidth(smw); 17817a84e134Smrg popleft = True; 17827a84e134Smrg } 17837a84e134Smrg } 17847a84e134Smrg else if (popleft && menu_x < 0) { 17857a84e134Smrg menu_x = 0; 17867a84e134Smrg popleft = False; 17877a84e134Smrg } 17887a84e134Smrg if (menu_y >= 0) { 17897a84e134Smrg int scr_height = HeightOfScreen(XtScreen(menu)); 17907a84e134Smrg 17917a84e134Smrg if (menu_y + XtHeight(menu) > scr_height) 17927a84e134Smrg menu_y = scr_height - XtHeight(menu) - XtBorderWidth(menu); 17937a84e134Smrg } 17947a84e134Smrg if (menu_y < 0) 17957a84e134Smrg menu_y = 0; 17967a84e134Smrg 17977a84e134Smrg num_args = 0; 17987a84e134Smrg XtSetArg(args[num_args], XtNx, menu_x); num_args++; 17997a84e134Smrg XtSetArg(args[num_args], XtNy, menu_y); num_args++; 18007a84e134Smrg XtSetValues(menu, args, num_args); 18017a84e134Smrg 18027a84e134Smrg if (popleft) 18037a84e134Smrg ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT; 18047a84e134Smrg else 18057a84e134Smrg ((SimpleMenuWidget)menu)->simple_menu.state &= ~SMW_POPLEFT; 18067a84e134Smrg 18077a84e134Smrg XtPopup(menu, XtGrabNone); 18087a84e134Smrg} 18097a84e134Smrg 18107a84e134Smrgstatic void 18117a84e134SmrgPopdownSubMenu(SimpleMenuWidget smw) 18127a84e134Smrg{ 18137a84e134Smrg SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu; 18147a84e134Smrg 18157a84e134Smrg if (!menu) 18167a84e134Smrg return; 18177a84e134Smrg 18187a84e134Smrg menu->simple_menu.state |= SMW_UNMAPPING; 18197a84e134Smrg PopdownSubMenu(menu); 18207a84e134Smrg 18217a84e134Smrg XtPopdown((Widget)menu); 18227a84e134Smrg 18237a84e134Smrg smw->simple_menu.sub_menu = NULL; 18247a84e134Smrg} 18257a84e134Smrg 18267a84e134Smrg/*ARGSUSED*/ 18277a84e134Smrgstatic void 18287a84e134SmrgPopupCB(Widget w, XtPointer client_data, XtPointer call_data) 18297a84e134Smrg{ 18307a84e134Smrg SimpleMenuWidget smw = (SimpleMenuWidget)w; 18317a84e134Smrg 18327a84e134Smrg smw->simple_menu.state &= ~(SMW_UNMAPPING | SMW_POPLEFT); 18337a84e134Smrg} 18347a84e134Smrg#endif /* OLDXAW */ 1835