749N/A/* $XConsortium: MenuButton.c,v 1.21 95/06/26 20:35:12 kaleb Exp $ */
749N/A
749N/A/*
749N/ACopyright (c) 1989, 1994 X Consortium
749N/A
749N/APermission is hereby granted, free of charge, to any person obtaining a copy
749N/Aof this software and associated documentation files (the "Software"), to deal
749N/Ain the Software without restriction, including without limitation the rights
749N/Ato use, copy, modify, merge, publish, distribute, sublicense, and/or sell
749N/Acopies of the Software, and to permit persons to whom the Software is
749N/Afurnished to do so, subject to the following conditions:
749N/A
749N/AThe above copyright notice and this permission notice shall be included in
749N/Aall copies or substantial portions of the Software.
749N/A
749N/ATHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
749N/AIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
749N/AFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
749N/AX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
749N/AAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
749N/ACONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
749N/A
749N/AExcept as contained in this notice, the name of the X Consortium shall not be
749N/Aused in advertising or otherwise to promote the sale, use or other dealings
749N/Ain this Software without prior written authorization from the X Consortium.
749N/A *
749N/A */
749N/A
749N/A
749N/A/***********************************************************************
749N/A *
749N/A * MenuButton Widget
749N/A *
749N/A ***********************************************************************/
749N/A
749N/A/*
749N/A * MenuButton.c - Source code for MenuButton widget.
749N/A *
749N/A * This is the source code for the Athena MenuButton widget.
749N/A * It is intended to provide an easy method of activating pulldown menus.
749N/A *
749N/A * Date: May 2, 1989
749N/A *
749N/A * By: Chris D. Peterson
749N/A * MIT X Consortium
749N/A * kit@expo.lcs.mit.edu
749N/A */
749N/A
749N/A#include <stdio.h>
749N/A#include <X11/IntrinsicP.h>
749N/A#include <X11/StringDefs.h>
749N/A
749N/A#include <X11/Xaw/XawInit.h>
749N/A#include <X11/Xaw/MenuButtoP.h>
749N/A
749N/Astatic void ClassInitialize();
749N/Astatic void PopupMenu();
749N/A
749N/A#define superclass ((CommandWidgetClass)&commandClassRec)
749N/A
749N/Astatic char defaultTranslations[] =
749N/A"<EnterWindow>: highlight()\n\
749N/A <LeaveWindow>: reset()\n\
749N/A Any<BtnDown>: reset() PopupMenu()";
749N/A
749N/A/****************************************************************
749N/A *
749N/A * Full class record constant
749N/A *
749N/A ****************************************************************/
749N/A
749N/A/* Private Data */
749N/A
749N/A#define offset(field) XtOffsetOf(MenuButtonRec, field)
749N/Astatic XtResource resources[] = {
749N/A {
749N/A XtNmenuName, XtCMenuName, XtRString, sizeof(String),
749N/A offset(menu_button.menu_name), XtRString, (XtPointer)"menu"},
749N/A};
749N/A#undef offset
749N/A
749N/Astatic XtActionsRec actionsList[] =
749N/A{
749N/A {"PopupMenu", PopupMenu}
749N/A};
749N/A
749N/AMenuButtonClassRec menuButtonClassRec = {
749N/A {
749N/A (WidgetClass) superclass, /* superclass */
749N/A "MenuButton", /* class_name */
749N/A sizeof(MenuButtonRec), /* size */
749N/A ClassInitialize, /* class_initialize */
749N/A NULL, /* class_part_initialize */
749N/A FALSE, /* class_inited */
749N/A NULL, /* initialize */
749N/A NULL, /* initialize_hook */
749N/A XtInheritRealize, /* realize */
749N/A actionsList, /* actions */
749N/A XtNumber(actionsList), /* num_actions */
749N/A resources, /* resources */
749N/A XtNumber(resources), /* resource_count */
749N/A NULLQUARK, /* xrm_class */
749N/A FALSE, /* compress_motion */
749N/A TRUE, /* compress_exposure */
749N/A TRUE, /* compress_enterleave */
749N/A FALSE, /* visible_interest */
749N/A NULL, /* destroy */
749N/A XtInheritResize, /* resize */
749N/A XtInheritExpose, /* expose */
749N/A NULL, /* set_values */
749N/A NULL, /* set_values_hook */
749N/A XtInheritSetValuesAlmost, /* set_values_almost */
749N/A NULL, /* get_values_hook */
749N/A NULL, /* accept_focus */
749N/A XtVersion, /* version */
749N/A NULL, /* callback_private */
749N/A defaultTranslations, /* tm_table */
749N/A XtInheritQueryGeometry, /* query_geometry */
749N/A XtInheritDisplayAccelerator, /* display_accelerator */
749N/A NULL /* extension */
749N/A }, /* CoreClass fields initialization */
749N/A {
749N/A XtInheritChangeSensitive /* change_sensitive */
749N/A }, /* SimpleClass fields initialization */
749N/A {
749N/A 0, /* field not used */
749N/A }, /* LabelClass fields initialization */
749N/A {
749N/A 0, /* field not used */
749N/A }, /* CommandClass fields initialization */
749N/A {
749N/A 0, /* field not used */
749N/A } /* MenuButtonClass fields initialization */
749N/A};
749N/A
749N/A /* for public consumption */
749N/AWidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec;
749N/A
749N/A/****************************************************************
749N/A *
749N/A * Private Procedures
749N/A *
749N/A ****************************************************************/
749N/A
749N/Astatic void ClassInitialize()
749N/A{
749N/A XawInitializeWidgetSet();
749N/A XtRegisterGrabAction(PopupMenu, True,
749N/A (unsigned int)(ButtonPressMask | ButtonReleaseMask),
749N/A GrabModeAsync, GrabModeAsync);
749N/A}
749N/A
749N/A/* ARGSUSED */
749N/Astatic void
749N/APopupMenu(w, event, params, num_params)
749N/AWidget w;
749N/AXEvent * event;
749N/AString * params;
749N/ACardinal * num_params;
749N/A{
749N/A MenuButtonWidget mbw = (MenuButtonWidget) w;
749N/A Widget menu, temp;
749N/A Arg arglist[2];
749N/A Cardinal num_args;
749N/A int menu_x, menu_y, menu_width, menu_height, button_height;
749N/A Position button_x, button_y;
749N/A
749N/A temp = w;
749N/A while(temp != NULL) {
749N/A menu = XtNameToWidget(temp, mbw->menu_button.menu_name);
749N/A if (menu == NULL)
749N/A temp = XtParent(temp);
749N/A else
749N/A break;
749N/A }
749N/A
749N/A if (menu == NULL) {
749N/A char error_buf[BUFSIZ];
749N/A char* errorp;
749N/A int len;
749N/A char* fmt = "MenuButton: Could not find menu widget named %s.";
749N/A
749N/A if ((len = strlen (fmt) + strlen (mbw->menu_button.menu_name)) < sizeof error_buf)
749N/A errorp = error_buf;
749N/A else
749N/A errorp = XtMalloc (len + 1);
749N/A if (errorp == NULL) {
749N/A errorp = error_buf;
749N/A strcpy (errorp, "MenuButton: Could not find menu widget.");
749N/A } else
749N/A (void) sprintf(errorp, fmt, mbw->menu_button.menu_name);
749N/A XtAppWarning (XtWidgetToApplicationContext (w), errorp);
749N/A if (errorp != error_buf) XtFree (errorp);
749N/A return;
749N/A }
749N/A if (!XtIsRealized(menu))
749N/A XtRealizeWidget(menu);
749N/A
749N/A menu_width = menu->core.width + 2 * menu->core.border_width;
749N/A button_height = w->core.height + 2 * w->core.border_width;
749N/A menu_height = menu->core.height + 2 * menu->core.border_width;
749N/A
749N/A XtTranslateCoords(w, 0, 0, &button_x, &button_y);
749N/A menu_x = button_x;
749N/A menu_y = button_y + button_height;
749N/A
749N/A if (menu_x >= 0) {
749N/A int scr_width = WidthOfScreen(XtScreen(menu));
749N/A if (menu_x + menu_width > scr_width)
749N/A menu_x = scr_width - menu_width;
749N/A }
749N/A if (menu_x < 0)
749N/A menu_x = 0;
749N/A
749N/A if (menu_y >= 0) {
749N/A int scr_height = HeightOfScreen(XtScreen(menu));
749N/A if (menu_y + menu_height > scr_height)
749N/A menu_y = scr_height - menu_height;
749N/A }
749N/A if (menu_y < 0)
749N/A menu_y = 0;
749N/A
749N/A num_args = 0;
749N/A XtSetArg(arglist[num_args], XtNx, menu_x); num_args++;
749N/A XtSetArg(arglist[num_args], XtNy, menu_y); num_args++;
749N/A XtSetValues(menu, arglist, num_args);
749N/A
749N/A XtPopupSpringLoaded(menu);
749N/A}
749N/A