|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: M T
Length: 39613 (0x9abd)
Types: TextFile
Names: »MenuMgr.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Toolkit/Xr/src/Xrlib/Dialog/MenuMgr.c«
/*
* $Source: /u1/Xr/src/Xrlib/Dialog/RCS/MenuMgr.c,v $
* $Header: MenuMgr.c,v 1.1 86/12/17 08:58:20 swick Exp $
*/
#ifndef lint
static char *rcsid_MenuMgr_c = "$Header: MenuMgr.c,v 1.1 86/12/17 08:58:20 swick Exp $";
#endif lint
#include <Xr/xr-copyright.h>
/* $Header: MenuMgr.c,v 1.1 86/12/17 08:58:20 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */
static char rcsid[] = "$Header: MenuMgr.c,v 1.1 86/12/17 08:58:20 swick Exp $";
/*************************************<+>*************************************
*****************************************************************************
**
** File: MenuMgr.c
**
** Project: X-ray Toolbox
**
** Description: X-ray Toolbox menu manager.
**
**
**
** ------------------------ MODIFICATION RECORD ------------------------
*
* $Log: MenuMgr.c,v $
* Revision 1.1 86/12/17 08:58:20 swick
* Initial revision
*
* Revision 7.0 86/11/13 08:26:50 08:26:50 ed ()
* Final QA release
*
* Revision 6.1 86/11/11 19:50:33 19:50:33 ed ()
* Fixed: strcmp not sent NULL any longer (SUN fix).
*
* Revision 6.0 86/11/10 15:35:50 15:35:50 ed ()
* QA #2 release
*
* Revision 5.5 86/11/10 15:07:04 15:07:04 ed ()
* removed ref to string.h
*
* Revision 5.4 86/11/07 14:08:17 14:08:17 ed ()
* Fixed: Borderwidth menu posting bug.
* Added procedure headers, new copyright message.
*
* Revision 5.2 86/11/06 11:29:04 11:29:04 ed ()
* Fixed: Submenu remains posted even if cursor is in another menu.
* Activate Menu now deactivates current menu (if any).
* Cannot activate and deactivate non text items.
* Menu language parser default case no works.
*
* Revision 5.1 86/10/30 09:53:35 09:53:35 ed ()
* Freeze server before function call, check ADDWINDOWFUNCT return value.
*
* Revision 5.0 86/10/28 08:20:19 08:20:19 ed ()
* QA #1.1 release
*
* Revision 4.2 86/10/27 13:45:23 13:45:23 ed ()
* Changed to use new XrInputMap().
*
* Revision 4.1 86/10/26 16:28:34 16:28:34 ed ()
* Now uses cursor from menu context.
*
* Revision 4.0 86/10/20 12:09:09 12:09:09 ed ()
* QA #1 release
*
* Revision 3.11 86/10/19 21:28:48 21:28:48 ed ()
* Linted, register variables, prepared for Beta release.
*
* Revision 3.10 86/10/18 16:57:44 16:57:44 ed ()
* Changed MSG_FREE to remove WINDOWFUNCTS.
*
*
* Revision 3.9 86/10/17 12:36:44 12:36:44 ed ()
* Adjusted menu positioning heuristic.
*
* Revision 3.8 86/10/16 19:59:57 19:59:57 ed ()
* Currentpath and Currentwindow work. Modified item language parser.
*
* Revision 3.7 86/10/15 21:43:44 21:43:44 ed ()
* Memory management changes
*
* Revision 3.6 86/10/14 16:44:44 16:44:44 ed ()
* Added item functs and item events
*
* Revision 3.5 86/10/13 20:44:35 20:44:35 ed ()
* Added Keyboard equivalent functionality.
*
* Revision 3.4 86/10/10 08:57:43 08:57:43 ed ()
* More drawing changes.
*
* Revision 3.3 86/10/09 22:04:13 22:04:13 ed ()
* Moved popup array to editor data structure.
* (code changes for this move)
*
* Revision 3.2 86/10/09 08:08:07 08:08:07 ed ()
* Added color stuff, changed menu cursor to default cursor.
*
* Revision 3.1 86/10/08 09:35:43 09:35:43 ed ()
* Modified to use new XrMapButton.
*
* Revision 3.0 86/10/02 16:02:47 16:02:47 ed ()
* Alpha Release set to 3.0
*
* Revision 1.4 86/09/30 10:26:28 10:26:28 ed ()
* Missed a printf.
*
* Revision 1.3 86/09/29 15:38:16 15:38:16 ed ()
* Added grabmouse code, Added code to adjust menu if it would
* have gone off the display.
*
*
* Revision 1.2 86/09/28 19:23:35 19:23:35 ed ()
* Removed printf's for alpha release.
*
* Revision 1.1 86/09/28 19:12:56 19:12:56 ed ()
* Initial revision
*
*****************************************************************************
*************************************<+>*************************************/
#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>
#include <Xr/in_types.h>
#include <ctype.h>
static INT32 xrDisplayWidth;
static INT32 xrDisplayHeight;
extern void addKeybdEquiv();
\f
/*************************************<->*************************************
*
* XrMenu(menuInstance, message, data)
*
* xrMenu * menuInstance;
* INT32 message;
* INT8 * data;
*
* Description:
* -----------
* This is the menu manager. It provides a pop-up, cascading
* menuing system for the X-ray toolbox. The most important
* message for the programmer are MSG_NEW and MSG_ACTIVATEMENU.
* MSG_NEW creates the menu, MSG_ACTIVATEMENU associates it
* with a registered X-ray window. Output form the menu
* manager is returned transparently to the program by the
* XrInput() module. The programmer will not normally call
* the menu manager for input directly.
*
* The other messages support the modification and query of
* the menu structure including sub-menu support. For a complete
* description of the menu manager, refer to the X-ray toolbox
* manual.
*
*
* Inputs:
* ------
* menuInstance = This value indicates to the menu manager,
* which menu should be dealt with.
*
* message = Contains the command to be executed.
*
* data = Varies depending on the message, But is generally
* a pointer to a structure.
*
*
* Outputs:
* -------
* menuInstance = Returned from MSG_NEW.
*
* TRUE = Returned upon successful completion of a message.
*
* NULL = Returned if something went wrong.
*
* xrError = The error variable is set to one of several values
* upon failure of this routine.
*
* Procedures Called
* -----------------
* MSG_NEW:
* (* xrMalloc)()
* (* xrFree)()
* DisplayHeight() - XLib
* DisplayWidth() - XLib
* strcmp()
* XrMenuEdit() - MenuEdit.c
* XCreateWindow() - XLib
* XQueryWindow() - XLib
* XSelectInput() - XLib
* XrCopyRect() - calc.c
* XrInput() - input.c
*
* MSG_EDIT:
* XrInput() - input.c
* XGrabServer() - XLib
* XGrabMouse() - XLib
* XQueryMouseButtons() - XLib
* XQueryMouse() - XLib
* XPixmapSave() - XLib
* XMoveWindow() - XLib
* XMapWindow() - XLib
* XrMenuEdit() - MenuEdit.c
* XUnmapTransparent() - XLib
* XPixmapPut() - XLib
* XFreePixmap() - XLib
* XrMapButton() - XLib
* XSync() - XLib
* XUngrabMouse() - XLib
* XUngrabServer() - XLib
* XFlush() - XLib
*
* MSG_KEYBDEQUIV:
* XrInput() - input.c
* XrInputMap() - inputlib.c
* XSync() - XLib
*
* MSG_FREE:
* (* xrFree)()
* XrInput() - input.c
* XrMenuEdit() - MenuEdit.c
* XDestroyWindow() - XLib
*
* MSG_ACTIVATEMENU:
* XrGetWindowEvent() - input.c
* XrInput() - input.c
* addKeybdEquiv()
*
* MSG_DEACTIVATEMENU:
* XrInput() - input.c
*
*
*
*************************************<->***********************************/
xrMenu *
XrMenu (menuInstance, message, data)
register xrMenu * menuInstance;
INT32 message;
INT8 * data;
{
/******************************************************************
*
* Process the messages sent to the menu manager.
*
******************************************************************/
switch (message) {
case MSG_NEW:
{
register xrMenu * mnuInstance;
register INT32 i;
register xrMenuInfo * mnuInfo;
xrMenuEditor * mnuEditor;
xrWindowData mnuWindowData;
WindowInfo winInfo;
register INT32 currentChar;
register INT32 parsing;
INT32 disabled;
/* coerce data to proper type for MSG_NEW */
mnuInfo = (xrMenuInfo *) data;
/* validate menu infomation pointer */
if ( mnuInfo == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* malloc space for the menu structures */
if ((mnuInstance = (xrMenu *) (*xrMalloc)(sizeof(xrMenu))) == NULL) {
xrErrno = XrOUTOFMEM;
return ((xrMenu *) NULL);
}
if ((mnuEditor =
(xrMenuEditor *) (*xrMalloc)(sizeof(xrMenuEditor))) == NULL) {
xrErrno = XrOUTOFMEM;
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
if ((mnuEditor -> menuStrings =
(INT8 **) (*xrMalloc)(sizeof(INT8 *) * (mnuInfo -> numItems)))
== NULL) {
xrErrno = XrOUTOFMEM;
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
if ((mnuEditor -> itemTypes =
(INT32 *) (*xrMalloc)(sizeof(INT32) * (mnuInfo -> numItems)))
== NULL)
{
xrErrno = XrOUTOFMEM;
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
if ((mnuEditor -> stringLengths =
(INT32 *) (*xrMalloc)(sizeof(INT32) * (mnuInfo -> numItems)))
== NULL)
{
xrErrno = XrOUTOFMEM;
(* xrFree) (mnuEditor -> itemTypes);
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
if ((mnuEditor -> keybdEquiv =
(INT16 *) (*xrMalloc)(sizeof(INT16) * (mnuInfo -> numItems)))
== NULL)
{
xrErrno = XrOUTOFMEM;
(* xrFree) (mnuEditor -> stringLengths);
(* xrFree) (mnuEditor -> itemTypes);
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
/***************************************************************
*
* Fill out the menu and menu editor structures created
* above by transferring the info structure information.
*
****************************************************************/
xrDisplayHeight = DisplayHeight();
xrDisplayWidth = DisplayWidth();
if (mnuInfo -> menuTitle)
{
if (! strcmp(mnuInfo -> menuTitle, ""))
mnuEditor -> menuTitle = NULL;
else
mnuEditor -> menuTitle = mnuInfo -> menuTitle;
}
else
{
mnuEditor -> menuTitle = NULL;
}
mnuEditor -> numItems = mnuInfo -> numItems;
if (!(mnuInfo -> menuContext))
mnuInfo -> menuContext = &xrPanelContextDefaults;
mnuEditor -> editorFont = mnuInfo -> menuContext -> fontInfo;
mnuEditor -> editorFGColor = mnuInfo -> menuContext -> foregroundColor;
mnuEditor -> editorBGColor = mnuInfo -> menuContext -> backgroundColor;
for (i=0; i < mnuEditor -> numItems; i++)
{
mnuEditor -> menuStrings[i] = mnuInfo -> menuItems[i];
mnuEditor -> keybdEquiv[i] = NULL;
disabled = 0;
currentChar = 0;
parsing = 1;
while(parsing)
{
if (mnuEditor -> menuStrings[i][0] == '\\')
{
switch (mnuEditor -> menuStrings[i][1])
{
case '-':
if(currentChar == 0)
mnuEditor -> itemTypes[i] = XrLINE;
parsing = 0;
break;
case '=':
if(currentChar == 0)
mnuEditor -> itemTypes[i] = XrDBLINE;
parsing = 0;
break;
case 'D':
mnuEditor -> menuStrings[i] += 3;
currentChar += 3;
mnuEditor -> itemTypes[i] = XrUSTRING;
mnuEditor -> stringLengths[i] =
strlen(mnuEditor -> menuStrings[i]);
disabled = 1;
break;
case 'K':
if(isalpha(mnuEditor ->menuStrings[i][3]))
{
mnuEditor -> keybdEquiv[i] =
mnuEditor -> menuStrings[i][3];
}
if(! disabled)
mnuEditor -> itemTypes[i] = XrSTRING;
mnuEditor -> menuStrings[i] += 4;
currentChar +=4;
mnuEditor -> stringLengths[i] =
strlen(mnuEditor -> menuStrings[i]);
break;
default:
mnuEditor -> itemTypes[i] = XrSTRING;
mnuEditor -> stringLengths[i] =
strlen(mnuEditor -> menuStrings[i]);
parsing = 0;
break;
}
}
else
{
if (! disabled)
mnuEditor -> itemTypes[i] = XrSTRING;
parsing = 0;
}
}
mnuEditor -> stringLengths[i] = strlen(mnuEditor -> menuStrings[i]);
}
mnuInstance -> pathLength = 0;
mnuInstance -> numWindows = 0;
mnuInstance -> menuId = mnuInfo -> menuId;
mnuInstance -> menuCursor = mnuInfo -> menuContext -> cursor;
mnuInstance -> borderWidth = mnuInfo -> menuContext -> borderWidth;
for (i=0; i < XrMAXMENUWINDOWS - 1; i++)
{
mnuInstance -> currentWindows[i] = NULL;
}
/* Information for menu editor is ready, get the size */
/* and create the editor */
if (XrMenuEdit(NULL, MSG_SIZE, mnuEditor) == NULL)
{
/* error out and return */
xrErrno = XrOUTOFMEM;
(* xrFree) (mnuEditor -> keybdEquiv);
(* xrFree) (mnuEditor -> stringLengths);
(* xrFree) (mnuEditor -> itemTypes);
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
if ( (mnuInstance -> menuWindow =
XCreateWindow( RootWindow, 0, 0,
mnuEditor -> editorRect.width,
mnuEditor -> editorRect.height,
mnuInfo -> menuContext -> borderWidth,
mnuInfo -> menuContext -> winForeground,
mnuInfo -> menuContext -> winBackground))
== NULL)
{
/* error out and return NULL */
xrErrno = XrOUTOFMEM;
(* xrFree) (mnuEditor -> keybdEquiv);
(* xrFree) (mnuEditor -> stringLengths);
(* xrFree) (mnuEditor -> itemTypes);
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
XQueryWindow(mnuInstance -> menuWindow, &winInfo);
mnuInstance -> totalWidth = winInfo.width + winInfo.bdrwidth * 2;
mnuInstance -> totalHeight = winInfo.height + winInfo.bdrwidth * 2;
if (mnuInstance -> totalWidth > xrDisplayWidth ||
mnuInstance -> totalHeight > xrDisplayHeight)
{
xrErrno = XrINVALIDPARM;
(* xrFree) (mnuEditor -> keybdEquiv);
(* xrFree) (mnuEditor -> stringLengths);
(* xrFree) (mnuEditor -> itemTypes);
(* xrFree)(mnuEditor -> menuStrings);
(* xrFree)(mnuEditor);
(* xrFree)(mnuInstance);
return ((xrMenu *) NULL);
}
mnuEditor -> editorWindowId = mnuInstance -> menuWindow;
XSelectInput (mnuInstance -> menuWindow, ButtonPressed | ButtonReleased
| EnterWindow | LeaveWindow);
XrCopyRect(&xrZeroRect, &mnuWindowData.windowRect);
mnuWindowData.foreTile = mnuInfo -> menuContext -> winForeground;
mnuWindowData.backTile = mnuInfo -> menuContext -> winBackground;
XrInput(mnuInstance -> menuWindow, MSG_ADDWINDOW, &mnuWindowData);
mnuInstance -> menuEditor = XrMenuEdit(NULL, MSG_NEW, mnuEditor);
mnuInstance -> menuEditor -> editorState = XrVISIBLE | XrSENSITIVE;
(* xrFree) (mnuEditor);
return (mnuInstance);
break;
} /* MSG_NEW end */
case MSG_EDIT:
{
register xrMenu * currentMenu;
register xrMenu * newMenu;
XButtonEvent * menuKey;
xrMenu * mainMenu;
xrEvent menuEditKey;
XEnterWindowEvent enterKey;
static xrEvent buildKey = {XrXRAY, 0, 0, XrMENU, 0, 0, 0,
{0, 0}, 0};
static xrEvent nullKey = {0, 0, 0, 0, 0, 0, 0,
{0, 0}, 0};
xrEvent * returnKey;
INT32 originX, originY, cursorX, cursorY, outsideMenu;
register INT32 menuing, numMenus;
register INT32 menuIndex;
Window subw;
xrMenuData * menuData;
INT16 state;
if ((menuKey = (XButtonEvent *) data) == NULL ||
(menuKey -> type != ButtonPressed &&
menuKey -> type != ButtonReleased))
{
XrInput(NULL, MSG_PUSHEVENT, menuKey);
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
XrInput(NULL, MSG_PUSHEVENT, menuKey);
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* Check to make sure the user hasn't released the button */
XGrabMouse(RootWindow, menuInstance -> menuCursor,
ButtonPressed | ButtonReleased | EnterWindow | LeaveWindow);
XQueryMouseButtons(RootWindow, &originX, &originY, &subw, &state);
if((state == 0) && ((xrMenuItemSelect == XrRIGHTBUTTONUP) ||
(xrMenuItemSelect == XrLEFTBUTTONUP) ||
(xrMenuItemSelect == XrMIDDLEBUTTONUP)))
{
XUngrabMouse();
XrInput(NULL, MSG_PUSHEVENT, &nullKey);
return((xrMenu *) TRUE);
}
XGrabServer();
buildKey.source = menuKey -> window;
numMenus = 0;
currentMenu = (xrMenu *) NULL;
newMenu = mainMenu = menuInstance;
mainMenu -> currentPath[numMenus].menuInstance = newMenu;
mainMenu -> currentPath[numMenus].itemIndex = -1;
menuing = TRUE;
while (menuing)
{
if (currentMenu != newMenu)
{
currentMenu = newMenu;
menuData = (xrMenuData *) currentMenu -> menuEditor -> editorData;
numMenus++;
XQueryMouse(RootWindow, &originX, &originY, &subw);
cursorX = originX;
cursorY = originY;
originX -= (menuData -> itemPosx + currentMenu -> borderWidth);
originY -= (menuData -> itemPosy[0] + currentMenu -> borderWidth);
/* figure the origin of the menu */
if(originX < 1)
{
originX = 1;
cursorX = 1;
}
if(originY < 1)
{
originY = 1;
cursorY = 1;
}
if ((originX + currentMenu -> totalWidth) > xrDisplayWidth)
{
originX = xrDisplayWidth - (currentMenu -> totalWidth + 1);
cursorX = originX + menuData -> itemPosx +
currentMenu -> borderWidth;
}
if ((originY + currentMenu -> totalHeight) > xrDisplayHeight)
{
originY = xrDisplayHeight - (currentMenu -> totalHeight + 1);
cursorY = originY + menuData -> itemPosy[0] +
currentMenu -> borderWidth;
}
/* figuring origin complete */
currentMenu -> menuOrigin.x = originX;
currentMenu -> menuOrigin.y = originY;
/* code here to keep window within display bounds */
currentMenu -> menuPixmap = XPixmapSave(RootWindow,
currentMenu -> menuOrigin.x,
currentMenu -> menuOrigin.y,
currentMenu -> totalWidth,
currentMenu -> totalHeight);
XMoveWindow(currentMenu -> menuWindow,
currentMenu -> menuOrigin.x,
currentMenu -> menuOrigin.y);
XMapWindow(currentMenu -> menuWindow);
if(currentMenu != mainMenu)
XWarpMouse(RootWindow, cursorX, cursorY);
XrMenuEdit(currentMenu -> menuEditor, MSG_REDRAW, XrREDRAW_ALL);
}
XrMenuEdit(currentMenu -> menuEditor, MSG_EDIT, &menuEditKey);
XrInput(NULL, MSG_NONBLKREAD, &menuEditKey);
if ((menuEditKey.type & XrXRAY) &&
(menuEditKey.inputCode == XrMENUEDIT))
{
switch(menuEditKey.value1)
{
case XrITEMAREA:
{
if (menuEditKey.value3 == XrMENUITEMSELECT)
{
buildKey.value2 = currentMenu -> menuId;
buildKey.value3 = menuEditKey.value2;
buildKey.valuePtr = (INT32) currentMenu;
menuing = FALSE;
returnKey = &buildKey;
}
break;
}
case XrUITEMAREA:
{
if (menuEditKey.value3 == XrMENUITEMSELECT)
{
returnKey = &nullKey;
menuing = FALSE;
}
break;
}
case XrPOPUPAREA:
{
if(menuData -> popupMenu[menuEditKey.value2])
{
mainMenu -> currentPath[numMenus - 1].menuInstance =
currentMenu;
mainMenu -> currentPath[numMenus - 1].itemIndex =
menuEditKey.value2;
newMenu = menuData -> popupMenu[menuEditKey.value2];
mainMenu -> currentPath[numMenus].menuInstance = newMenu;
mainMenu -> currentPath[numMenus].itemIndex = -1;
}
else
{
if (menuEditKey.value3 == XrMENUITEMSELECT)
{
buildKey.value2 = currentMenu -> menuId;
buildKey.value3 = menuEditKey.value2;
buildKey.valuePtr = (INT32) currentMenu;
menuing = FALSE;
returnKey = &buildKey;
}
}
break;
}
case XrEXITPOPUP:
{
break;
}
case XrOUTSIDEMENU:
{
outsideMenu = TRUE;
while(outsideMenu)
{
XrInput(NULL, MSG_BLKREAD, &enterKey);
if (enterKey.type == EnterWindow)
{
for (menuIndex = 0; menuIndex < numMenus; menuIndex++)
{
if (mainMenu ->
currentPath[menuIndex].menuInstance -> menuWindow ==
enterKey.window)
{
outsideMenu = FALSE;
while (numMenus-- != menuIndex + 1)
{
XUnmapTransparent(currentMenu -> menuWindow);
XPixmapPut(RootWindow,
0,0,
currentMenu -> menuOrigin.x, currentMenu -> menuOrigin.y,
currentMenu -> totalWidth, currentMenu -> totalHeight,
currentMenu -> menuPixmap, GXcopy, AllPlanes);
XFreePixmap(currentMenu -> menuPixmap);
XrMenuEdit(currentMenu -> menuEditor, MSG_RESET, NULL);
currentMenu = mainMenu -> currentPath[numMenus - 1].menuInstance;
newMenu = currentMenu;
}
numMenus++;
break;
}
} /* for loop */
menuData = (xrMenuData *) currentMenu -> menuEditor -> editorData;
} /* if statement */
else
{
if(XrMapButton(XrMENUITEMSELECT,&enterKey))
{
menuing = FALSE;
returnKey = &nullKey;
outsideMenu = FALSE;
break;
}
}
} /* while loop */
break;
}
case XrNULLAREA:
{
if (menuEditKey.value3 == XrMENUITEMSELECT)
{
returnKey = &nullKey;
menuing = FALSE;
}
break;
}
default:
break;
} /* end switch */
} /* end if */
} /* end while */
mainMenu -> pathLength = numMenus;
while (numMenus--)
{
XUnmapTransparent(currentMenu -> menuWindow);
XPixmapPut(RootWindow,
0,0,
currentMenu -> menuOrigin.x, currentMenu -> menuOrigin.y,
currentMenu -> totalWidth, currentMenu -> totalHeight,
currentMenu -> menuPixmap, GXcopy, AllPlanes);
XFreePixmap(currentMenu -> menuPixmap);
XrMenuEdit(currentMenu -> menuEditor, MSG_RESET, NULL);
currentMenu = mainMenu -> currentPath[numMenus - 1].menuInstance;
}
XSync(1);
XUngrabMouse();
XUngrabServer();
XFlush();
if (returnKey -> type == 0)
{
XrInput(NULL, MSG_PUSHEVENT, returnKey);
return((xrMenu *) TRUE);
}
else
{
if(menuData -> itemEvent[returnKey -> value3])
XrInput(NULL, MSG_PUSHEVENT,
menuData -> itemEvent[returnKey -> value3]);
else
XrInput(NULL, MSG_PUSHEVENT, returnKey);
}
if (menuData -> itemFunct[returnKey -> value3])
(* menuData -> itemFunct[returnKey -> value3])();
return((xrMenu*) TRUE);
break;
}
case MSG_KEYBDEQUIV:
{
xrEvent returnEvent;
XKeyEvent * keybdEvent;
register xrMenuData * menuData;
INT8 * asciiCode;
static INT16 charMask = 0x1f;
register INT32 i;
INT32 nBytes;
static xrEvent nullKey = {0, 0, 0, 0, 0, 0, 0,
{0, 0}, 0};
if ((keybdEvent = (XKeyEvent *) data) == NULL ||
(keybdEvent -> type != KeyPressed))
{
XrInput(NULL, MSG_PUSHEVENT, keybdEvent);
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
XrInput(NULL, MSG_PUSHEVENT, keybdEvent);
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
asciiCode = XrInputMap(keybdEvent, &nBytes);
menuData = (xrMenuData *) menuInstance -> menuEditor -> editorData;
returnEvent.value3 = -1;
for(i=0; i < menuData -> numItems; i++)
{
if((menuData -> keybdEquiv[i] & charMask) == * asciiCode)
{
returnEvent.value3 = i;
break;
}
}
if (menuData -> itemTypes[returnEvent.value3] == XrUSTRING)
{
returnEvent = nullKey;
}
else
{
returnEvent.type = XrXRAY;
returnEvent.source = keybdEvent -> window;
returnEvent.inputCode = 0;
returnEvent.inputType = XrMENU;
returnEvent.value1 = 0;
returnEvent.value2 = menuInstance -> menuId;
returnEvent.valuePtr = (INT32) menuInstance;
}
XSync(1);
if (returnEvent.type == 0)
{
XrInput(NULL, MSG_PUSHEVENT, &returnEvent);
return((xrMenu *) TRUE);
}
else
{
if(menuData -> itemEvent[returnEvent.value3])
XrInput(NULL, MSG_PUSHEVENT,
menuData -> itemEvent[returnEvent.value3]);
else
XrInput(NULL, MSG_PUSHEVENT, &returnEvent);
}
if (menuData -> itemFunct[returnEvent.value3])
(* menuData -> itemFunct[returnEvent.value3])();
return((xrMenu*) TRUE);
break;
}
case MSG_FREE:
{
register xrMenuData * menuData;
register INT32 i;
/* validate menu infomation pointer */
if (menuInstance == NULL) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
menuData = (xrMenuData *) menuInstance -> menuEditor -> editorData;
/* Remove menu display functions for given menu and windows */
for (i=0; i < XrMAXMENUWINDOWS; i++)
{
if (menuInstance -> currentWindows[i])
{
while (XrInput(menuInstance -> currentWindows[i],
MSG_REMOVEWINDOWFUNCT,
(INT8 *) XrMenu))
{
}
}
}
/* free various arrays */
(* xrFree) (menuData -> menuStrings);
(* xrFree) (menuData -> itemTypes);
(* xrFree) (menuData -> stringLengths);
(* xrFree) (menuData -> keybdEquiv);
XrMenuEdit(menuInstance -> menuEditor, MSG_FREE, NULL);
XrInput(menuInstance -> menuWindow, MSG_REMOVEWINDOW, NULL);
XDestroyWindow(menuInstance -> menuWindow);
(* xrFree) (menuInstance);
return ((xrMenu * ) TRUE);
break;
}
case MSG_ACTIVATEMENU:
{
Window menuWindow;
xrWindowEvent eventSet[1];
static xrWindowFunctInfo menuFunct = {TRUE, (xrPFI)XrMenu,
NULL,
(INT32)MSG_EDIT,1,
NULL};
register INT32 i;
if ((menuWindow = (Window) data) == NULL) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
if (menuInstance -> numWindows + 1 > XrMAXMENUWINDOWS)
if ( menuInstance == NULL )
{
xrErrno = XrOUTOFMEM;
return ((xrMenu *) NULL);
}
/* Remove any menu functions associated with this window */
while (XrInput(menuWindow, MSG_REMOVEWINDOWFUNCT, (INT8 *) XrMenu))
{
}
menuFunct.instance = (INT32) menuInstance;
menuFunct.eventList = &eventSet[0];
XrGetWindowEvent(XrMENUPOST, &eventSet[0]);
if (!(XrInput(menuWindow, MSG_ADDWINDOWFUNCT, &menuFunct)))
{
/* errno set by XrInput */
return((xrMenu *) NULL);
}
addKeybdEquiv(menuInstance, menuWindow, TRUE);
for (i=0; i <= XrMAXMENUWINDOWS - 1; i++)
{
if (! menuInstance -> currentWindows[i])
{
menuInstance -> currentWindows[i] = menuWindow;
menuInstance -> numWindows++;
break;
}
}
return((xrMenu *) TRUE);
break;
}
case MSG_DEACTIVATEMENU:
{
register Window menuWindow;
register INT32 i, thisWindow;
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
if ((menuWindow = (Window) data) == NULL) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/*****************************************************/
/* check to make sure menu is active on given window */
/*****************************************************/
thisWindow = FALSE;
for (i=0; i < menuInstance -> numWindows; i++)
{
if (menuInstance -> currentWindows[i] == menuWindow)
{
thisWindow = TRUE;
menuInstance -> currentWindows[i] = NULL;
break;
}
}
if (thisWindow)
{
while (XrInput(menuWindow, MSG_REMOVEWINDOWFUNCT, (INT8 *) XrMenu))
{
}
return((xrMenu *) TRUE);
}
xrErrno = XrINVALIDPARM;
return ((xrMenu *) NULL);
break;
}
case MSG_ADDSUBMENU:
{
register xrMenuIndex * subMenu;
register xrMenuData * menuData;
subMenu = (xrMenuIndex *) data;
if (subMenu == NULL) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
menuData = (xrMenuData *) menuInstance -> menuEditor -> editorData;
menuData -> popupMenu[subMenu -> itemIndex] =
subMenu -> menuInstance;
return((xrMenu *) TRUE);
break;
}
case MSG_REMOVESUBMENU:
{
register xrMenuIndex * subMenu;
register xrMenuData * menuData;
subMenu = (xrMenuIndex *) data;
if (subMenu == NULL) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
menuData = (xrMenuData *) menuInstance -> menuEditor -> editorData;
menuData -> popupMenu[subMenu -> itemIndex] = (xrMenu *) NULL;
return((xrMenu *) TRUE);
break;
}
case MSG_ACTIVATEITEM:
{
register INT32 itemIndex;
register xrMenuData * dataPtr;
if ((itemIndex = (INT32) data) < 0) {
xrErrno = XrINVALIDPARM;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
dataPtr = (xrMenuData *) menuInstance -> menuEditor -> editorData;
if ((dataPtr -> itemTypes[itemIndex] == XrSTRING) ||
(dataPtr -> itemTypes[itemIndex] == XrUSTRING))
{
dataPtr -> itemTypes[itemIndex] = XrSTRING;
}
else
{
xrErrno = XrINVALIDPARM;
return((xrMenu *) NULL);
}
return((xrMenu *) TRUE);
break;
}
case MSG_DEACTIVATEITEM:
{
register INT32 itemIndex;
register xrMenuData * dataPtr;
if ((itemIndex = (INT32) data) < 0) {
xrErrno = XrINVALIDPARM;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
dataPtr = (xrMenuData *) menuInstance -> menuEditor -> editorData;
if ((dataPtr -> itemTypes[itemIndex] == XrSTRING) ||
(dataPtr -> itemTypes[itemIndex] == XrUSTRING))
{
dataPtr -> itemTypes[itemIndex] = XrUSTRING;
}
else
{
xrErrno = XrINVALIDPARM;
return((xrMenu *) NULL);
}
return((xrMenu *) TRUE);
break;
}
case MSG_SETITEMFUNCT:
{
register xrMenuIndex * indexStruct;
register xrMenuData * dataPtr;
if ((indexStruct = (xrMenuIndex *) data) < 0) {
xrErrno = XrINVALIDPARM;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
dataPtr = (xrMenuData *) menuInstance -> menuEditor -> editorData;
dataPtr -> itemFunct[indexStruct -> itemIndex] =
(xrPFI) indexStruct -> itemData;
return((xrMenu *) TRUE);
break;
}
case MSG_SETITEMEVENT:
{
register xrMenuIndex * indexStruct;
register xrMenuData * dataPtr;
if ((indexStruct = (xrMenuIndex *) data) < 0) {
xrErrno = XrINVALIDPARM;
return ((xrMenu *) NULL);
}
/* validate menu pointer */
if ( menuInstance == NULL ) {
xrErrno = XrINVALIDPTR;
return ((xrMenu *) NULL);
}
dataPtr = (xrMenuData *) menuInstance -> menuEditor -> editorData;
dataPtr -> itemEvent[indexStruct -> itemIndex] =
(xrEvent *) indexStruct -> itemData;
return((xrMenu *) TRUE);
}
default:
xrErrno = XrINVALIDMSG;
return((xrMenu *) NULL);
}
return((xrMenu*) TRUE);
}
\f
/*************************************<->*************************************
*
* addKeybdEquiv(instance, menuWindow, recursive)
* xrMenu * instance;
* Window menuWindow;
* INT32 recursive;
*
* Description:
* -----------
* This routine recursively goes through a menu tree and adds
* keyboard equivalents to the window given.
*
*
* Inputs:
* ------
* instance = The menu instance to start recursion on.
*
* menuWindow = the window to add the keyboard equivalents to.
*
* recursive = A boolean that determines if the sub-menus
* should be considered.
*
* Outputs:
* -------
* void function -- Adds WINDOWFUNCTS as a side effect.
*
* Procedures Called
* -----------------
* isalpha()
* XrInput() - input.c
* addKeybdEquiv()
*
*
*************************************<->***********************************/
static
void
addKeybdEquiv(instance, menuWindow, recursive)
xrMenu * instance;
Window menuWindow;
INT32 recursive;
{
xrWindowFunctInfo keybdFunct;
static INT16 charMask = 0x1f;
register INT32 i;
register xrMenuData * menuData;
xrWindowEvent keybdEvent;
menuData = (xrMenuData *) instance -> menuEditor -> editorData;
for (i=0; i < menuData -> numItems; i++)
{
if (menuData -> keybdEquiv[i])
{
if (isalpha(menuData -> keybdEquiv[i]))
{
keybdFunct.processFlag = TRUE;
keybdFunct.funct = (xrPFI) XrMenu;
keybdFunct.instance = (INT32) instance;
keybdFunct.message = MSG_KEYBDEQUIV;
keybdFunct.eventCount = 1;
keybdEvent.inputType = KeyPressed;
keybdEvent.inputCode = charMask & menuData -> keybdEquiv[i];
keybdFunct.eventList = &keybdEvent;
XrInput(menuWindow, MSG_ADDWINDOWFUNCT, &keybdFunct);
}
}
if ((menuData -> popupMenu[i]) && recursive)
{
addKeybdEquiv(menuData -> popupMenu[i], menuWindow, TRUE);
}
}
return;
}