|
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; }