diff options
Diffstat (limited to 'src/MenuButton.c')
-rw-r--r-- | src/MenuButton.c | 300 |
1 files changed, 172 insertions, 128 deletions
diff --git a/src/MenuButton.c b/src/MenuButton.c index 4483009..f21dc90 100644 --- a/src/MenuButton.c +++ b/src/MenuButton.c @@ -25,12 +25,7 @@ in this Software without prior written authorization from The Open Group. * */ - -/*********************************************************************** - * - * MenuButton Widget - * - ***********************************************************************/ +/* $XFree86: xc/lib/Xaw/MenuButton.c,v 3.10 2001/12/14 19:54:41 dawes Exp $ */ /* * MenuButton.c - Source code for MenuButton widget. @@ -48,65 +43,80 @@ in this Software without prior written authorization from The Open Group. #include <stdio.h> #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> - -#include <X11/Xaw/XawInit.h> +#include <X11/Xmu/SysUtil.h> #include <X11/Xaw/MenuButtoP.h> +#include <X11/Xaw/XawInit.h> +#include "Private.h" -static void ClassInitialize(); -static void PopupMenu(); +/* + * Class Methods + */ +static void XawMenuButtonClassInitialize(void); +static void XawMenuButtonInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawMenuButtonDestroy(Widget); +static Boolean XawMenuButtonSetValues(Widget, Widget, Widget, ArgList, Cardinal*); + +/* + * Actions + */ +static void PopupMenu(Widget, XEvent*, String*, Cardinal*); +/* + * Initialization + */ #define superclass ((CommandWidgetClass)&commandClassRec) static char defaultTranslations[] = -"<EnterWindow>: highlight()\n\ - <LeaveWindow>: reset()\n\ - Any<BtnDown>: reset() PopupMenu()"; +"<Enter>:" "highlight()\n" +"<Leave>:" "reset()\n" +"Any<BtnDown>:" "reset() PopupMenu()\n"; -/**************************************************************** - * - * Full class record constant - * - ****************************************************************/ - -/* Private Data */ +static char default_menu_name[] = "menu"; #define offset(field) XtOffsetOf(MenuButtonRec, field) static XtResource resources[] = { { - XtNmenuName, XtCMenuName, XtRString, sizeof(String), - offset(menu_button.menu_name), XtRString, (XtPointer)"menu"}, + XtNmenuName, + XtCMenuName, + XtRString, + sizeof(String), + offset(menu_button.menu_name), + XtRString, + (XtPointer)default_menu_name + }, }; #undef offset static XtActionsRec actionsList[] = { - {"PopupMenu", PopupMenu} + {"PopupMenu", PopupMenu}, }; MenuButtonClassRec menuButtonClassRec = { + /* core */ { - (WidgetClass) superclass, /* superclass */ + (WidgetClass)superclass, /* superclass */ "MenuButton", /* class_name */ sizeof(MenuButtonRec), /* size */ - ClassInitialize, /* class_initialize */ + XawMenuButtonClassInitialize, /* class_initialize */ NULL, /* class_part_initialize */ - FALSE, /* class_inited */ - NULL, /* initialize */ + False, /* class_inited */ + XawMenuButtonInitialize, /* initialize */ NULL, /* initialize_hook */ XtInheritRealize, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ resources, /* resources */ - XtNumber(resources), /* resource_count */ + XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ - FALSE, /* compress_motion */ - TRUE, /* compress_exposure */ - TRUE, /* compress_enterleave */ - FALSE, /* visible_interest */ - NULL, /* destroy */ + False, /* compress_motion */ + True, /* compress_exposure */ + True, /* compress_enterleave */ + False, /* visible_interest */ + XawMenuButtonDestroy, /* destroy */ XtInheritResize, /* resize */ XtInheritExpose, /* expose */ - NULL, /* set_values */ + XawMenuButtonSetValues, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ NULL, /* get_values_hook */ @@ -116,114 +126,148 @@ MenuButtonClassRec menuButtonClassRec = { defaultTranslations, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display_accelerator */ - NULL /* extension */ - }, /* CoreClass fields initialization */ + NULL, /* extension */ + }, + /* simple */ { XtInheritChangeSensitive /* change_sensitive */ - }, /* SimpleClass fields initialization */ + }, + /* label */ { - 0, /* field not used */ - }, /* LabelClass fields initialization */ + NULL, /* extension */ + }, + /* command */ { - 0, /* field not used */ - }, /* CommandClass fields initialization */ + NULL, /* extension */ + }, + /* menu_button */ { - 0, /* field not used */ - } /* MenuButtonClass fields initialization */ + NULL, /* extension */ + }, }; - /* for public consumption */ -WidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec; - -/**************************************************************** - * - * Private Procedures - * - ****************************************************************/ +WidgetClass menuButtonWidgetClass = (WidgetClass)&menuButtonClassRec; -static void ClassInitialize() +/* + * Implementation + */ +static void +XawMenuButtonClassInitialize(void) { XawInitializeWidgetSet(); - XtRegisterGrabAction(PopupMenu, True, - (unsigned int)(ButtonPressMask | ButtonReleaseMask), + XtRegisterGrabAction(PopupMenu, True, + ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync); } -/* ARGSUSED */ +/*ARGSUSED*/ static void -PopupMenu(w, event, params, num_params) -Widget w; -XEvent * event; -String * params; -Cardinal * num_params; +XawMenuButtonInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) { - MenuButtonWidget mbw = (MenuButtonWidget) w; - Widget menu, temp; - Arg arglist[2]; - Cardinal num_args; - int menu_x, menu_y, menu_width, menu_height, button_height; - Position button_x, button_y; - - temp = w; - while(temp != NULL) { - menu = XtNameToWidget(temp, mbw->menu_button.menu_name); - if (menu == NULL) - temp = XtParent(temp); - else - break; - } - - if (menu == NULL) { - char error_buf[BUFSIZ]; - char* errorp; - int len; - char* fmt = "MenuButton: Could not find menu widget named %s."; - - if ((len = strlen (fmt) + strlen (mbw->menu_button.menu_name)) < sizeof error_buf) - errorp = error_buf; - else - errorp = XtMalloc (len + 1); - if (errorp == NULL) { - errorp = error_buf; - strcpy (errorp, "MenuButton: Could not find menu widget."); - } else - (void) sprintf(errorp, fmt, mbw->menu_button.menu_name); - XtAppWarning (XtWidgetToApplicationContext (w), errorp); - if (errorp != error_buf) XtFree (errorp); - return; - } - if (!XtIsRealized(menu)) - XtRealizeWidget(menu); - - menu_width = menu->core.width + 2 * menu->core.border_width; - button_height = w->core.height + 2 * w->core.border_width; - menu_height = menu->core.height + 2 * menu->core.border_width; - - XtTranslateCoords(w, 0, 0, &button_x, &button_y); - menu_x = button_x; - menu_y = button_y + button_height; - - if (menu_x >= 0) { - int scr_width = WidthOfScreen(XtScreen(menu)); - if (menu_x + menu_width > scr_width) - menu_x = scr_width - menu_width; - } - if (menu_x < 0) - menu_x = 0; - - if (menu_y >= 0) { - int scr_height = HeightOfScreen(XtScreen(menu)); - if (menu_y + menu_height > scr_height) - menu_y = scr_height - menu_height; - } - if (menu_y < 0) - menu_y = 0; - - num_args = 0; - XtSetArg(arglist[num_args], XtNx, menu_x); num_args++; - XtSetArg(arglist[num_args], XtNy, menu_y); num_args++; - XtSetValues(menu, arglist, num_args); - - XtPopupSpringLoaded(menu); + MenuButtonWidget mbw = (MenuButtonWidget)cnew; + + if (mbw->menu_button.menu_name != default_menu_name) + mbw->menu_button.menu_name = XtNewString(mbw->menu_button.menu_name); } +static void +XawMenuButtonDestroy(Widget w) +{ + MenuButtonWidget mbw = (MenuButtonWidget)w; + + if (mbw->menu_button.menu_name != default_menu_name) + XtFree(mbw->menu_button.menu_name); +} + +/*ARGSUSED*/ +static Boolean +XawMenuButtonSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) +{ + MenuButtonWidget mbw_old = (MenuButtonWidget)current; + MenuButtonWidget mbw_new = (MenuButtonWidget)cnew; + + if (mbw_old->menu_button.menu_name != mbw_new->menu_button.menu_name) { + if (mbw_old->menu_button.menu_name != default_menu_name) + XtFree(mbw_old->menu_button.menu_name); + if (mbw_new->menu_button.menu_name != default_menu_name) + mbw_new->menu_button.menu_name = + XtNewString(mbw_new->menu_button.menu_name); + } + + return (False); +} + +/*ARGSUSED*/ +static void +PopupMenu(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + MenuButtonWidget mbw = (MenuButtonWidget)w; + Widget menu = NULL, temp; + Arg arglist[2]; + Cardinal num_args; + int menu_x, menu_y, menu_width, menu_height, button_height; + Position button_x, button_y; + + temp = w; + while(temp != NULL) { + menu = XtNameToWidget(temp, mbw->menu_button.menu_name); + if (menu == NULL) + temp = XtParent(temp); + else + break; + } + + if (menu == NULL) { + char error_buf[BUFSIZ]; + + (void)XmuSnprintf(error_buf, sizeof(error_buf), + "MenuButton: Could not find menu widget named %s.", + mbw->menu_button.menu_name); + XtAppWarning(XtWidgetToApplicationContext(w), error_buf); + return; + } + + if (!XtIsRealized(menu)) + XtRealizeWidget(menu); + + menu_width = XtWidth(menu) + (XtBorderWidth(menu) << 1); + button_height = XtHeight(w) + (XtBorderWidth(w) << 1); + menu_height = XtHeight(menu) + (XtBorderWidth(menu) << 1); + + XtTranslateCoords(w, 0, 0, &button_x, &button_y); + menu_x = button_x; + menu_y = button_y + button_height; + + if (menu_y >= 0) { + int scr_height = HeightOfScreen(XtScreen(menu)); + + if (menu_y + menu_height > scr_height) + menu_y = button_y - menu_height; + if (menu_y < 0) { + menu_y = scr_height - menu_height; + menu_x = button_x + XtWidth(w) + (XtBorderWidth(w) << 1); + if (menu_x + menu_width > WidthOfScreen(XtScreen(menu))) + menu_x = button_x - menu_width; + } + } + if (menu_y < 0) + menu_y = 0; + + if (menu_x >= 0) { + int scr_width = WidthOfScreen(XtScreen(menu)); + + if (menu_x + menu_width > scr_width) + menu_x = scr_width - menu_width; + } + if (menu_x < 0) + menu_x = 0; + + num_args = 0; + XtSetArg(arglist[num_args], XtNx, menu_x); num_args++; + XtSetArg(arglist[num_args], XtNy, menu_y); num_args++; + XtSetValues(menu, arglist, num_args); + + XtPopupSpringLoaded(menu); +} |