1135 lines
31 KiB
C
1135 lines
31 KiB
C
|
#ifndef lint
|
|||
|
static char sccs_id[] = "@(#)menu.c 5.2 6/5/89";
|
|||
|
#endif
|
|||
|
|
|||
|
/*
|
|||
|
* Copyright 1988 by Siemens Research and Technology Laboratories, Princeton, NJ
|
|||
|
*
|
|||
|
* All Rights Reserved
|
|||
|
*
|
|||
|
* Permission to use, copy, modify, and distribute this software and its
|
|||
|
* documentation for any purpose and without fee is hereby granted,
|
|||
|
* provided that the above copyright notice appear in all copies and that
|
|||
|
* both that copyright notice and this permission notice appear in
|
|||
|
* supporting documentation, and that the name of Siemens Research and Technology
|
|||
|
* Laboratories not be used in advertising or publicity pertaining to
|
|||
|
* distribution of the software without specific, written prior permission.
|
|||
|
*
|
|||
|
*
|
|||
|
* SIEMENS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|||
|
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|||
|
* SIEMENS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|||
|
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|||
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|||
|
* SOFTWARE.
|
|||
|
*/
|
|||
|
#include <stdlib.h>
|
|||
|
#include "copyright.h"
|
|||
|
|
|||
|
/*
|
|||
|
RTL Menu Package Version 1.2
|
|||
|
by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1988
|
|||
|
|
|||
|
menu.c: menu utility and support functions.
|
|||
|
|
|||
|
Originally hacked by Adam J. Richter, based on the menu package for xterm.
|
|||
|
( misc.c X10/6.6 )
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
|
|||
|
Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
|
|||
|
|
|||
|
Permission to use, copy, modify, and distribute this
|
|||
|
software and its documentation for any purpose and without
|
|||
|
fee is hereby granted, provided that the above copyright
|
|||
|
notice appear in all copies and that both that copyright
|
|||
|
notice and this permission notice appear in supporting
|
|||
|
documentation, and that the name of M.I.T. not be used in
|
|||
|
advertising or publicity pertaining to distribution of the
|
|||
|
software without specific, written prior permission.
|
|||
|
M.I.T. makes no representations about the suitability of
|
|||
|
this software for any purpose. It is provided "as is"
|
|||
|
without express or implied warranty.
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
|||
|
*
|
|||
|
* All Rights Reserved
|
|||
|
*
|
|||
|
* Permission to use, copy, modify, and distribute this software and its
|
|||
|
* documentation for any purpose and without fee is hereby granted,
|
|||
|
* provided that the above copyright notice appear in all copies and that
|
|||
|
* both that copyright notice and this permission notice appear in
|
|||
|
* supporting documentation, and that the name of Digital Equipment
|
|||
|
* Corporation not be used in advertising or publicity pertaining to
|
|||
|
* distribution of the software without specific, written prior permission.
|
|||
|
*
|
|||
|
*
|
|||
|
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|||
|
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|||
|
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|||
|
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|||
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|||
|
* SOFTWARE.
|
|||
|
*/
|
|||
|
|
|||
|
#include "rtlmenuP.h"
|
|||
|
#include <X11/X10.h>
|
|||
|
#include "gray1_32.h" /* filled out to 32x32 pixels (works on color) */
|
|||
|
#include "arrow_icon.h"
|
|||
|
#include "arrow_ic32.h" /* filled out to 32x32 pixels (works on color) */
|
|||
|
#include "check_ic32.h"
|
|||
|
#define MakeEven(x) ((x%2 == 0)? x : x-1)
|
|||
|
#define InvertPlane 1
|
|||
|
|
|||
|
static char def_menu_font[] = "8x13";
|
|||
|
Menu MenuDefault;
|
|||
|
char *MenuDefaultFont;
|
|||
|
static XAssocTable *menu_table;
|
|||
|
static XAssocTable *item_table;
|
|||
|
static bool tables_initialized = FALSE;
|
|||
|
RTLMenuItem AddMenuItem(), Display_Menu(), MenuGetItem(),
|
|||
|
MenuItemByName(), MenuItemByData(), GetInitialItem();
|
|||
|
bool DisposeItem(), SetItemCheck(), SetItemDisable(),
|
|||
|
SetItemText();
|
|||
|
void DisposeMenu(), InitMenu(), Undisplay_Menu(), MenuInvert(),
|
|||
|
PlacePointer(), Draw_Menu(), Draw_Item(), SetInitialItem(),
|
|||
|
ClearInitialItem();
|
|||
|
RTLMenu NewMenu(), MenuGetMenu();
|
|||
|
int ItemGetMiddleY();
|
|||
|
|
|||
|
static bool Recalc_Menu(RTLMenu menu);
|
|||
|
static RTLMenuItem MoveMenu(RTLMenu menu, int ev_x, int ev_y);
|
|||
|
static bool MapMenu(RTLMenu menu);
|
|||
|
static void Generate_Menu_Entries(RTLMenu menu);
|
|||
|
static void UnmapMenu(RTLMenu menu);
|
|||
|
static bool SetupMenuWindow(RTLMenu menu);
|
|||
|
static bool SetupItems(RTLMenu menu);
|
|||
|
static void SetInputMask(RTLMenu menu, Mask mask);
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* AddMenuItem() adds a menu item to an existing menu, at the end of the
|
|||
|
* list, which are number sequentially from zero. The menuitem index is
|
|||
|
* return, or NULL if failed.
|
|||
|
*/
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
AddMenuItem(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
RTLMenuItem menuitem, *next;
|
|||
|
|
|||
|
if(!menu || ItemIsNull(menuitem = (RTLMenuItem)allocate(MenuItem, 1)))
|
|||
|
return(NULLITEM);
|
|||
|
bzero((char *)menuitem, sizeof(MenuItem));
|
|||
|
ItemText(menuitem) = NULL;
|
|||
|
ItemTextLength(menuitem) = 0;
|
|||
|
|
|||
|
for(next = MenuItemsPtr(menu) ;
|
|||
|
*next; next = ItemNextPtr(*next));
|
|||
|
|
|||
|
*next = menuitem;
|
|||
|
|
|||
|
SetMenuFlag(menu, menuChanged);
|
|||
|
|
|||
|
return(menuitem);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* DisposeItem() releases the memory allocated for the given indexed
|
|||
|
* menuitem. Nonzero is returned if an item was actual disposed of.
|
|||
|
* It also checks to see whether the item we're disposing is the
|
|||
|
* initial item for the menu -- if so, null out the initial item.
|
|||
|
*/
|
|||
|
bool
|
|||
|
DisposeItem(menu, item)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
{
|
|||
|
RTLMenuItem *next, *last, menuitem;
|
|||
|
|
|||
|
if (MenuIsNull(menu) || ItemIsNull(item))
|
|||
|
return(FALSE);
|
|||
|
next = MenuItemsPtr(menu);
|
|||
|
do
|
|||
|
{
|
|||
|
if(ItemIsNull(*next))
|
|||
|
return(FALSE);
|
|||
|
last = next;
|
|||
|
next = ItemNextPtr(*next);
|
|||
|
}
|
|||
|
while((*last != item) && !ItemIsNull(*next));
|
|||
|
menuitem = *last;
|
|||
|
*last = *next;
|
|||
|
if (ItemWindow(menuitem)) {
|
|||
|
XDeleteAssoc(MenuDisplay((Menu *)menu),
|
|||
|
item_table, ItemWindow(menuitem));
|
|||
|
XDestroyWindow(MenuDisplay((Menu *)menu), ItemWindow(menuitem));
|
|||
|
}
|
|||
|
if (ItemIsInitialItem(menu, menuitem))
|
|||
|
ClearInitialItem(menu);
|
|||
|
|
|||
|
str_free(ItemText(menuitem));
|
|||
|
free((char*)menuitem);
|
|||
|
|
|||
|
SetMenuFlag(menu, menuChanged);
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* DisposeMenu() releases the memory allocated for the given menu.
|
|||
|
*/
|
|||
|
void
|
|||
|
DisposeMenu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
if(!menu)
|
|||
|
return;
|
|||
|
if (TestMenuFlag(menu, menuMapped))
|
|||
|
UnmapMenu(menu);
|
|||
|
while(DisposeItem(menu, MenuItems(menu)));
|
|||
|
if(MenuWindow(menu)) {
|
|||
|
XDeleteAssoc(MenuDisplay(menu), menu_table, MenuWindow((Menu *)menu));
|
|||
|
XDestroyWindow(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
}
|
|||
|
XFreePixmap (MenuDisplay(menu), MenuGreyPixmap(menu));
|
|||
|
XFreePixmap (MenuDisplay(menu), MenuArrowPixmap(menu));
|
|||
|
XFreePixmap (MenuDisplay(menu), MenuCheckmarkPixmap(menu));
|
|||
|
XFreeGC (MenuDisplay(menu), MenuNormalGC(menu));
|
|||
|
XFreeGC (MenuDisplay(menu), MenuInvertGC(menu));
|
|||
|
XFreeGC (MenuDisplay(menu), MenuHighlightedGC(menu));
|
|||
|
|
|||
|
if (MenuHasInitialItem(menu))
|
|||
|
ClearInitialItem(menu);
|
|||
|
free((char*) menu);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
InitMenu(name, options, display)
|
|||
|
char *name;
|
|||
|
RTLMenuOptionsMask options;
|
|||
|
Display *display;
|
|||
|
{
|
|||
|
char *cp;
|
|||
|
|
|||
|
MenuDefault.display = display;
|
|||
|
MenuDefault.menuFlags = menuChanged;
|
|||
|
|
|||
|
MenuDefault.menuInitialItemText = (char *) NULL;
|
|||
|
MenuDefault.menuBorderWidth =
|
|||
|
(cp = XGetDefault(MenuDefault.display, name, "MenuBorder")) ?
|
|||
|
atoi(cp) : 1;
|
|||
|
MenuDefault.menuItemPad =
|
|||
|
(cp = XGetDefault(MenuDefault.display, name, "MenuPad")) ? atoi(cp) : 3;
|
|||
|
MenuDefault.delta = Default_Delta;
|
|||
|
/* Find a font to use -- check for defaults */
|
|||
|
cp = XGetDefault(MenuDefault.display, name, "MenuFont");
|
|||
|
if (cp == NULL)
|
|||
|
cp = XGetDefault(MenuDefault.display, name, "Font");
|
|||
|
MenuDefaultFont = (cp == NULL)? def_menu_font : cp;
|
|||
|
|
|||
|
MenuDefault.menuOptions = options;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* ItemText changes the text of item of the menu.
|
|||
|
*/
|
|||
|
bool
|
|||
|
SetItemText(menu, item, text)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
char *text;
|
|||
|
{
|
|||
|
if (streql(ItemText(item), text))
|
|||
|
return (TRUE);
|
|||
|
|
|||
|
str_replace(ItemText(item), text);
|
|||
|
|
|||
|
ItemTextLength(item) = str_length(text);
|
|||
|
SetMenuFlag(menu, menuChanged);
|
|||
|
|
|||
|
(void) Recalc_Menu (menu);
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* NewMenu() returns a pointer to an initialized new Menu structure, or NULL
|
|||
|
* if failed. The Menu structure MenuDefault contains the default menu settings.
|
|||
|
*/
|
|||
|
RTLMenu
|
|||
|
NewMenu(display, screen, reverse)
|
|||
|
Display *display;
|
|||
|
int screen;
|
|||
|
int reverse;
|
|||
|
{
|
|||
|
extern Pixmap MakeGreyStipple ();
|
|||
|
RTLMenu menu;
|
|||
|
|
|||
|
XGCValues gcValues, invertGCValues;
|
|||
|
static unsigned long gcMask =
|
|||
|
GCFunction | GCForeground | GCBackground | GCFont | GCStipple;
|
|||
|
static unsigned long invertgcMask = GCFont | GCFunction | GCForeground;
|
|||
|
|
|||
|
/* Allocate the memory for the menu structure. */
|
|||
|
if(MenuIsNull((menu = (RTLMenu)allocate(Menu, 1))))
|
|||
|
return(NULLMENU);
|
|||
|
|
|||
|
/* Initialize to default values. */
|
|||
|
*(Menu *)menu = MenuDefault;
|
|||
|
|
|||
|
/* set options mask */
|
|||
|
MenuDisplay(menu) = display;
|
|||
|
MenuScreen(menu) = screen;
|
|||
|
|
|||
|
/* If the menu font hasn't yet been gotten, go get it. */
|
|||
|
/* Try to open selected default font. If that failes, check to see */
|
|||
|
/* if the one we#re opening is the "fall back" default, def_menu_font-- */
|
|||
|
/* if it is, exit. Otherwise, try def_menu_font -- if that fails, exit */
|
|||
|
if ((MenuFontInfo(menu) = XLoadQueryFont (display, MenuDefaultFont))
|
|||
|
== NULL)
|
|||
|
{
|
|||
|
if (!strcmp(MenuDefaultFont,def_menu_font))
|
|||
|
{
|
|||
|
fprintf(stderr, "rtl: couldn't open font \"%s\"\n",
|
|||
|
MenuDefaultFont);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ((MenuFontInfo(menu) = XLoadQueryFont (display, def_menu_font))
|
|||
|
== NULL)
|
|||
|
{
|
|||
|
fprintf(stderr, "rtl: couldn't open font \"%s\" or \"%s\"\n",
|
|||
|
MenuDefaultFont, def_menu_font);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
gcValues.font = MenuFontInfo(menu)->fid;
|
|||
|
|
|||
|
/* If the menu cursor hasn't been given, make a default one. */
|
|||
|
MenuCursor(menu) = XCreateFontCursor (MenuDisplay(menu), XC_right_ptr);
|
|||
|
|
|||
|
/* Make miscellaneous pixmaps */
|
|||
|
MenuArrowPixmap(menu) = XCreateBitmapFromData (MenuDisplay(menu),
|
|||
|
RootWindow (display, screen),
|
|||
|
arrow_32_bits,
|
|||
|
arrow_32_width,
|
|||
|
arrow_32_height);
|
|||
|
MenuGreyPixmap(menu) = XCreateBitmapFromData (display,
|
|||
|
RootWindow (display, screen),
|
|||
|
gray1_32_bits,
|
|||
|
gray1_32_width,
|
|||
|
gray1_32_height);
|
|||
|
MenuCheckmarkPixmap(menu) = XCreateBitmapFromData (MenuDisplay(menu),
|
|||
|
RootWindow (display, screen),
|
|||
|
check_32_bits,
|
|||
|
check_32_width,
|
|||
|
check_32_height);
|
|||
|
/*
|
|||
|
* Initialize the default background and border pixmaps and foreground
|
|||
|
* and background colors (black and white).
|
|||
|
*/
|
|||
|
if(reverse) {
|
|||
|
gcValues.foreground = WhitePixel (display, screen);
|
|||
|
gcValues.background = BlackPixel (display, screen);
|
|||
|
} else {
|
|||
|
gcValues.foreground = BlackPixel (display, screen);
|
|||
|
gcValues.background = WhitePixel (display, screen);
|
|||
|
}
|
|||
|
gcValues.stipple = MenuGreyPixmap(menu);
|
|||
|
gcValues.function = GXcopy;
|
|||
|
gcValues.subwindow_mode = IncludeInferiors;
|
|||
|
gcValues.graphics_exposures = False;
|
|||
|
MenuNormalGC(menu) =
|
|||
|
XCreateGC (display, RootWindow (display, screen),
|
|||
|
gcMask | GCSubwindowMode | GCGraphicsExposures, &gcValues);
|
|||
|
invertGCValues = gcValues;
|
|||
|
invertGCValues.foreground = gcValues.background;
|
|||
|
invertGCValues.background = gcValues.foreground;
|
|||
|
MenuHighlightedGC(menu) = XCreateGC (display, RootWindow (display, screen),
|
|||
|
gcMask, &invertGCValues);
|
|||
|
|
|||
|
gcValues.function = GXxor;
|
|||
|
gcValues.foreground = BlackPixel(MenuDisplay(menu), MenuScreen(menu)) ^
|
|||
|
WhitePixel(MenuDisplay(menu),MenuScreen(menu));
|
|||
|
MenuInvertGC(menu) = XCreateGC (display, RootWindow (display, screen),
|
|||
|
invertgcMask, &gcValues);
|
|||
|
|
|||
|
return(menu);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* SetItemCheck sets the check state of item of the menu to "state".
|
|||
|
*/
|
|||
|
bool
|
|||
|
SetItemCheck(menu, item, state)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
int state;
|
|||
|
{
|
|||
|
if (TestItemFlag(item,itemChecked)
|
|||
|
== state) /* Exit if unchanged */
|
|||
|
return (True);
|
|||
|
|
|||
|
if (state)
|
|||
|
SetItemFlag(item, itemChecked);
|
|||
|
else
|
|||
|
ResetItemFlag(item, itemChecked);
|
|||
|
|
|||
|
SetItemFlag(item, itemChanged);
|
|||
|
SetMenuFlag(menu, menuItemChanged);
|
|||
|
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* SetItemDisable sets the disable state of item "n" of the menu to "state".
|
|||
|
*/
|
|||
|
bool
|
|||
|
SetItemDisable(menu, item, state)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
int state;
|
|||
|
{
|
|||
|
if (TestItemFlag(item,itemDisabled) == state) /* Exit if unchanged */
|
|||
|
return (True);
|
|||
|
|
|||
|
if(state)
|
|||
|
{
|
|||
|
SetItemFlag(item, itemDisabled);
|
|||
|
/* if disabled item is currently initial item, null initial item */
|
|||
|
if (ItemIsInitialItem(menu, item))
|
|||
|
ClearInitialItem(menu);
|
|||
|
}
|
|||
|
else
|
|||
|
ResetItemFlag(item, itemDisabled);
|
|||
|
|
|||
|
SetItemFlag(item, itemChanged);
|
|||
|
SetMenuFlag(menu, menuItemChanged);
|
|||
|
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
Display_Menu(menu, parent, x, y)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenu parent;
|
|||
|
int x;
|
|||
|
int y;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
if (MenuIsNull(menu))
|
|||
|
return(FALSE);
|
|||
|
|
|||
|
SetMenuParent(menu, parent);
|
|||
|
|
|||
|
if (MenuIsNull(parent))
|
|||
|
MenuNested(menu) = 0;
|
|||
|
else
|
|||
|
MenuNested(menu) = MenuNested(parent) + 1;
|
|||
|
|
|||
|
if (!SetupMenuWindow(menu))
|
|||
|
return NULL;
|
|||
|
if (TestOptionFlag(menu,savebits) &&
|
|||
|
(MenuSavedPixmap(menu) != (Pixmap) 0))
|
|||
|
SetInputMask(menu, MenuIgnoreMask);
|
|||
|
else
|
|||
|
SetInputMask(menu, MenuExposureMask);
|
|||
|
|
|||
|
Generate_Menu_Entries(menu);
|
|||
|
if (!(item = MoveMenu(menu, x, y)) || !MapMenu(menu))
|
|||
|
return FALSE;
|
|||
|
|
|||
|
Draw_Menu(menu);
|
|||
|
|
|||
|
return(item);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
Undisplay_Menu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
if (MenuIsNull(menu))
|
|||
|
return;
|
|||
|
|
|||
|
SetMenuParent(menu, NULLMENU);
|
|||
|
MenuNested(menu) = 0;
|
|||
|
|
|||
|
UnmapMenu(menu);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
MenuInvert(menu, w)
|
|||
|
RTLMenu menu;
|
|||
|
Window w;
|
|||
|
{
|
|||
|
XFillRectangle (MenuDisplay(menu),
|
|||
|
w,
|
|||
|
MenuInvertGC(menu),
|
|||
|
0, 0,
|
|||
|
MenuWidth(menu),
|
|||
|
MenuItemHeight(menu));
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Recalculate all of the various menu and item variables.
|
|||
|
*/
|
|||
|
static bool
|
|||
|
Recalc_Menu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
int max, height, fontheight;
|
|||
|
|
|||
|
/*
|
|||
|
* We must have already gotten the menu font.
|
|||
|
*/
|
|||
|
if(!MenuFontInfo(menu))
|
|||
|
return(FALSE);
|
|||
|
/*
|
|||
|
* Initialize the various max width variables.
|
|||
|
*/
|
|||
|
fontheight = MenuFontInfo(menu)->ascent + MenuFontInfo(menu)->descent + 2;
|
|||
|
height = 0;
|
|||
|
MenuMaxTextWidth(menu) = 0;
|
|||
|
/*
|
|||
|
* The item height is the maximum of the font height and the
|
|||
|
* checkbox height.
|
|||
|
*/
|
|||
|
max = fontheight;
|
|||
|
if(checkMarkHeight > max)
|
|||
|
max = checkMarkHeight;
|
|||
|
|
|||
|
max += 2*ItemBorder;
|
|||
|
max = MakeEven(max);
|
|||
|
MenuItemHeight(menu) = max;
|
|||
|
|
|||
|
/*
|
|||
|
* Go through the menu item list.
|
|||
|
*/
|
|||
|
for(item = MenuItems(menu) ; item ;
|
|||
|
item = ItemNext(item))
|
|||
|
{
|
|||
|
height += max;
|
|||
|
/*
|
|||
|
* Check the text width with the max value stored in
|
|||
|
* menu.
|
|||
|
*/
|
|||
|
if((ItemTextWidth(item) =
|
|||
|
XTextWidth(MenuFontInfo(menu),
|
|||
|
ItemText(item),
|
|||
|
str_length (ItemText(item))))
|
|||
|
> MenuMaxTextWidth(menu))
|
|||
|
MenuMaxTextWidth(menu) = ItemTextWidth(item);
|
|||
|
}
|
|||
|
/*
|
|||
|
* Set the menu height and then set the menu width.
|
|||
|
*/
|
|||
|
MenuHeight(menu) = height;
|
|||
|
MenuWidth(menu) = 4 * MenuItemPad(menu) + MenuMaxTextWidth(menu) +
|
|||
|
checkMarkWidth + arrow_width + (2 * ItemBorder);
|
|||
|
MenuItemWidth(menu) = MenuWidth(menu) - (2 * ItemBorder);
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Figure out where to popup the menu, relative to the where the button was
|
|||
|
* pressed.
|
|||
|
* Returns pointer to initial item to warp to.
|
|||
|
*/
|
|||
|
static RTLMenuItem
|
|||
|
MoveMenu(menu, ev_x, ev_y)
|
|||
|
RTLMenu menu;
|
|||
|
int ev_x, ev_y;
|
|||
|
{
|
|||
|
int x, y;
|
|||
|
int total_width, total_height;
|
|||
|
int offset;
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
/*
|
|||
|
* Get the coordinates of the mouse when the button was pressed.
|
|||
|
*/
|
|||
|
total_width = MenuWidth(menu) + 2 * MenuBorderWidth(menu);
|
|||
|
total_height = MenuHeight(menu) + 2 * MenuBorderWidth(menu);
|
|||
|
x = ev_x - MenuItemPad(menu);
|
|||
|
y = ev_y - MenuItemHeight(menu)/2;
|
|||
|
if (x < 0)
|
|||
|
x = 0;
|
|||
|
else if (TestOptionFlag(menu, rightoffset) &&
|
|||
|
!MenuIsNull(MenuParent(menu)))
|
|||
|
{
|
|||
|
/* check whether parent is close to right edge... */
|
|||
|
/* "too close" means that child would leave < delta of its parent */
|
|||
|
/* visible to its left. */
|
|||
|
if (TestOptionFlag(menu, bigoffset))
|
|||
|
{
|
|||
|
if (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) >
|
|||
|
DisplayWidth(MenuDisplay(menu), MenuScreen(menu)) - total_width)
|
|||
|
x = MenuX(MenuParent(menu))
|
|||
|
- total_width + 2*MenuBorderWidth(menu);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (MenuX(MenuParent(menu)) + MenuDelta(MenuParent(menu)) >
|
|||
|
DisplayWidth(MenuDisplay(menu), MenuScreen(menu)) - total_width)
|
|||
|
{
|
|||
|
x = (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) +
|
|||
|
2 * MenuBorderWidth(MenuParent(menu))
|
|||
|
- total_width - MenuDelta(menu));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (x + total_width > DisplayWidth(MenuDisplay(menu), MenuScreen(menu)))
|
|||
|
x = DisplayWidth(MenuDisplay(menu), MenuScreen(menu))
|
|||
|
- total_width;
|
|||
|
|
|||
|
/*
|
|||
|
* If we have an initial item, try to popup the menu centered
|
|||
|
* vertically within this item.
|
|||
|
*/
|
|||
|
if(MenuHasInitialItem(menu)) {
|
|||
|
/*
|
|||
|
* Look through the item list. "y" is the vertical position
|
|||
|
* of the top of the current item and "n" is the item number.
|
|||
|
*/
|
|||
|
y = ev_y;
|
|||
|
offset = MenuBorderWidth(menu);
|
|||
|
for(item = MenuItems(menu) ; ;) {
|
|||
|
/*
|
|||
|
* On finding the intial item, center within this item.
|
|||
|
*/
|
|||
|
if(ItemIsInitialItem(menu, item)) {
|
|||
|
offset += MenuItemHeight(menu) / 2;
|
|||
|
y -= offset;
|
|||
|
break;
|
|||
|
}
|
|||
|
offset += MenuItemHeight(menu);
|
|||
|
/*
|
|||
|
* If we run out of items, turn off the initial item
|
|||
|
* and treat this as if no initial item.
|
|||
|
*/
|
|||
|
if(!(item = ItemNext(item))) {
|
|||
|
ClearInitialItem(menu);
|
|||
|
y = ev_y - MenuItemHeight(menu)/2;
|
|||
|
goto noInitial;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
noInitial:
|
|||
|
if (y < 0)
|
|||
|
y = 0;
|
|||
|
else if (y + total_height >
|
|||
|
DisplayHeight(MenuDisplay(menu), MenuScreen(menu)))
|
|||
|
{
|
|||
|
y = DisplayHeight(MenuDisplay(menu), MenuScreen(menu))
|
|||
|
- (total_height + 1);
|
|||
|
}
|
|||
|
y = MakeEven(y) + 1;
|
|||
|
if ((x != ev_x) || (y != ev_y))
|
|||
|
XMoveWindow(MenuDisplay(menu), MenuWindow(menu), x, y);
|
|||
|
MenuX(menu) = x;
|
|||
|
MenuY(menu) = y;
|
|||
|
|
|||
|
if (!ItemIsInitialItem(menu, item))
|
|||
|
item = MenuItems(menu);
|
|||
|
return(item);
|
|||
|
}
|
|||
|
|
|||
|
static
|
|||
|
bool MapMenu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
if (! TestMenuFlag(menu, menuMapped))
|
|||
|
ResetMenuItemHighlighted(menu);
|
|||
|
if (TestOptionFlag(menu,savebits))
|
|||
|
{
|
|||
|
if ((MenuSavedPixmap(menu) == (Pixmap) 0) ||
|
|||
|
(MenuOldWidth(menu) != MenuWidth(menu)) ||
|
|||
|
(MenuOldHeight(menu) != MenuHeight(menu)) ||
|
|||
|
(MenuOldBorderWidth(menu) != MenuBorderWidth(menu)))
|
|||
|
{
|
|||
|
if (MenuSavedPixmap(menu) != (Pixmap) 0)
|
|||
|
XFreePixmap(MenuDisplay(menu), MenuSavedPixmap(menu));
|
|||
|
MenuSavedPixmap(menu) =
|
|||
|
XCreatePixmap(MenuDisplay(menu),
|
|||
|
RootWindow(MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
MenuWidth(menu) + 2*MenuBorderWidth(menu),
|
|||
|
MenuHeight(menu) + 2*MenuBorderWidth(menu),
|
|||
|
DefaultDepth(MenuDisplay(menu), MenuScreen(menu)));
|
|||
|
MenuOldWidth(menu) = MenuWidth(menu);
|
|||
|
MenuOldHeight(menu) = MenuHeight(menu);
|
|||
|
MenuOldBorderWidth(menu) = MenuBorderWidth(menu);
|
|||
|
}
|
|||
|
else
|
|||
|
SetInputMask(menu, MenuExposureMask);
|
|||
|
|
|||
|
if (MenuSavedPixmap(menu) != (Pixmap) 0) {
|
|||
|
SetInputMask(menu, MenuIgnoreMask);
|
|||
|
XCopyArea(MenuDisplay(menu),
|
|||
|
RootWindow(MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
MenuSavedPixmap(menu),
|
|||
|
MenuNormalGC(menu),
|
|||
|
MenuX(menu),
|
|||
|
MenuY(menu),
|
|||
|
(unsigned int) (MenuWidth(menu) + 2*MenuBorderWidth(menu)),
|
|||
|
(unsigned int) (MenuHeight(menu) + 2*MenuBorderWidth(menu)),
|
|||
|
0, 0);
|
|||
|
}
|
|||
|
else
|
|||
|
SetInputMask(menu, MenuExposureMask);
|
|||
|
}
|
|||
|
XRaiseWindow(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
XMapWindow(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
SetMenuFlag(menu, menuMapped);
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
PlacePointer(menu, item)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
{
|
|||
|
int y;
|
|||
|
|
|||
|
y = ItemGetMiddleY(item);
|
|||
|
XWarpPointer(MenuDisplay(menu), None,
|
|||
|
RootWindow(MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
0, 0, 0, 0,
|
|||
|
MenuX(menu) + MenuItemPad(menu), y);
|
|||
|
}
|
|||
|
|
|||
|
void AdjustPointer(menu, x, y)
|
|||
|
RTLMenu menu;
|
|||
|
int x, y;
|
|||
|
{
|
|||
|
if (y == 0)
|
|||
|
XWarpPointer(MenuDisplay(menu), None,
|
|||
|
RootWindow(MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
0, 0, 0, 0, x, 1);
|
|||
|
else if (y == (DisplayHeight(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)) - 1))
|
|||
|
XWarpPointer(MenuDisplay(menu), None,
|
|||
|
RootWindow(MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
0, 0, 0, 0,
|
|||
|
x, DisplayHeight(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)) - 2);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void
|
|||
|
Generate_Menu_Entries (menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
for (item = MenuItems(menu); item; (item = ItemNext(item))) {
|
|||
|
if (ItemGenerator(item)) {
|
|||
|
char *newText;
|
|||
|
|
|||
|
(ItemGenerator(item)) (&newText, &ItemCallback(item));
|
|||
|
SetItemText (menu, item, newText);
|
|||
|
}
|
|||
|
|
|||
|
if (ItemCheckproc(item))
|
|||
|
SetItemCheck (menu, item, (ItemCheckproc(item))(menu,item));
|
|||
|
}
|
|||
|
(void) SetupMenuWindow (menu);
|
|||
|
}
|
|||
|
|
|||
|
/* Draw the entire menu in the blank window. */
|
|||
|
void
|
|||
|
Draw_Menu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
ResetMenuFlag(menu, menuChanged);
|
|||
|
/* For each item in the list, first draw any check mark and then
|
|||
|
draw the rest of it. */
|
|||
|
for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
|
|||
|
if (TestOptionFlag(menu, savebits))
|
|||
|
{
|
|||
|
/* go ahead and draw it, don't wait for exposes */
|
|||
|
Draw_Item(menu, item, 0, 0, (int)MenuWidth(menu),(int)MenuItemHeight(menu));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Draw the item at vertical position y.
|
|||
|
*/
|
|||
|
void
|
|||
|
Draw_Item(menu, item, fill_x, fill_y, fill_width, fill_height)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
int fill_x, fill_y, fill_width, fill_height;
|
|||
|
{
|
|||
|
int y; /* baseline */
|
|||
|
int x = MenuItemPad(menu);
|
|||
|
int x1 = 2 * MenuItemPad(menu) + checkMarkWidth;
|
|||
|
int pad;
|
|||
|
int high;
|
|||
|
XGCValues gcValues;
|
|||
|
|
|||
|
if (TestItemFlag(item, itemDisabled))
|
|||
|
{
|
|||
|
gcValues.fill_style = FillOpaqueStippled;
|
|||
|
XChangeGC(MenuDisplay(menu), MenuNormalGC(menu),
|
|||
|
(GCFillStyle), &gcValues);
|
|||
|
}
|
|||
|
|
|||
|
high = (MenuItemHighlighted(menu) == item);
|
|||
|
|
|||
|
if (high)
|
|||
|
{
|
|||
|
XSetFunction(MenuDisplay(menu), MenuNormalGC(menu), GXset);
|
|||
|
XFillRectangle(MenuDisplay(menu), ItemWindow(item),
|
|||
|
MenuNormalGC(menu), fill_x, fill_y,
|
|||
|
fill_width, fill_height);
|
|||
|
XSetFunction(MenuDisplay(menu), MenuNormalGC(menu), GXcopyInverted);
|
|||
|
}
|
|||
|
else
|
|||
|
XClearArea(MenuDisplay(menu), ItemWindow(item),
|
|||
|
fill_x, fill_y, fill_width, fill_height, False);
|
|||
|
|
|||
|
/*
|
|||
|
* Draw the check mark, possibly dimmed, wherever is necessary.
|
|||
|
*/
|
|||
|
if(TestItemFlag(item, itemChecked)){
|
|||
|
XCopyPlane (MenuDisplay(menu), MenuCheckmarkPixmap(menu),
|
|||
|
ItemWindow(item),
|
|||
|
MenuNormalGC(menu),
|
|||
|
0, 0, check_32_width, check_32_height,
|
|||
|
(int) x, (MenuItemHeight(menu) - checkMarkHeight) / 2,
|
|||
|
(unsigned long) 1);
|
|||
|
}
|
|||
|
|
|||
|
/* Draw submenu indicator arrow */
|
|||
|
if(ItemSubmenu(item)) {
|
|||
|
XCopyPlane (MenuDisplay(menu), MenuArrowPixmap(menu),
|
|||
|
ItemWindow(item),
|
|||
|
MenuNormalGC(menu),
|
|||
|
0, 0,
|
|||
|
arrow_32_width, arrow_32_height,
|
|||
|
(int) (x + MenuItemWidth(menu) -
|
|||
|
arrow_width - MenuItemPad(menu)),
|
|||
|
(MenuItemHeight(menu) - arrow_height) / 2 - 1,
|
|||
|
(unsigned long) 1);
|
|||
|
}
|
|||
|
/*
|
|||
|
* Draw the text, centered vertically.
|
|||
|
*/
|
|||
|
pad = (MenuItemHeight(menu) -
|
|||
|
(MenuFontInfo(menu)->ascent + MenuFontInfo(menu)->descent)) / 2;
|
|||
|
y = MenuItemHeight(menu) - pad - MenuFontInfo(menu)->descent;
|
|||
|
|
|||
|
XDrawString (MenuDisplay(menu), ItemWindow(item),
|
|||
|
(high? MenuHighlightedGC(menu) : MenuNormalGC(menu)),
|
|||
|
x1, y, ItemText(item), ItemTextLength(item));
|
|||
|
if (high)
|
|||
|
XSetFunction(MenuDisplay(menu), MenuNormalGC(menu), GXcopy);
|
|||
|
if (TestItemFlag(item, itemDisabled))
|
|||
|
{
|
|||
|
gcValues.fill_style = FillSolid;
|
|||
|
XChangeGC(MenuDisplay(menu), MenuNormalGC(menu),
|
|||
|
(GCFillStyle), &gcValues);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* UnmapMenu() unmaps a menu, if it is currently mapped.
|
|||
|
*/
|
|||
|
static void
|
|||
|
UnmapMenu(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
if(!menu || !(TestMenuFlag(menu, menuMapped)))
|
|||
|
return;
|
|||
|
XUnmapWindow(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
/* XClearWindow (MenuDisplay(menu), MenuWindow(menu));*/
|
|||
|
|
|||
|
if (TestOptionFlag(menu, savebits))
|
|||
|
{
|
|||
|
if (MenuSavedPixmap(menu))
|
|||
|
XCopyArea (MenuDisplay(menu),
|
|||
|
MenuSavedPixmap(menu),
|
|||
|
RootWindow (MenuDisplay(menu), MenuScreen(menu)),
|
|||
|
MenuNormalGC(menu),
|
|||
|
0, 0,
|
|||
|
MenuWidth(menu) + 2*MenuBorderWidth(menu),
|
|||
|
MenuHeight(menu) + 2*MenuBorderWidth(menu),
|
|||
|
MenuX(menu), MenuY(menu));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ResetMenuFlag(menu, menuMapped);
|
|||
|
}
|
|||
|
|
|||
|
static bool
|
|||
|
SetupMenuWindow (menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
|
|||
|
|
|||
|
if (tables_initialized == FALSE) {
|
|||
|
tables_initialized = TRUE;
|
|||
|
if ((menu_table = XCreateAssocTable(Menu_Table_Size))
|
|||
|
== (XAssocTable *) NULL)
|
|||
|
return FALSE;
|
|||
|
if ((item_table = XCreateAssocTable(Item_Table_Size))
|
|||
|
== (XAssocTable *) NULL)
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* If the entire menu has changed, throw away any saved pixmap and
|
|||
|
* then call RecalcMenu().
|
|||
|
*/
|
|||
|
|
|||
|
if(changed & menuChanged) {
|
|||
|
if(!Recalc_Menu(menu))
|
|||
|
return FALSE;
|
|||
|
changed &= ~menuItemChanged;
|
|||
|
}
|
|||
|
|
|||
|
if(!MenuWindow(menu)) {
|
|||
|
static unsigned long valuemask =
|
|||
|
CWOverrideRedirect | CWBorderPixel | CWBackPixel;
|
|||
|
XSetWindowAttributes attributes;
|
|||
|
|
|||
|
attributes.override_redirect = True;
|
|||
|
attributes.border_pixel =
|
|||
|
XBlackPixel (MenuDisplay(menu), MenuScreen(menu));
|
|||
|
attributes.background_pixel =
|
|||
|
XWhitePixel (MenuDisplay(menu), MenuScreen(menu));
|
|||
|
|
|||
|
if((MenuWindow(menu) =
|
|||
|
XCreateWindow(MenuDisplay(menu),
|
|||
|
RootWindow (MenuDisplay(menu),
|
|||
|
MenuScreen(menu)),
|
|||
|
0, 0,
|
|||
|
MenuWidth(menu), MenuHeight(menu),
|
|||
|
MenuBorderWidth(menu),
|
|||
|
DefaultDepth(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)),
|
|||
|
InputOutput,
|
|||
|
DefaultVisual(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)),
|
|||
|
valuemask, &attributes)
|
|||
|
) == (Window)0)
|
|||
|
return FALSE;
|
|||
|
else if (SetupItems(menu) == FALSE)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
XMakeAssoc(MenuDisplay(menu), menu_table, MenuWindow(menu),
|
|||
|
(char *) menu);
|
|||
|
XMapSubwindows(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
|
|||
|
XDefineCursor(MenuDisplay(menu), MenuWindow(menu),
|
|||
|
MenuCursor(menu));
|
|||
|
}
|
|||
|
else if(changed & menuChanged) {
|
|||
|
XResizeWindow(MenuDisplay(menu), MenuWindow(menu),
|
|||
|
MenuWidth(menu), MenuHeight(menu));
|
|||
|
if (SetupItems(menu) == FALSE)
|
|||
|
return FALSE;
|
|||
|
XMapSubwindows(MenuDisplay(menu), MenuWindow(menu));
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
static bool
|
|||
|
SetupItems(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
int y;
|
|||
|
RTLMenuItem item;
|
|||
|
int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
|
|||
|
|
|||
|
for (item = MenuItems(menu), y = 0;
|
|||
|
item;
|
|||
|
y += MenuItemHeight(menu), item = ItemNext(item)) {
|
|||
|
if (!ItemWindow(item)) {
|
|||
|
static unsigned long valuemask =
|
|||
|
CWOverrideRedirect | CWBorderPixel | CWBackPixel;
|
|||
|
XSetWindowAttributes attributes;
|
|||
|
attributes.override_redirect = True;
|
|||
|
attributes.border_pixel =
|
|||
|
XBlackPixel (MenuDisplay(menu), MenuScreen(menu));
|
|||
|
attributes.background_pixel =
|
|||
|
XWhitePixel (MenuDisplay(menu), MenuScreen(menu));
|
|||
|
|
|||
|
if((ItemWindow(item) =
|
|||
|
XCreateWindow(MenuDisplay(menu),
|
|||
|
MenuWindow(menu),
|
|||
|
0, y,
|
|||
|
MenuItemWidth(menu),
|
|||
|
MenuItemHeight(menu)-(2 * ItemBorder),
|
|||
|
ItemBorder,
|
|||
|
DefaultDepth(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)),
|
|||
|
InputOutput,
|
|||
|
DefaultVisual(MenuDisplay(menu),
|
|||
|
MenuScreen(menu)),
|
|||
|
valuemask, &attributes)
|
|||
|
) == (Window) 0)
|
|||
|
return FALSE;
|
|||
|
SetItemMenu(item, menu);
|
|||
|
XMakeAssoc(MenuDisplay(menu), item_table, ItemWindow(item),
|
|||
|
(char *) item);
|
|||
|
XDefineCursor(MenuDisplay(menu), ItemWindow(item),
|
|||
|
MenuCursor(menu));
|
|||
|
}
|
|||
|
else if(changed & menuChanged) {
|
|||
|
XResizeWindow(MenuDisplay(menu), ItemWindow(item),
|
|||
|
MenuItemWidth(menu),
|
|||
|
MenuItemHeight(menu) - (2 * ItemBorder));
|
|||
|
XMoveWindow(MenuDisplay(menu), ItemWindow(item), 0, y);
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
SetInputMask(menu, mask)
|
|||
|
RTLMenu menu;
|
|||
|
Mask mask;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
XSelectInput(MenuDisplay(menu), MenuWindow(menu),
|
|||
|
(mask | MenuEventMask));
|
|||
|
for(item = MenuItems(menu) ; item ; item = ItemNext(item))
|
|||
|
{
|
|||
|
if (TestItemFlag(item, itemDisabled))
|
|||
|
XSelectInput(MenuDisplay(menu), ItemWindow(item),
|
|||
|
(mask | NormalItemEventMask));
|
|||
|
else if (ItemIsLeaf(item))
|
|||
|
XSelectInput(MenuDisplay(menu), ItemWindow(item),
|
|||
|
(mask | NormalItemEventMask));
|
|||
|
else
|
|||
|
XSelectInput(MenuDisplay(menu), ItemWindow(item),
|
|||
|
(mask | SubmenuItemEventMask));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
MenuItemByData(menu, data)
|
|||
|
RTLMenu menu;
|
|||
|
generic data;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
for (item = MenuItems(menu);
|
|||
|
!ItemIsNull(item) && !EqualGen(ItemData(item), data);
|
|||
|
item = ItemNext(item));
|
|||
|
|
|||
|
return item;
|
|||
|
}
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
MenuItemByName (menu, name)
|
|||
|
RTLMenu menu;
|
|||
|
char *name;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
for (item = MenuItems(menu); item; item = ItemNext(item))
|
|||
|
if (streql (name, ItemText(item)))
|
|||
|
return item;
|
|||
|
return NULLITEM;
|
|||
|
}
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
MenuGetItem(menu, window)
|
|||
|
RTLMenu menu;
|
|||
|
Window window;
|
|||
|
{
|
|||
|
return (RTLMenuItem)(XLookUpAssoc(MenuDisplay(menu), item_table, window));
|
|||
|
}
|
|||
|
|
|||
|
RTLMenu
|
|||
|
MenuGetMenu(menu, window)
|
|||
|
RTLMenu menu;
|
|||
|
Window window;
|
|||
|
{
|
|||
|
return (RTLMenu )(XLookUpAssoc(MenuDisplay(menu), menu_table, window));
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
ItemGetMiddleY(item)
|
|||
|
RTLMenuItem item;
|
|||
|
{
|
|||
|
Window child;
|
|||
|
XWindowAttributes attributes;
|
|||
|
int x, y;
|
|||
|
|
|||
|
XGetWindowAttributes(MenuDisplay(ItemMenu(item)), ItemWindow(item),
|
|||
|
&attributes);
|
|||
|
XTranslateCoordinates(MenuDisplay(ItemMenu(item)),
|
|||
|
MenuWindow(ItemMenu(item)),
|
|||
|
RootWindow(MenuDisplay(ItemMenu(item)),
|
|||
|
MenuScreen(ItemMenu(item))),
|
|||
|
attributes.x, attributes.y,
|
|||
|
&x, &y, &child);
|
|||
|
return MakeEven(y + (MenuItemHeight(ItemMenu(item))/2));
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
SetInitialItem(menu, item)
|
|||
|
RTLMenu menu;
|
|||
|
RTLMenuItem item;
|
|||
|
{
|
|||
|
|
|||
|
if (MenuHasInitialItem(menu)) {
|
|||
|
if (str_length(MenuInitialItemText(menu)) < str_length(ItemText(item)))
|
|||
|
MenuInitialItemText(menu) =
|
|||
|
realloc(MenuInitialItemText(menu),
|
|||
|
str_length(ItemText(item)) + 1);
|
|||
|
}
|
|||
|
else
|
|||
|
MenuInitialItemText(menu) =
|
|||
|
allocate(char,(str_length(ItemText(item)) + 1));
|
|||
|
str_copy(MenuInitialItemText(menu), ItemText(item));
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
ClearInitialItem(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
if (MenuHasInitialItem(menu)) {
|
|||
|
free(MenuInitialItemText(menu));
|
|||
|
MenuInitialItemText(menu) = (char *) NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RTLMenuItem
|
|||
|
GetInitialItem(menu)
|
|||
|
RTLMenu menu;
|
|||
|
{
|
|||
|
RTLMenuItem item;
|
|||
|
|
|||
|
if (MenuHasInitialItem(menu)) {
|
|||
|
for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
|
|||
|
if (ItemIsInitialItem(menu, item))
|
|||
|
return(item);
|
|||
|
}
|
|||
|
}
|
|||
|
return((RTLMenuItem) NULL);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|