MenuButton.c revision 421c997b
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/* 277a84e134Smrg * MenuButton.c - Source code for MenuButton widget. 287a84e134Smrg * 297a84e134Smrg * This is the source code for the Athena MenuButton widget. 307a84e134Smrg * It is intended to provide an easy method of activating pulldown menus. 317a84e134Smrg * 327a84e134Smrg * Date: May 2, 1989 337a84e134Smrg * 347a84e134Smrg * By: Chris D. Peterson 35421c997bSmrg * 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/Xaw/MenuButtoP.h> 467a84e134Smrg#include <X11/Xaw/XawInit.h> 477a84e134Smrg#include "Private.h" 487a84e134Smrg 497a84e134Smrg/* 507a84e134Smrg * Class Methods 517a84e134Smrg */ 527a84e134Smrgstatic void XawMenuButtonClassInitialize(void); 537a84e134Smrgstatic void XawMenuButtonInitialize(Widget, Widget, ArgList, Cardinal*); 547a84e134Smrgstatic void XawMenuButtonDestroy(Widget); 557a84e134Smrgstatic Boolean XawMenuButtonSetValues(Widget, Widget, Widget, ArgList, Cardinal*); 567a84e134Smrg 577a84e134Smrg/* 587a84e134Smrg * Actions 597a84e134Smrg */ 607a84e134Smrgstatic void PopupMenu(Widget, XEvent*, String*, Cardinal*); 617a84e134Smrg 627a84e134Smrg/* 637a84e134Smrg * Initialization 647a84e134Smrg */ 657a84e134Smrg#define superclass ((CommandWidgetClass)&commandClassRec) 667a84e134Smrg 67421c997bSmrgstatic char defaultTranslations[] = 687a84e134Smrg"<Enter>:" "highlight()\n" 697a84e134Smrg"<Leave>:" "reset()\n" 707a84e134Smrg"Any<BtnDown>:" "reset() PopupMenu()\n"; 717a84e134Smrg 727a84e134Smrgstatic char default_menu_name[] = "menu"; 737a84e134Smrg 747a84e134Smrg#define offset(field) XtOffsetOf(MenuButtonRec, field) 757a84e134Smrgstatic XtResource resources[] = { 767a84e134Smrg { 777a84e134Smrg XtNmenuName, 787a84e134Smrg XtCMenuName, 797a84e134Smrg XtRString, 807a84e134Smrg sizeof(String), 817a84e134Smrg offset(menu_button.menu_name), 827a84e134Smrg XtRString, 837a84e134Smrg (XtPointer)default_menu_name 847a84e134Smrg }, 857a84e134Smrg}; 867a84e134Smrg#undef offset 877a84e134Smrg 887a84e134Smrgstatic XtActionsRec actionsList[] = 897a84e134Smrg{ 907a84e134Smrg {"PopupMenu", PopupMenu}, 917a84e134Smrg}; 927a84e134Smrg 937a84e134SmrgMenuButtonClassRec menuButtonClassRec = { 947a84e134Smrg /* core */ 957a84e134Smrg { 967a84e134Smrg (WidgetClass)superclass, /* superclass */ 977a84e134Smrg "MenuButton", /* class_name */ 98421c997bSmrg sizeof(MenuButtonRec), /* size */ 997a84e134Smrg XawMenuButtonClassInitialize, /* class_initialize */ 1007a84e134Smrg NULL, /* class_part_initialize */ 1017a84e134Smrg False, /* class_inited */ 1027a84e134Smrg XawMenuButtonInitialize, /* initialize */ 1037a84e134Smrg NULL, /* initialize_hook */ 1047a84e134Smrg XtInheritRealize, /* realize */ 1057a84e134Smrg actionsList, /* actions */ 1067a84e134Smrg XtNumber(actionsList), /* num_actions */ 1077a84e134Smrg resources, /* resources */ 1087a84e134Smrg XtNumber(resources), /* num_resources */ 1097a84e134Smrg NULLQUARK, /* xrm_class */ 1107a84e134Smrg False, /* compress_motion */ 1117a84e134Smrg True, /* compress_exposure */ 1127a84e134Smrg True, /* compress_enterleave */ 1137a84e134Smrg False, /* visible_interest */ 1147a84e134Smrg XawMenuButtonDestroy, /* destroy */ 1157a84e134Smrg XtInheritResize, /* resize */ 1167a84e134Smrg XtInheritExpose, /* expose */ 1177a84e134Smrg XawMenuButtonSetValues, /* set_values */ 1187a84e134Smrg NULL, /* set_values_hook */ 1197a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 1207a84e134Smrg NULL, /* get_values_hook */ 1217a84e134Smrg NULL, /* accept_focus */ 1227a84e134Smrg XtVersion, /* version */ 1237a84e134Smrg NULL, /* callback_private */ 124421c997bSmrg defaultTranslations, /* tm_table */ 1257a84e134Smrg XtInheritQueryGeometry, /* query_geometry */ 1267a84e134Smrg XtInheritDisplayAccelerator, /* display_accelerator */ 1277a84e134Smrg NULL, /* extension */ 1287a84e134Smrg }, 1297a84e134Smrg /* simple */ 1307a84e134Smrg { 131421c997bSmrg XtInheritChangeSensitive /* change_sensitive */ 1327a84e134Smrg }, 1337a84e134Smrg /* label */ 1347a84e134Smrg { 1357a84e134Smrg NULL, /* extension */ 1367a84e134Smrg }, 1377a84e134Smrg /* command */ 1387a84e134Smrg { 1397a84e134Smrg NULL, /* extension */ 1407a84e134Smrg }, 1417a84e134Smrg /* menu_button */ 1427a84e134Smrg { 1437a84e134Smrg NULL, /* extension */ 1447a84e134Smrg }, 1457a84e134Smrg}; 1467a84e134Smrg 1477a84e134SmrgWidgetClass menuButtonWidgetClass = (WidgetClass)&menuButtonClassRec; 1487a84e134Smrg 1497a84e134Smrg/* 1507a84e134Smrg * Implementation 1517a84e134Smrg */ 1527a84e134Smrgstatic void 1537a84e134SmrgXawMenuButtonClassInitialize(void) 1547a84e134Smrg{ 1557a84e134Smrg XawInitializeWidgetSet(); 1567a84e134Smrg XtRegisterGrabAction(PopupMenu, True, 1577a84e134Smrg ButtonPressMask | ButtonReleaseMask, 1587a84e134Smrg GrabModeAsync, GrabModeAsync); 1597a84e134Smrg} 1607a84e134Smrg 1617a84e134Smrg/*ARGSUSED*/ 1627a84e134Smrgstatic void 1637a84e134SmrgXawMenuButtonInitialize(Widget request, Widget cnew, 1647a84e134Smrg ArgList args, Cardinal *num_args) 1657a84e134Smrg{ 1667a84e134Smrg MenuButtonWidget mbw = (MenuButtonWidget)cnew; 1677a84e134Smrg 1687a84e134Smrg if (mbw->menu_button.menu_name != default_menu_name) 1697a84e134Smrg mbw->menu_button.menu_name = XtNewString(mbw->menu_button.menu_name); 1707a84e134Smrg} 1717a84e134Smrg 1727a84e134Smrgstatic void 1737a84e134SmrgXawMenuButtonDestroy(Widget w) 1747a84e134Smrg{ 1757a84e134Smrg MenuButtonWidget mbw = (MenuButtonWidget)w; 1767a84e134Smrg 1777a84e134Smrg if (mbw->menu_button.menu_name != default_menu_name) 1787a84e134Smrg XtFree(mbw->menu_button.menu_name); 1797a84e134Smrg} 1807a84e134Smrg 1817a84e134Smrg/*ARGSUSED*/ 1827a84e134Smrgstatic Boolean 1837a84e134SmrgXawMenuButtonSetValues(Widget current, Widget request, Widget cnew, 1847a84e134Smrg ArgList args, Cardinal *num_args) 1857a84e134Smrg{ 1867a84e134Smrg MenuButtonWidget mbw_old = (MenuButtonWidget)current; 1877a84e134Smrg MenuButtonWidget mbw_new = (MenuButtonWidget)cnew; 1887a84e134Smrg 1897a84e134Smrg if (mbw_old->menu_button.menu_name != mbw_new->menu_button.menu_name) { 1907a84e134Smrg if (mbw_old->menu_button.menu_name != default_menu_name) 1917a84e134Smrg XtFree(mbw_old->menu_button.menu_name); 1927a84e134Smrg if (mbw_new->menu_button.menu_name != default_menu_name) 1937a84e134Smrg mbw_new->menu_button.menu_name = 1947a84e134Smrg XtNewString(mbw_new->menu_button.menu_name); 1957a84e134Smrg } 1967a84e134Smrg 1977a84e134Smrg return (False); 1987a84e134Smrg} 1997a84e134Smrg 2007a84e134Smrg/*ARGSUSED*/ 2017a84e134Smrgstatic void 2027a84e134SmrgPopupMenu(Widget w, XEvent *event, String *params, Cardinal *num_params) 2037a84e134Smrg{ 2047a84e134Smrg MenuButtonWidget mbw = (MenuButtonWidget)w; 2057a84e134Smrg Widget menu = NULL, temp; 2067a84e134Smrg Arg arglist[2]; 2077a84e134Smrg Cardinal num_args; 2087a84e134Smrg int menu_x, menu_y, menu_width, menu_height, button_height; 2097a84e134Smrg Position button_x, button_y; 2107a84e134Smrg 2117a84e134Smrg temp = w; 2127a84e134Smrg while(temp != NULL) { 2137a84e134Smrg menu = XtNameToWidget(temp, mbw->menu_button.menu_name); 214421c997bSmrg if (menu == NULL) 2157a84e134Smrg temp = XtParent(temp); 2167a84e134Smrg else 2177a84e134Smrg break; 2187a84e134Smrg } 2197a84e134Smrg 2207a84e134Smrg if (menu == NULL) { 2217a84e134Smrg char error_buf[BUFSIZ]; 2227a84e134Smrg 223421c997bSmrg snprintf(error_buf, sizeof(error_buf), 224421c997bSmrg "MenuButton: Could not find menu widget named %s.", 225421c997bSmrg mbw->menu_button.menu_name); 2267a84e134Smrg XtAppWarning(XtWidgetToApplicationContext(w), error_buf); 2277a84e134Smrg return; 2287a84e134Smrg } 2297a84e134Smrg 2307a84e134Smrg if (!XtIsRealized(menu)) 2317a84e134Smrg XtRealizeWidget(menu); 232421c997bSmrg 2337a84e134Smrg menu_width = XtWidth(menu) + (XtBorderWidth(menu) << 1); 2347a84e134Smrg button_height = XtHeight(w) + (XtBorderWidth(w) << 1); 2357a84e134Smrg menu_height = XtHeight(menu) + (XtBorderWidth(menu) << 1); 2367a84e134Smrg 2377a84e134Smrg XtTranslateCoords(w, 0, 0, &button_x, &button_y); 2387a84e134Smrg menu_x = button_x; 2397a84e134Smrg menu_y = button_y + button_height; 2407a84e134Smrg 2417a84e134Smrg if (menu_y >= 0) { 2427a84e134Smrg int scr_height = HeightOfScreen(XtScreen(menu)); 2437a84e134Smrg 2447a84e134Smrg if (menu_y + menu_height > scr_height) 2457a84e134Smrg menu_y = button_y - menu_height; 2467a84e134Smrg if (menu_y < 0) { 2477a84e134Smrg menu_y = scr_height - menu_height; 2487a84e134Smrg menu_x = button_x + XtWidth(w) + (XtBorderWidth(w) << 1); 2497a84e134Smrg if (menu_x + menu_width > WidthOfScreen(XtScreen(menu))) 2507a84e134Smrg menu_x = button_x - menu_width; 2517a84e134Smrg } 2527a84e134Smrg } 2537a84e134Smrg if (menu_y < 0) 2547a84e134Smrg menu_y = 0; 2557a84e134Smrg 2567a84e134Smrg if (menu_x >= 0) { 2577a84e134Smrg int scr_width = WidthOfScreen(XtScreen(menu)); 2587a84e134Smrg 2597a84e134Smrg if (menu_x + menu_width > scr_width) 2607a84e134Smrg menu_x = scr_width - menu_width; 2617a84e134Smrg } 262421c997bSmrg if (menu_x < 0) 2637a84e134Smrg menu_x = 0; 2647a84e134Smrg 2657a84e134Smrg num_args = 0; 2667a84e134Smrg XtSetArg(arglist[num_args], XtNx, menu_x); num_args++; 2677a84e134Smrg XtSetArg(arglist[num_args], XtNy, menu_y); num_args++; 2687a84e134Smrg XtSetValues(menu, arglist, num_args); 2697a84e134Smrg 2707a84e134Smrg XtPopupSpringLoaded(menu); 2717a84e134Smrg} 272