#include "WmCEvent.h"
#include "WmResource.h"
#include "WmResParse.h"
-#if (defined(MWM_QATS_PROTOCOL))
-# include "WmDebug.h"
-#endif /* defined(MWM_QATS_PROTOCOL) */
#include <stdio.h>
#include <X11/Shell.h>
XtPointer call_data);
static MenuItem *DuplicateMenuItems (MenuItem *menuItems);
-#if (defined(MWM_QATS_PROTOCOL))
-static MenuExclusion *DuplicateMenuExclusions(MenuExclusion *exclusions);
-static Boolean FindClientCommandMatch (MenuSpec *menuSpec,
- String clientCommand,
- MenuItem **menuItem);
-static void InsertTreeOnClient (WmScreenData *pSD, ClientData *pCD,
- CmdTree *tree,
- MatchList **client_match_list,
- MatchList **global_match_list,
- MenuSpec *menuSpec, MenuItem *template,
- String command_so_far,
- Boolean duplicate_globals, Atom selection,
- Context greyed_context, Boolean inLine);
-static MenuSpec *MakeMenuSpec (String menuName, CARD32 commandID);
-static void UnmapPulldownCallback (Widget w, XtPointer client_data,
- XtPointer call_data);
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-\f
/*************************************<->*************************************
*
* MakeMenu (menuName, initialContext, accelContext, moreMenuItems,
*
*************************************<->***********************************/
MenuSpec *MakeMenu (WmScreenData *pSD,
-#if (defined(MWM_QATS_PROTOCOL))
- ClientData *pCD,
-#endif /* defined(MWM_QATS_PROTOCOL) */
String menuName, Context initialContext,
Context accelContext, MenuItem *moreMenuItems,
Boolean fSystemMenu)
if (moreMenuItems != NULL)
{
-#if (defined(MWM_QATS_PROTOCOL))
- if ((newMenuSpec = DuplicateMenuSpec(menuSpec)) == (MenuSpec *)NULL)
- return NULL;
-#else
if ((newMenuSpec = (MenuSpec *) XtMalloc (sizeof (MenuSpec))) == NULL)
/* Handle insufficent memory */
{
newMenuSpec->accelContext = menuSpec->accelContext;
newMenuSpec->accelKeySpecs = NULL;
newMenuSpec->nextMenuSpec = NULL;
-#endif
menuSpec = newMenuSpec;
}
XtManageChild((Widget)children[wPos -1]);
}
}
- else
- {
- if (XtIsManaged((Widget)children[wPos -1]))
- {
- XtUnmanageChild((Widget)children[wPos -1]);
- }
- }
- }
-
-} /* END OF FUNCTION CheckTerminalSeparator */
-
-
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * MakeMenuSpec (menuName, commandID)
- *
- *
- *
- * Description:
- * -----------
- * This function creates and returns a MenuSpec structure.
- *
- *
- * Inputs:
- * ------
- * menuName = name of the menu specification
- * commandID = client command id of the menu item to build.
- * 0 if not for a client command.
- *
- *
- * Outputs:
- * -------
- * Return = pointer to a MenuSpec structure with zero'ed fields.
- *
- *
- * Comments:
- * --------
- * A new MenuSpec structure is allocated. The name is set to the
- * menuName argument. The menuItems list, menuButtons list and
- * accelerator related fields are zero'ed out to NULL values.
- *
- *************************************<->***********************************/
-static MenuSpec *
-MakeMenuSpec (String menuName, CARD32 commandID)
-{
- MenuSpec *menuSpec;
-
- if ((menuSpec = (MenuSpec *) XtMalloc (sizeof (MenuSpec))) == NULL)
- /* Handle insufficent memory */
- {
- MWarning(((char *)GETMESSAGE(48, 2,
- "Insufficient memory for menu %s\n")), menuName);
- return (NULL);
- }
-
- menuSpec->name = XtNewString(menuName);
- menuSpec->currentContext = F_CONTEXT_ALL;
- menuSpec->menuWidget = (Widget) NULL;
- menuSpec->whichButton = SELECT_BUTTON;
- menuSpec->height = 0;
- menuSpec->menuItems = (MenuItem *) NULL;
- menuSpec->menuButtons = (MenuButton *) NULL;
- menuSpec->menuButtonSize = 0;
- menuSpec->menuButtonCount = 0;
- menuSpec->accelContext = F_CONTEXT_ALL;
- menuSpec->accelKeySpecs = (KeySpec *) NULL;
- menuSpec->exclusions = (MenuExclusion *) NULL;
- menuSpec->clientLocal = FALSE;
- menuSpec->commandID = commandID;
- menuSpec->nextMenuSpec = (MenuSpec *) NULL;
-
- return(menuSpec);
-}
-#endif
-\f
-/*************************************<->*************************************
- *
- * DuplicateMenuItems (menuItems)
- *
- *
- *
- * Description:
- * -----------
- * This function creates an indentical duplicate of the given menuItems
- * list.
- *
- *
- * Inputs:
- * ------
- * menuItems = the linked list of menuItems to duplicate
- *
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuItems list, identical to the original
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static MenuItem *
-DuplicateMenuItems (MenuItem *menuItems)
-{
- MenuItem *newMenuItem = (MenuItem *) NULL, *returnMenuItem, *curMenuItem;
-
- for (curMenuItem = menuItems;
- curMenuItem != (MenuItem *) NULL;
- curMenuItem = curMenuItem->nextMenuItem)
- {
- /* If its the first one ... */
- if (newMenuItem == (MenuItem *) NULL)
- {
- newMenuItem = (MenuItem *)XtMalloc(sizeof(MenuItem));
- returnMenuItem = newMenuItem;
- }
- else /* ... otherwise, get the next menuItem. */
- {
- newMenuItem->nextMenuItem =
- (MenuItem *)XtMalloc(sizeof(MenuItem));
- newMenuItem = newMenuItem->nextMenuItem;
- }
-
- newMenuItem->labelType = curMenuItem->labelType;
- if (curMenuItem->label != (String) NULL)
- newMenuItem->label = XtNewString(curMenuItem->label);
- else
- newMenuItem->label = NULL;
- newMenuItem->labelBitmapIndex = curMenuItem->labelBitmapIndex;
- newMenuItem->mnemonic = curMenuItem->mnemonic;
- newMenuItem->accelState = curMenuItem->accelState;
- newMenuItem->accelKeyCode = curMenuItem->accelKeyCode;
- if (curMenuItem->accelText != (String) NULL)
- newMenuItem->accelText = XtNewString(curMenuItem->accelText);
- else
- newMenuItem->accelText = NULL;
- newMenuItem->wmFunction = curMenuItem->wmFunction;
-
- if ((curMenuItem->wmFunction == F_Send_Msg)
- || (curMenuItem->wmFunction == F_Set_Context)
- /*
- * NOTE: For now, in dtwm this function is used only
- * to copy the FrontPanel menu. So, we know that
- * curMenuItem->wmFuncArgs isn't going anywhere,
- * so it's safe to simply point at it. If at some
- * point it becomes possible that curMenuItem->wmFuncArgs
- * can go away, we'll need to make a (deep) copy of
- * the WmActionArg. 11/20/96
- */
- || (curMenuItem->wmFunction == F_Action)
- )
- newMenuItem->wmFuncArgs = curMenuItem->wmFuncArgs;
- else if (curMenuItem->wmFuncArgs != (String) NULL)
- newMenuItem->wmFuncArgs = XtNewString(curMenuItem->wmFuncArgs);
- else
- newMenuItem->wmFuncArgs = NULL;
-
- newMenuItem->greyedContext = curMenuItem->greyedContext;
- newMenuItem->mgtMask = curMenuItem->mgtMask;
-#if (defined(MWM_QATS_PROTOCOL))
- newMenuItem->clientCommandName =
- XtNewString(curMenuItem->clientCommandName);
- newMenuItem->clientCommandID = curMenuItem->clientCommandID;
-#endif
- newMenuItem->nextMenuItem = (MenuItem *) NULL;
- }
-
- return(returnMenuItem);
-}
-
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * DuplicateMenuExclusions (exclusions)
- *
- *
- *
- * Description:
- * -----------
- * This function creates an indentical duplicate of the given menu exclusions
- * list.
- *
- *
- * Inputs:
- * ------
- * exclusions = the linked list of menu exclusions to duplicate
- *
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuExclusion list, identical to the original
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static MenuExclusion *
-DuplicateMenuExclusions (MenuExclusion *exclusions)
-{
- MenuExclusion *newMenuExclusion = (MenuExclusion *) NULL;
- MenuExclusion *returnMenuExclusion = (MenuExclusion *) NULL;
- MenuExclusion *curMenuExclusion = (MenuExclusion *) NULL;
-
- for (curMenuExclusion = exclusions;
- curMenuExclusion != (MenuExclusion *) NULL;
- curMenuExclusion = curMenuExclusion->nextExclusion)
- {
- /* If its the first one ... */
- if (newMenuExclusion == (MenuExclusion *) NULL)
- {
- newMenuExclusion =
- (MenuExclusion *)XtMalloc(sizeof(MenuExclusion));
- returnMenuExclusion = newMenuExclusion;
- }
- else /* ... otherwise, get the next menuExclusion. */
- {
- newMenuExclusion->nextExclusion =
- (MenuExclusion *)XtMalloc(sizeof(MenuExclusion));
- newMenuExclusion = newMenuExclusion->nextExclusion;
- }
-
- newMenuExclusion->command_string =
- XtNewString(curMenuExclusion->command_string);
- }
-
- /* Make sure we properly NULL terminate the list. */
- if (newMenuExclusion != (MenuExclusion *) NULL)
- newMenuExclusion->nextExclusion = (MenuExclusion *) NULL;
-
- return(returnMenuExclusion);
-}
-#endif
-\f
-/*************************************<->*************************************
- *
- * DuplicateMenuSpec (menuSpec)
- *
- *
- *
- * Description:
- * -----------
- * This function creates an indentical duplicate of the given menuSpec.
- * The menuItems list in the menuSpec is also duplicated.
- *
- *
- * Inputs:
- * ------
- * menuSpec = the menuSpec to duplicate
- *
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuSpec structure with the same field
- * values as the original
- *
- *
- * Comments:
- * --------
- * A new MenuSpec structure is allocated. Most of he fields of the new
- * structure are set to the same values as the passed in menuSpec.
- * There are some differences between the two final structures.
- * One difference: any fields related to push buttons and other
- * widgets are left blank in the new MenuSpec to be filled in later.
- *
- *************************************<->***********************************/
-MenuSpec *
-DuplicateMenuSpec (MenuSpec *menuSpec)
-{
- MenuSpec *newMenuSpec;
-
- if ((newMenuSpec = (MenuSpec *) XtMalloc (sizeof (MenuSpec))) == NULL)
- /* Handle insufficent memory */
- {
- Warning((char *)GETMESSAGE(48, 9,
- "Insufficient memory for menu specification\n"));
- return (NULL);
- }
- newMenuSpec->name = XtNewString(menuSpec->name);
- newMenuSpec->currentContext = menuSpec->currentContext;
- newMenuSpec->menuWidget = (Widget) NULL;
- newMenuSpec->whichButton = menuSpec->whichButton;
- newMenuSpec->height = menuSpec->height;
- newMenuSpec->menuItems = DuplicateMenuItems(menuSpec->menuItems);
- newMenuSpec->menuButtons = (MenuButton *) NULL;
- newMenuSpec->menuButtonSize = 0;
- newMenuSpec->menuButtonCount = 0;
- newMenuSpec->accelContext = menuSpec->accelContext;
- newMenuSpec->accelKeySpecs = (KeySpec *) NULL;
-#if (defined(MWM_QATS_PROTOCOL))
- newMenuSpec->exclusions = DuplicateMenuExclusions(menuSpec->exclusions);
- newMenuSpec->clientLocal = TRUE;
- newMenuSpec->commandID = menuSpec->commandID;
-#endif
- newMenuSpec->nextMenuSpec = (MenuSpec *) NULL;
-
- return(newMenuSpec);
-}
-
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * MakeMenuItem (label, wmFunction, funcArgs, mnemonic, accelText)
- *
- *
- * Description:
- * -----------
- * This function creates and returns a MenuItem structure.
- *
- *
- * Inputs:
- * ------
- * label = the display name of the menu item
- * wmFunction = the wm function to invoke
- * funcArgs = the function arguments to pass to the wm function
- * mnemonic = the mnemonic keysym
- * accelText = the accelerator text
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuItem structure with fields filled
- * in as per passed arguments
- *
- *
- * Comments:
- * --------
- * This function is actually used as the underlying mechanism for
- * MenuItem creation by MakeMenuItemFromTemplate and
- * MakeClientCommandMenuItem.
- *
- * Assumptions:
- * -----------
- * This function assumes that ParseWmAccelerator simply takes a pointer
- * to a string and parses the accelerator found in it. If ParseWmAccelerator
- * is ever modified to call GetString to get more text from the parse
- * stream (as other parse functions do) then this code will break.
- *
- *************************************<->***********************************/
-static MenuItem *
-MakeMenuItem (String label, WmFunction wmFunction, String funcArgs,
- KeySym mnemonic, unsigned int accelState,
- KeyCode accelKeyCode, String accelText)
-{
- MenuItem *menuItem;
-/*
- unsigned char *copy_of_accelText;
-*/
-
- if ((menuItem = (MenuItem *) XtMalloc (sizeof (MenuItem))) == NULL)
- /* Handle insufficent memory */
- {
- MWarning(((char *)GETMESSAGE(48, 10,
- "Insufficient memory for menu item %s\n")), label);
- return (NULL);
- }
-
- menuItem->labelType = XmSTRING;
- menuItem->label = XtNewString(label);
- menuItem->labelBitmapIndex = -1;
- menuItem->mnemonic = mnemonic;
- menuItem->clientCommandName = NULL;
- menuItem->clientCommandID = 0;
-
-/*
- copy_of_accelText = (unsigned char *)XtNewString(accelText);
- ParseWmAccelerator(©_of_accelText, menuItem);
-*/
-
- menuItem->accelState = accelState;
- menuItem->accelKeyCode = accelKeyCode;
- menuItem->accelText = XtNewString(accelText);
-
- menuItem->wmFunction = wmFunction;
- menuItem->wmFuncArgs = XtNewString(funcArgs);
- SetGreyedContextAndMgtMask(menuItem, wmFunction);
- menuItem->nextMenuItem = (MenuItem *) NULL;
-
- return(menuItem);
-}
-
-\f
-/*************************************<->*************************************
- *
- * MakeMenuItemFromTemplate (template, name, funcArgs)
- *
- *
- * Description:
- * -----------
- * This function creates and returns a MenuItem structure.
- *
- *
- * Inputs:
- * ------
- * template = a template menuItem used to fill in fields of the
- * new menu item
- * name = the display name this item should have
- * funcArgs = the function arguments to pass to the wm function
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuItem structure with fields filled
- * in as per template MenuItem and funcargs
- *
- *
- * Comments:
- * --------
- * This function uses the values in the template MenuItem to create
- * a new copy of the template with the given funcArgs.
- *
- *************************************<->***********************************/
-
-static MenuItem *MakeMenuItemFromTemplate (MenuItem *template, String name,
- String funcArgs)
-{
- if (template->clientCommandName == (String) NULL)
- return(MakeMenuItem(name, template->wmFunction, funcArgs,
- template->mnemonic, template->accelState,
- template->accelKeyCode, template->accelText));
-
- return(MakeMenuItem(template->clientCommandName, template->wmFunction,
- funcArgs, template->mnemonic, template->accelState,
- template->accelKeyCode, template->accelText));
-}
-
-\f
-/*************************************<->*************************************
- *
- * MakeClientCommandMenuItem (label, funcArgs)
- *
- *
- * Description:
- * -----------
- * This function creates and returns a MenuItem structure filled as
- * appropriate for client command menu items using the given label
- * and funcArgs.
- *
- *
- * Inputs:
- * ------
- * label = the display label for this menu item
- * funcArgs = the function arguments to pass to the wm function
- *
- * Outputs:
- * -------
- * Return = pointer to a new MenuItem structure with fields filled
- * in as per arguments and client command specs
- *
- *
- * Comments:
- * --------
- * This function will fill in a new MenuItem structure as appropriate for
- * client commands. This function is used when you want to insert a client
- * command into a menu without using a MenuItem template constructed from
- * mwmrc.
- *
- *************************************<->***********************************/
-
-static MenuItem *MakeClientCommandMenuItem (String label, String funcArgs)
-{
- return(MakeMenuItem(label, F_InvokeCommand, funcArgs,
- (KeySym) NULL, (unsigned int)0,
- (KeyCode) NULL, (String)NULL));
-}
-
-\f
-/*************************************<->*************************************
- *
- * PerformClientCommandMatch (clientCommand, menuItem, bestMatchSoFar)
- *
- *
- * Description:
- * -----------
- * This function determines whether the menuItemCommand specification
- * matches the clientCommand.
- *
- * Inputs:
- * ------
- * clientCommand = the clientCommand that we want to find a specification for
- * menuItem = the menu item we will look in for a specification
- * bestMatchSoFar = the menu item we will return if the given menu item is
- * not a match or not a better match
- *
- * Outputs:
- * -------
- * Return = pointer to the given menuItem if it contains a client command
- * specification and if that specification matches the given
- * clientCommand *and* if the match is a better match than
- * the bestMatchSoFar. Otherwise, the bestMatchSoFar is returned,
- * which could possibly be NULL.
- *
- * Comments:
- * --------
- * If the menuItem does match, it also determines whether it is
- * a better match than the bestMatchSoFar. If so, the menuItemCommand is
- * returned. Otherwise, bestMatchSoFar is returned.
- *
- * Best matching is defined as follows:
- * 1. A specification with fewer wildcards is considered a better
- * match than one with more wildcards.
- * 2. Given two specifications with the same number of wildcards,
- * the specification with its wildcards more towards the right
- * than the left is considered a better match.
- *
- *************************************<->***********************************/
-
-/* @RGC: This is kind of arbitrary, but I can't imagine there being more
- than a small number of segments in any given command specification. */
-#define MAXSEGMENTS 100
-
-static MenuItem *PerformClientCommandMatch (String clientCommand,
- MenuItem *menuItem,
- MenuItem *bestMatchSoFar)
-{
- String menuItemCommand, bestMatchStr;
- int seglength, i;
- int segments = 0, wildcards = 0, wildcardPositions[MAXSEGMENTS];
- int bestSegments = 0, bestWildcards = 0;
- int bestWildcardPositions[MAXSEGMENTS];
- Boolean foundWildcard = FALSE;
-
- if (menuItem == (MenuItem *) NULL)
- return(bestMatchSoFar);
- menuItemCommand = menuItem->label;
-
- /* Skip any modifier characters at the beginning of the
- menu items client command. */
- /* @RGC: This is kind of kludgy. We shouldn't have to know
- the specifics of command parsing here. */
- if (menuItemCommand[0] == '~')
- ++menuItemCommand;
- else if (menuItemCommand[0] == '=' && menuItemCommand[1] == '>')
- menuItemCommand += 2;
- else if (menuItemCommand[0] == '=')
- ++menuItemCommand;
- else if (menuItemCommand[0] == '-' && menuItemCommand[1] == '>')
- menuItemCommand += 2;
-
- /* If the menu item doesn't even contain a client command spec,
- then just return the existing best match. */
- if (*menuItemCommand != '<') return(bestMatchSoFar);
-
- /* Run down the clientCommand and the menuItemCommand together,
- matching along the way. If matching fails at any point, then
- return the bestMatchSoFar. */
- for (segments = 0;
- *menuItemCommand != '\0' && *clientCommand != '\0';
- ++segments)
- {
- /* Skip past the '<' at the beginning of the next segment and
- any whitespace. */
- ++menuItemCommand; ++clientCommand;
- while (isspace(*menuItemCommand)) ++menuItemCommand;
- while (isspace(*clientCommand)) ++clientCommand;
-
- /* First check whether the current menuItemCommand segment is
- a wildcard. */
- if (*menuItemCommand == '*')
- {
- /* Since the menuItemCommand segment is a wildcard, skip
- it and the current segment of the client command since
- the wildcard has to match at least one segment in
- the client command. */
- wildcardPositions[wildcards++] = segments;
- ++menuItemCommand;
- while (isspace(*menuItemCommand)) ++menuItemCommand;
- while (*clientCommand != '>' && *clientCommand != '\0')
- ++clientCommand;
- foundWildcard = TRUE;
- }
- else
- {
- /* Calculate how long the current segment of the
- menuItemCommand is */
- for (seglength = 0;
- menuItemCommand[seglength] != '>' &&
- menuItemCommand[seglength] != '\0';
- ++seglength)
- /*EMPTY*/;
-
- /* If we are pointing at '\0', then this isn't a match */
- if (menuItemCommand[seglength] == '\0') return(bestMatchSoFar);
-
- /* Get rid of trailing white space on the segment. */
- for (; seglength > 0; --seglength)
- {
- if (!isspace(menuItemCommand[seglength - 1]))
- break;
- }
-
- /* Now string compare this segment with the clientCommand
- segment, up to the number of characters in the menu
- item segment. */
- if (strncmp(menuItemCommand, clientCommand, seglength) == 0)
- {
- /* So far so good. Just make sure clientCommand doesn't
- have anything but whitespace after its seglength
- character. */
- clientCommand += seglength;
- while (isspace(*clientCommand)) ++clientCommand;
- if (*clientCommand != '>') return(bestMatchSoFar);
-
- /* We have a match. Clear the foundWildcard since we
- have sync'ed up and keep trying to match. */
- foundWildcard = FALSE;
- menuItemCommand += seglength;
- while (isspace(*menuItemCommand)) ++menuItemCommand;
- }
- else if (foundWildcard == FALSE)
- {
- /* We didn't match and there wasn't wildcard to
- swallow the discrepancy. Therefore, this is not
- a match. */
- return(bestMatchSoFar);
- }
- }
-
- /* We finished the current segments, we should be looking at
- a close bracket and a following period or a close bracket and
- a following NULL. Skip past the close brackets and optional
- period. If we don't see those, then this isn't a match. */
- if (menuItemCommand[0] == '>' && menuItemCommand[1] == '\0' &&
- clientCommand[0] == '>' && clientCommand[1] == '\0')
- {
- ++menuItemCommand; ++clientCommand;
- }
- else if (menuItemCommand[0] == '>' && menuItemCommand[1] == '.' &&
- clientCommand[0] == '>' && clientCommand[1] == '.')
- {
- menuItemCommand += 2;
- clientCommand += 2;
- }
- else return(bestMatchSoFar);
- }
-
- /* If we terminated the loop because only one of the two commands being
- compared was empty, then we don't have a complete match. Return the
- best match so far. */
- if (*menuItemCommand != '\0' || *clientCommand != '\0')
- return(bestMatchSoFar);
-
- /* So the menuItemCommand must have matched. If the current best
- match is NULL, then just return the menuItem. Otherwise calculate some
- matching quality metrics for the bestMatchSoFar and compare them
- to the menuItemCommand metrics to decide which of the two to
- return. */
- if (bestMatchSoFar == (MenuItem *) NULL)
- return(menuItem);
-
- bestMatchStr = bestMatchSoFar->label;
-
- /* Skip any modifier characters at the beginning of the
- best match client command. */
- /* @RGC: This is kind of kludgy. We shouldn't have to know
- the specifics of command parsing here. */
- if (bestMatchStr[0] == '~')
- ++bestMatchStr;
- else if (bestMatchStr[0] == '=' && bestMatchStr[1] == '>')
- bestMatchStr += 2;
- else if (bestMatchStr[0] == '=')
- ++bestMatchStr;
- else if (bestMatchStr[0] == '-' && bestMatchStr[1] == '>')
- bestMatchStr += 2;
-
- /* If the best match doesn't even contain a client command spec,
- then just return the new match as the best match. */
- if (*bestMatchStr != '<') return(menuItem);
-
- for (bestSegments = 0;
- *bestMatchStr != '\0';
- ++bestSegments)
- {
- /* Skip past the '<' at the beginning of the next segment and
- any whitespace. */
- ++bestMatchStr;
- while (isspace(*bestMatchStr)) ++bestMatchStr;
-
- /* First check whether the current bestMatchStr segment is
- a wildcard. @RGC: We are assuming that there is nothing
- but possible whitespace after the *. */
- if (*bestMatchStr == '*')
- bestWildcardPositions[bestWildcards++] = bestSegments;
- while (*bestMatchStr != '>' && *bestMatchStr != '\0')
- ++bestMatchStr;
-
- /* Check for the closing > and . or close > and NULL. If they
- do not both appear then the bestMatch is bad and we should
- return the menuItem. */
- if (bestMatchStr[0] == '>' && bestMatchStr[1] == '\0')
- ++bestMatchStr;
- else if (bestMatchStr[0] == '>' && bestMatchStr[1] == '.')
- bestMatchStr += 2;
- else return(menuItem);
- }
-
- /* Now compare the best match metrics with the menu item metrics to
- determine who should be returned. */
- if (bestWildcards != wildcards)
- {
- /* Return the menuItem with the fewest wildcards. */
- return(bestWildcards < wildcards ? bestMatchSoFar : menuItem);
- }
- else
- {
- /* Find which menu item has the earliest wild card and return
- the other. */
- for (i = 0; i < wildcards; ++i)
- if (wildcardPositions[i] != bestWildcardPositions[i])
- {
- return(bestWildcardPositions[i] < wildcardPositions[i] ?
- bestMatchSoFar : menuItem);
- }
-
- /* If we got this far, then the two specifications are too
- close to call. Return bestMatchSoFar. */
- return(bestMatchSoFar);
- }
-}
-
-\f
-/*************************************<->*************************************
- *
- * ExcludeClientCommand (menuSpec, clientCommand)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- * menuSpec = the menuSpec whose menuItems we want to search through
- * clientCommand = the clientCommand that we want to find an exclusion for
- *
- * Outputs:
- * -------
- * Return = TRUE if the command must be excluded from the menuSpec.
- * FALSE if there is no exclusion preventing the insertion.
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static Boolean ExcludeClientCommand (MenuSpec *menuSpec, String clientCommand)
-{
- MenuItem placeholder;
- MenuExclusion *curExclusion;
-
- /* Search for an exclusion that would cause this command to be
- excluded, if any such exclusion exists. */
- for (curExclusion = menuSpec->exclusions;
- curExclusion != (MenuExclusion *) NULL;
- curExclusion = curExclusion->nextExclusion)
- {
- /* We don't have menu items for exclusions so just use a bogus
- placeholder menu item with the label field set to the string
- found in the exclusion. */
- placeholder.label = curExclusion->command_string;
-
- /* If we don't get NULL back, then this exclusion matches. */
- if (PerformClientCommandMatch(clientCommand,
- &placeholder, NULL) != (MenuItem *) NULL)
- {
- return(TRUE);
- }
- }
- return(FALSE);
-}
-
-\f
-/*************************************<->*************************************
- *
- * ForceInLineToCascade (menuSpec, clientCommand, bestMatch)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- * menuSpec = the menuSpec whose menuItems we want to search through
- * clientCommand = the clientCommand that we want to find an force for
- * bestMatch = the best matching menu item that was found
- *
- * Outputs:
- * -------
- * Return = TRUE if the command set must be cascaded
- * FALSE if there is no forced cascade
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static Boolean ForceInLineToCascade (MenuSpec *menuSpec,
- String clientCommand,
- MenuItem **bestMatch)
-{
- /* First find the best match in the menu spec. */
- FindClientCommandMatch(menuSpec, clientCommand, bestMatch);
-
- /* If the best match is not NULL, then check whether it forces
- the client command to cascade. */
- if (*bestMatch != (MenuItem *) NULL)
- {
- /* If there is a force cascade modifier, then return TRUE. */
- if ((strncmp((*bestMatch)->label, "->", 2) == 0) ||
- (strncmp((*bestMatch)->label, "=>", 2) == 0))
- return(TRUE);
- }
-
- /* If the best match is NULL, then return FALSE. We have been
- given no indication that the inLine command should be forced
- to cascade. */
- return(FALSE);
-}
-
-\f
-/*************************************<->*************************************
- *
- * FindClientCommandMatch (menuSpec, clientCommand, menuItem)
- *
- *
- * Description:
- * -----------
- * This function searches through the list of menuItems in the given
- * menuSpec, searching for ones which have a client command specification
- * and, for each one that does, whether that specification matches the
- * given client. The best matching menuItem out of all that matched
- * is returned.
- *
- * Inputs:
- * ------
- * menuSpec = the menuSpec whose menuItems we want to search through
- * clientCommand = the clientCommand that we want to find a specification for
- * menuItem = the best matching menu item
- *
- * Outputs:
- * -------
- * Return = TRUE if the command may be inserted into the menuSpec.
- * FALSE if there is an exclusion preventing the insertion.
- * Also return the best matching menu item in the menuItem
- * buffer argument. NULL is returned if no matching MenuItem
- * can be found.
- *
- * Comments:
- * --------
- * Best matching is defined as follows:
- * 1. A specification with fewer wildcards is considered a better
- * match than one with more wildcards.
- * 2. Given two specifications with the same number of wildcards,
- * the specification with its wildcards more towards the right
- * than the left is considered a better match.
- *
- *************************************<->***********************************/
-
-static Boolean FindClientCommandMatch (MenuSpec *menuSpec,
- String clientCommand,
- MenuItem **menuItem)
-{
- MenuItem *bestMatch = (MenuItem *) NULL, *curMenuItem, placeholder;
- MenuItem *bestExclusionItem = (MenuItem *) NULL;
- MenuExclusion *curExclusion;
- String bestExclusionStr = (String) NULL;
-
- /* First search for a match in the menu items of the menu spec. */
- for (curMenuItem = menuSpec->menuItems;
- curMenuItem != (MenuItem *) NULL;
- curMenuItem = curMenuItem->nextMenuItem)
- {
- bestMatch =
- PerformClientCommandMatch(clientCommand, curMenuItem, bestMatch);
- }
-
- /* Now search for the best exclusion that would cause this match to be
- excluded, if any such exclusion exists. */
- for (curExclusion = menuSpec->exclusions;
- curExclusion != (MenuExclusion *) NULL;
- curExclusion = curExclusion->nextExclusion)
- {
- /* We don't have menu items for exclusions so just use a bogus
- placeholder menu item with the label field set to the string
- found in the exclusion. */
- placeholder.label = curExclusion->command_string;
-
- /* Find the best exclusion string in the bunch. */
- bestExclusionItem =
- PerformClientCommandMatch(clientCommand, &placeholder,
- bestExclusionItem);
-
- /* Save the best exclusion string since we are going to reuse
- the placeholder menu item. */
- if (bestExclusionItem != (MenuItem *) NULL)
- bestExclusionStr = bestExclusionItem->label;
- }
-
- /* Okay, now if we found an exclusion, we need to determine if the
- exclusion was a better match than the best match that we found.
- If so, the item is *really* exclude. Otherwise, we return the
- best match and let the item be included. */
- placeholder.label = bestExclusionStr;
- if (bestExclusionStr == (String) NULL ||
- PerformClientCommandMatch(clientCommand, bestMatch, &placeholder) ==
- bestMatch)
- {
- *menuItem = bestMatch;
- return(TRUE);
- }
- else
- {
- *menuItem = NULL;
- return(FALSE);
- }
-}
-
-
-\f
-/*************************************<->*************************************
- *
- * PerformInsertionsOnMatchList (matchlist)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void PerformInsertionsOnMatchList (MatchList **matchlist)
-{
- MatchList *curmatch;
- MenuItem *newMenuItem, *curitem;
-
- if (*matchlist == (MatchList *) NULL)
- return;
-
- if ((*matchlist)->menuspec == (MenuSpec *) NULL)
- {
- /* should never get here, but if we do, then we can't
- continue in this routine since mwm will dump. This
- may be caused by the cci code duplicating a global
- menu for a client when it shouldn't be duplicated.
- If we skip this routine, the cci command will not
- be added which is far less disturbing than a dump. */
- return;
- }
-
-
- for (curmatch = *matchlist;
- curmatch != (MatchList *) NULL;
- curmatch = curmatch->next)
- {
- if (curmatch->menuitem != (MenuItem *) NULL)
- {
- /* Find this menu item within the menuspec. */
- for (curitem = curmatch->menuspec->menuItems;
- curitem != curmatch->menuitem &&
- curitem != (MenuItem *) NULL;
- curitem = curitem->nextMenuItem)
- /*EMPTY*/;
-
- /* If we didn't find the menuitem in the menuspec, then
- don't do this match. */
- if (curitem == (MenuItem *) NULL) continue;
-
- newMenuItem =
- MakeMenuItemFromTemplate(curmatch->menuitem,
- curmatch->treenode->defaultName,
- curmatch->funcargs);
- newMenuItem->wmFunction = curmatch->function;
- newMenuItem->greyedContext = curmatch->greyed_context;
- newMenuItem->nextMenuItem = curitem->nextMenuItem;
- newMenuItem->clientCommandID = curmatch->treenode->commandID;
- curitem->nextMenuItem = newMenuItem;
- }
- else
- {
- MenuItem *last = (MenuItem *) NULL;
-
- if (curmatch->menuspec != NULL)
- {
- /* Find the last menu item in the menuspec */
- for (last = curmatch->menuspec->menuItems;
- last != (MenuItem *) NULL &&
- last->nextMenuItem != (MenuItem *) NULL;
- last = last->nextMenuItem)
- {
- /* If the next item is f.quit and it is the last
- item, then stop searching now. We don't want
- to insert after a trailing f.kill (i.e. Close). */
- if ((last->nextMenuItem->wmFunction == F_Kill) &&
- (last->nextMenuItem->nextMenuItem == (MenuItem *) NULL))
- break;
- }
- }
-
- /* Create a new client command menu item */
- newMenuItem =
- MakeClientCommandMenuItem
- (XtNewString(curmatch->treenode->defaultName),
- XtNewString(curmatch->funcargs));
- newMenuItem->wmFunction = curmatch->function;
- newMenuItem->greyedContext = curmatch->greyed_context;
- newMenuItem->clientCommandID = curmatch->treenode->commandID;
-
- /* Insert the new menu item at the end of the list */
- if (last == (MenuItem *) NULL)
- {
- newMenuItem->nextMenuItem = (MenuItem *) NULL;
- if (curmatch->menuspec != NULL)
- curmatch->menuspec->menuItems = newMenuItem;
- else
- {
- /* again, should never get here... */
- return;
- }
- }
- else
- {
- newMenuItem->nextMenuItem = last->nextMenuItem;
- last->nextMenuItem = newMenuItem;
- }
- }
- }
-}
-
-\f
-/*************************************<->*************************************
- *
- * void
- * DestroyMenuSpecWidgets (menuSpec)
- *
- *
- * Description:
- * -----------
- *
- *
- * Inputs:
- * ------
- * menuSpec = pointer to MenuSpec structure
- *
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- * Destroys all the menuspec widgets so that we can rebuild the menu from
- * scratch.
- *
- *************************************<->***********************************/
-
-void DestroyMenuSpecWidgets (MenuSpec *menuSpec)
-{
- /* check for bad input value - shouldn't happen. */
- if (menuSpec == (MenuSpec *) NULL) return;
-
- /* Destroy the menu widget */
- if (menuSpec->menuWidget != (Widget) NULL)
- {
- XtDestroyWidget(XtParent(menuSpec->menuWidget));
- menuSpec->menuWidget = (Widget) NULL;
- }
-
- /* Destroy the menu buttons array */
- if (menuSpec->menuButtonSize != 0)
- {
- XtFree((char *)menuSpec->menuButtons);
- menuSpec->menuButtons = (MenuButton *) NULL;
- }
-
- /* Reset the counters */
- menuSpec->menuButtonSize = 0;
- menuSpec->menuButtonCount = 0;
-
- /* Clear the flag that says we have processed this menu spec for
- widget creation. (We probably don't need to do this after all
- since CreateMenuWidgets clears it when done.) */
- if (menuSpec->currentContext & CR_MENU_MARK)
- menuSpec->currentContext &= ~(CR_MENU_MARK);
-
- return;
-}
-
-\f
-/*************************************<->*************************************
- *
- * void
- * DestroyMenuSpec (pSD, commandID)
- *
- *
- * Description:
- * -----------
- *
- *
- * Inputs:
- * ------
- * pSD = screen data pointer of screen with command to remove
- * commandID = command id of the menuspec to be removed.
- * if no match is found, then no removal is done.
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- * Destroy the specified menuSpec from the list of menuspecs on the
- * specified screen. Note, there may be more than one copy of the
- * spec floating around since duplications may have been done for
- * some clients.
- *
- *************************************<->***********************************/
-
-void DestroyMenuSpec (WmScreenData *pSD, CARD32 commandID)
-{
- MenuSpec *msToKill = NULL, *pMS;
- ClientListEntry *curClient;
-
- /* Scan through global menu specs. */
- if (pSD != NULL && pSD->menuSpecs != NULL && commandID != 0)
- {
- /* Scan through the list of menuSpecs and pull the mathing one
- * out of the list.
- */
- if (commandID == pSD->menuSpecs->commandID)
- {
- /* match at head of menuSpec list. */
- msToKill = pSD->menuSpecs;
- pSD->menuSpecs = pSD->menuSpecs->nextMenuSpec;
- msToKill->nextMenuSpec = NULL;
- }
- else
- {
- for (pMS = pSD->menuSpecs;
- (pMS->nextMenuSpec != NULL &&
- pMS->nextMenuSpec->commandID != commandID);
- pMS = pMS->nextMenuSpec)
- ;
-
- if (pMS->nextMenuSpec != NULL)
- {
- msToKill = pMS->nextMenuSpec;
- pMS->nextMenuSpec = msToKill->nextMenuSpec;
- msToKill->nextMenuSpec = NULL;
- }
- }
-
- /* found it - now remove the menuSpec. */
- if (msToKill != NULL)
- FreeCustomMenuSpec(msToKill);
- }
-
-
- /* Check each client's menu spec list. Stop searching if global. */
- for (curClient = pSD->clientList;
- curClient != (ClientListEntry *)NULL;
- curClient = curClient->nextSibling)
- {
- /*
- * Check the first position.
- * If matched, then we're done with this client.
- */
- if (commandID == pSD->menuSpecs->commandID)
- {
- msToKill = curClient->pCD->systemMenuSpec;
- curClient->pCD->systemMenuSpec = msToKill->nextMenuSpec;
- msToKill->nextMenuSpec = NULL;
- }
-
- /* Check the rest of the list. */
- else
- {
- for (pMS = curClient->pCD->systemMenuSpec;
- (pMS->nextMenuSpec != (MenuSpec *)NULL) &&
- (pMS->nextMenuSpec->commandID != commandID) &&
- pMS->clientLocal;
- pMS = pMS->nextMenuSpec)
- ;
-
- if ((pMS->nextMenuSpec != (MenuSpec *)NULL) &&
- (pMS->nextMenuSpec->commandID != commandID))
- {
- msToKill = pMS->nextMenuSpec;
- pMS->nextMenuSpec = msToKill->nextMenuSpec;
- msToKill->nextMenuSpec = NULL;
- }
- else
- msToKill = NULL;
- }
-
- if (msToKill != NULL)
- FreeCustomMenuSpec(msToKill);
- }
-
- return;
-}
-
-\f
-/*************************************<->*************************************
- *
- * ReplaceMenuSpecForClient (menuspec, pCD)
- *
- *
- * Description:
- * -----------
- * Duplicates the given menuspec and replaces the given menuspec if
- * found in the clients menuspec list with the duplicate.
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return = the duplicate menuspec
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static MenuSpec *ReplaceMenuSpecForClient (MenuSpec *menuSpec, ClientData *pCD)
-{
- MenuSpec *newMenuSpec, *curMenuSpec;
-
- /* Duplicate the menu spec */
- newMenuSpec = DuplicateMenuSpec(menuSpec);
-
- /* Try to find this menuspec in the list of client
- menuspecs. If we find it then we want to replace it with
- the new one. */
- if (pCD->systemMenuSpec == menuSpec)
- {
- /* It was the head of the list. We need to handle that
- a little special */
- newMenuSpec->nextMenuSpec = pCD->systemMenuSpec->nextMenuSpec;
- pCD->systemMenuSpec = newMenuSpec;
- }
- else
- {
- /* Search through the list until we find the menuspec or
- the end of the list. */
- for (curMenuSpec = pCD->systemMenuSpec;
- curMenuSpec->nextMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
- {
- if (curMenuSpec->nextMenuSpec == menuSpec)
- {
- newMenuSpec->nextMenuSpec =
- curMenuSpec->nextMenuSpec->nextMenuSpec;
- curMenuSpec->nextMenuSpec = newMenuSpec;
- /* We found it and replaced it. Now get out of
- the loop. */
- break;
- }
- }
- if (curMenuSpec->nextMenuSpec == (MenuSpec *) NULL)
- {
- /* We didn't find it. Just stick it at the end? We
- should have found it. I'm not sure how to handle
- this. */
- curMenuSpec->nextMenuSpec = newMenuSpec;
- newMenuSpec = (MenuSpec *) NULL;
- }
- }
-
- return(newMenuSpec);
-}
-
-\f
-/*************************************<->*************************************
- *
- * FindLastMenuSpecToModify (menuspec, command_id)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return = the last menu spec that would be affected by modifications
- * to the given command id
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static MenuSpec * FindLastMenuSpecToModify(MenuSpec *menuSpec,
- CARD32 command_id)
-{
- MenuSpec *curMenuSpec, *lastToModify = (MenuSpec *) NULL;
- MenuItem *curItem;
-
- /* Search through all the menu specs in the list starting with
- the passed in menuSpec */
- for (curMenuSpec = menuSpec;
- curMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
- {
- /* Try to find a menu item in this menu spec with the
- command_id that will require modification */
- for (curItem = curMenuSpec->menuItems;
- curItem != (MenuItem *) NULL;
- curItem = curItem->nextMenuItem)
- {
- if (curItem->clientCommandID == command_id)
- break;
- }
-
- /* If we found a menu item that needs changing, then this
- menu spec will need changing. Set the lastToModify to
- point to this menu spec. If we find no other menu spec
- that needs changing, then this will be the last one
- in the list that needs changing. */
- if (curItem != (MenuItem *) NULL)
- lastToModify = curMenuSpec;
- }
-
- /* We've looked through all the menu specs starting with menuSpec
- and we've looked at all the menu items in all of those menu
- specs. The lastToModify variable should be set to the last
- menu spec we saw that needed modification. Return it. */
- return(lastToModify);
-}
-
-\f
-/*************************************<->*************************************
- *
- * RecreateMenuWidgets (matchlist)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void RecreateMenuWidgets (WmScreenData *pSD, ClientData *pCD,
- MatchList **matchlist)
-{
- MatchList *current;
- int count = 0, i;
- MenuSpec **to_change;
-
- /* First count how many menu specs we need to recreate widgets for */
- for (current = *matchlist;
- current != (MatchList *) NULL;
- current = current->next)
- ++count;
-
- /* If there are no affected menuspecs, then just return. */
- if (count == 0) return;
-
- /* Allocate an array of menuspec pointers that is the size of the
- number of menu specs we need to recreate widgets for */
- to_change = (MenuSpec **)XtMalloc(sizeof(MenuSpec *) * count);
- for (i = 0; i < count; ++i)
- to_change[i] = (MenuSpec *) NULL;
-
- /* Now run through all the matchlist items, storing menuspecs in
- that array. If the menuspec is already there, then don't store
- it again. */
- for (current = *matchlist;
- current != (MatchList *) NULL;
- current = current->next)
- {
- for (i = 0; i < count; ++i)
- {
- if (to_change[i] == current->menuspec) break;
- else if (to_change[i] == (MenuSpec *) NULL)
- {
- to_change[i] = current->menuspec;
- break;
- }
- }
- }
-
- /* Run through the array, destroy all existing widgets for each
- menuspec */
- for (i = 0; i < count && to_change[i] != (MenuSpec *) NULL ; ++i)
- {
- DestroyMenuSpecWidgets(to_change[i]);
- }
-
- /* Run through the array again creating widgets for all the menuspecs */
- for (i = 0; i < count && to_change[i] != (MenuSpec *) NULL; ++i)
- {
- to_change[i]->menuWidget =
- CreateMenuWidget (pSD, pCD, to_change[i]->name, pSD->screenTopLevelW,
- TRUE, to_change[i], NULL);
- }
-
- /* Free the array. We're done. */
- XtFree((char *) to_change);
-}
-
-\f
-/*************************************<->*************************************
- *
- * FreeMatchList (matchlist)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void FreeMatchList (MatchList **matchlist)
-{
- MatchList *current, *next;
-
- current = *matchlist;
-
- while (current != (MatchList *) NULL)
- {
- next = current->next;
- XtFree(current->command_string);
- XtFree(current->funcargs);
- XtFree((char *)current);
- current = next;
- }
-
- *matchlist = (MatchList *) NULL;
-}
-
-\f
-/*************************************<->*************************************
- *
- * StoreMatchedCommand (matchlist, menuSpec, menuItem, command_string,
- * treenode, function, funcargs)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- * If the existing match has NULL for the menuitem, then get rid of
- * it and replace with proposed match.
- *
- *************************************<->***********************************/
-
-static void StoreMatchedCommand (MatchList **matchlist, MenuSpec *menuSpec,
- MenuItem *menuItem, String command_string,
- CmdTree *treenode, WmFunction function,
- String funcargs, Context greyed_context)
-{
- MatchList *current, *new;
-
- /* If this entry does not already exist in the match list, then insert
- it. This implies that we first have to perform a search of the list.
- The search is very easy. We can simply compare the tuple of
- <menuSpec,command_string> with each entry in the matchlist
- to see if we already have that tuple stored. We can do straight
- pointer value matching for the menuSpec and strcmp for the
- command_string */
- for (current = *matchlist;
- current != (MatchList *) NULL;
- current = current->next)
- {
- if (current->menuspec == menuSpec &&
- strcmp(current->command_string, command_string) == 0)
- {
- /* If the currently stored menu item is NULL,
- then replace with the new menuitem and return. */
- if (current->menuitem == (MenuItem *) NULL)
- {
- current->menuitem = menuItem;
- return;
- }
- /* Otherwise, we have alreay inserted this
- command into this menuspec so don't allow
- another insertion. */
- else return;
- }
- }
-
- /* Well, we didn't find a match, so store the entry */
- new = (MatchList *)XtMalloc(sizeof(MatchList));
- new->menuspec = menuSpec;
- new->menuitem = menuItem;
- new->command_string = XtNewString(command_string);
- new->treenode = treenode;
- new->function = function;
- new->funcargs = XtNewString(funcargs);
- new->greyed_context = greyed_context;
- new->next = (MatchList *) NULL;
-
- /* Stick it at the head of the list. It's easier. */
- new->next = *matchlist;
- *matchlist = new;
-}
-
-\f
-/*************************************<->*************************************
- *
- * SearchForOtherMatches (pSD, pCD, treenode,
- * client_match_list, global_match_list,
- * menuSpec, command_string,
- * function, funcargs, duplicate_globals, selection,
- * greyed_context)
- *
- *
- * Description:
- * -----------
- * menuSpec = menu spec to exclude from search
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void SearchForOtherMatches (WmScreenData *pSD, ClientData *pCD,
- CmdTree *treenode,
- MatchList **client_match_list,
- MatchList **global_match_list,
- MenuSpec *menuSpec, String command_string,
- WmFunction function, String funcargs,
- Boolean duplicate_globals, Atom selection,
- Context greyed_context, Boolean inLine)
-{
- MenuSpec *current, *newMenuSpec;
- MenuItem *match;
-
- /* Search through all of the clients menuspecs first */
- for (current = (pCD == NULL ? NULL : pCD->systemMenuSpec);
- current != (MenuSpec *) NULL;
- current = current->nextMenuSpec)
- {
- /* If the current menu spec is a global, then just quit
- this loop. Any menu specs from this point on will
- have a next pointer that is still in the global list. */
- if (menuSpec->clientLocal != TRUE) break;
- FindClientCommandMatch(current, command_string, &match);
- if (match != (MenuItem *) NULL)
- {
- if (treenode->subTrees != (CmdTree *) NULL && inLine &&
- (strncmp(match->label, "->", 2) == 0 ||
- strncmp(match->label, "=>", 2) == 0))
- {
- CmdTree *tree;
- for (tree = treenode->subTrees;
- tree != (CmdTree *) NULL;
- tree = tree->next)
- {
- char new_command_str[1024];
- char new_funcargs[1024];
- WmFunction inLine_function;
-
- if (command_string == NULL)
- sprintf(new_command_str, "<%s>", tree->name);
- else
- sprintf(new_command_str, "%s.<%s>", command_string,
- tree->name);
- if (tree->subTrees != (CmdTree *) NULL)
- {
- /* menu to cascade to */
- sprintf(new_funcargs, "<%s>", tree->name);
- inLine_function = F_Menu;
- }
- else
- {
- sprintf(new_funcargs, "%d %ld %ld", tree->commandID,
- pCD->client, selection);
- inLine_function = F_InvokeCommand;
- }
- StoreMatchedCommand(client_match_list, current, match,
- new_command_str, tree,
- inLine_function, new_funcargs,
- greyed_context);
- }
- }
- else
- {
- StoreMatchedCommand(client_match_list, current, match,
- command_string, treenode, function,
- funcargs, greyed_context);
- }
- }
- }
-
- /* Search through all of the global menuspecs also. */
- for (current = pSD->menuSpecs;
- current != (MenuSpec *) NULL;
- current = current->nextMenuSpec)
- {
- FindClientCommandMatch(current, command_string, &match);
- if (match != (MenuItem *) NULL)
- {
- if (duplicate_globals == TRUE)
- {
- /* Create a duplicate of the current menuspec and
- store that away in the client instead of the current
- menuspec. */
- newMenuSpec = ReplaceMenuSpecForClient(current, pCD);
-
- /* Now store enough information so that we can actually
- create the insertion later. */
- StoreMatchedCommand(client_match_list, newMenuSpec, NULL,
- command_string, treenode, function,
- funcargs, greyed_context);
- }
- else /* Change global menu */
- {
- StoreMatchedCommand(global_match_list, current, match,
- command_string, treenode, function,
- funcargs, greyed_context);
- }
- }
- }
-}
-
-\f
-/*************************************<->*************************************
- *
- * InsertTreeOnClient (pSD, pCD, tree, client_match_list, global_match_list,
- * menuSpec, templateMenuItem, command_so_far,
- * duplicate_globals, selection, greyed_context, inLine)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- * If duplicate_globals is TRUE, then pCD cannot be NULL.
- *
- *************************************<->***********************************/
-
-static void InsertTreeOnClient (WmScreenData *pSD, ClientData *pCD,
- CmdTree *tree,
- MatchList **client_match_list,
- MatchList **global_match_list,
- MenuSpec *menuSpec, MenuItem *template,
- String command_so_far,
- Boolean duplicate_globals, Atom selection,
- Context greyed_context, Boolean inLine)
-{
- String new_command_str;
- int length;
- char funcarg_buf[256];
- MenuSpec *newMenuSpec, *last, *dupMenuSpec;
- CmdTree *subtree;
- MenuItem *bestMatch = (MenuItem *) NULL;
-
- /* If the menuSpec we were given is NULL, then just return. We need to
- at least have a starting menuSpec. */
- if (menuSpec == (MenuSpec *) NULL)
- return;
-
- /* If we want global menus duplicated for a client, then the pCD
- had better not be NULL. */
- if (duplicate_globals && pCD == (ClientData *) NULL)
- return;
-
- while (tree != (CmdTree *) NULL)
- {
- /* The "4" below is to allow for brackets to surround the
- tree->name, the period to separate it from the command
- so far and a NULL. */
- length = (command_so_far != NULL ? strlen(command_so_far) : 0) +
- (tree->name != NULL ? strlen(tree->name) : 0) + 4;
- new_command_str = XtMalloc(sizeof(unsigned char) * length);
- if (command_so_far != (String) NULL)
- sprintf(new_command_str, "%s.<%s>", command_so_far, tree->name);
- else
- sprintf(new_command_str, "<%s>", tree->name);
-
- /* If there is an exclusion preventing this command from being
- inserted, then just continue the loop. @RGC: This is wrong.
- We still want to search for other matches if there is an
- exclusion. We just don't want to allow one of those other
- matches to be this menuSpec. */
- if (ExcludeClientCommand(menuSpec, new_command_str))
- {
- tree = tree->next;
- XtFree(new_command_str);
- continue;
- }
-
- /* If tree is a command set and the inLine flag is TRUE then
- * we need to insert the command sets commands in the current
- * menu spec instead of creating a cascade.
- */
- if (tree->subTrees != (CmdTree *) NULL && inLine == TRUE &&
- ForceInLineToCascade(menuSpec, new_command_str,
- &bestMatch) == FALSE)
- {
- /* Recursively process subtrees */
- for (subtree = tree->subTrees;
- subtree != (CmdTree *) NULL;
- subtree = subtree->next)
- {
- /* Pass along the bestMatch. If it is a valid menu item
- then we want the insertion to occur at that menuitem
- instead of at the end of the menu. */
- InsertTreeOnClient(pSD, pCD, subtree, client_match_list,
- global_match_list, menuSpec, bestMatch,
- new_command_str, duplicate_globals,
- selection, greyed_context, inLine);
- }
- /* We don't want to search for other matches because we
- want the items to be inserted inLine. Any other matches
- will be found in the recursive calls. (??? or am I wrong?) */
- }
- /* If tree is a command set then we need to create a new
- menuSpec. */
- else if (tree->subTrees != (CmdTree *) NULL)
- {
- /* Create the name of the menu for the f.menu command. */
- sprintf(funcarg_buf, "<%s>", tree->name);
-
- /* Store the cascade button information so it can be
- created later. */
- StoreMatchedCommand(
- (menuSpec->clientLocal ? client_match_list : global_match_list),
- menuSpec, template, new_command_str, tree, F_Menu, funcarg_buf,
- greyed_context);
-
- /* We need to create a menu spec for the menu that this cascade
- button will cascade to. Try to find one in the clients menu
- spec list, stopping the first time we hit a global menu. If we
- can't find one there and if we are *not* supposed to duplicate
- globals, then try to find it in the global list. In all other
- cases, create a new one using the funcarg_buf that we created
- above as the name of the menuspec. */
- for (newMenuSpec = (pCD == NULL ? NULL : pCD->systemMenuSpec);
- newMenuSpec != (MenuSpec *) NULL;
- newMenuSpec = newMenuSpec->nextMenuSpec)
- {
- if (newMenuSpec->clientLocal == FALSE)
- {
- newMenuSpec = (MenuSpec *) NULL;
- break;
- }
- if (strcmp(newMenuSpec->name, funcarg_buf) == 0)
- break;
- }
-
- /* If we didn't find it in the client list, maybe we should
- look in the global list. */
- if (newMenuSpec == (MenuSpec *) NULL && duplicate_globals == FALSE)
- {
- for (newMenuSpec = pSD->menuSpecs;
- newMenuSpec != (MenuSpec *) NULL;
- newMenuSpec = newMenuSpec->nextMenuSpec)
- {
- if (strcmp(newMenuSpec->name, funcarg_buf) == 0)
- break;
- }
- }
-
- /* If we still don't have a menu spec, then create a new one. */
- if (newMenuSpec == (MenuSpec *) NULL)
- {
- newMenuSpec = MakeMenuSpec(funcarg_buf,
- tree == NULL ? (CARD32)NULL
- : tree->commandID);
- if (duplicate_globals) newMenuSpec->clientLocal = TRUE;
- else newMenuSpec->clientLocal = FALSE;
-
- /* If we are duplicating globals, then add the new menu spec
- to the client list. Otherwise add it to the global list. */
- if (duplicate_globals)
- last = pCD->systemMenuSpec;
- else
- last = pSD->menuSpecs;
-
- /* Find the last menu spec in the list. */
- while (last != (MenuSpec *) NULL &&
- last->nextMenuSpec != (MenuSpec *) NULL)
- last = last->nextMenuSpec;
-
- /* Put the new menu spec at the end of the list. */
- if (last == (MenuSpec *) NULL)
- {
- if (duplicate_globals)
- pCD->systemMenuSpec = newMenuSpec;
- else
- pSD->menuSpecs = newMenuSpec;
- }
- else last->nextMenuSpec = newMenuSpec;
- }
-
- /* Recursively process subtrees */
- for (subtree = tree->subTrees;
- subtree != (CmdTree *) NULL;
- subtree = subtree->next)
- {
- InsertTreeOnClient(pSD, pCD, subtree, client_match_list,
- global_match_list, newMenuSpec, NULL,
- new_command_str, duplicate_globals,
- selection, greyed_context, inLine);
- }
-
- /* Search for any other matches in the existing menu specs
- for this command, excluding newMenuSpec. */
- SearchForOtherMatches(pSD, pCD, tree,
- client_match_list, global_match_list,
- newMenuSpec, new_command_str,
- F_Menu, funcarg_buf,
- duplicate_globals, selection,
- greyed_context, inLine);
-
- }
- else /* the tree is a simple command */
- {
- /* Store away the push button information so it can be
- created later. */
- sprintf(funcarg_buf, "%d %ld %ld", tree->commandID,
- (pCD == NULL ? None : pCD->client), selection);
-
- /* If the menuSpec is global and we are supposed to be
- duplicating global menu specs, then create a duplicate
- and replace the menuspec with the duplicate for this
- client. */
- if (duplicate_globals)
- dupMenuSpec = ReplaceMenuSpecForClient(menuSpec, pCD);
- else
- dupMenuSpec = menuSpec;
-
- /* Now store the match away in the appropriate match list */
- StoreMatchedCommand((dupMenuSpec->clientLocal ?
- client_match_list : global_match_list),
- dupMenuSpec, template, new_command_str, tree,
- F_InvokeCommand, funcarg_buf, greyed_context);
-
- /* Search for any other matches in the existing menu specs
- for this command, excluding newMenuSpec. */
-
- SearchForOtherMatches(pSD, pCD, tree,
- client_match_list, global_match_list,
- dupMenuSpec, new_command_str,
- F_InvokeCommand, funcarg_buf,
- FALSE, /* Don't duplicate globals not associated
- with this pCD. CR 9623 */
- selection,
- greyed_context, inLine);
- }
-
- /* Move on to the next tree item at this level */
- tree = tree->next;
- XtFree(new_command_str);
- }
-}
-
-\f
-/*************************************<->*************************************
- *
- * InsertTreeOnAllClients (pSD, tree, selection, active_context, inLine)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- * pSD = per screen data
- * tree = command tree
- * selection = owned by inserting client
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-void InsertTreeOnAllClients (WmScreenData *pSD, CmdTree *tree, Atom selection,
- Context active_context, Boolean inLine)
-{
- ClientListEntry *current;
- MatchList *global_matchlist = (MatchList *) NULL;
- MatchList *client_matchlist = (MatchList *) NULL;
- Context greyed_context = F_CONTEXT_ALL;
-
- /* If there aren't any clients, then there's nothing to do. */
- if (pSD->clientList == (ClientListEntry *) NULL)
- return;
-
- /* Setup the greyed context based on the active context */
- if (active_context & F_CONTEXT_WINDOW)
- greyed_context &= ~(F_CONTEXT_WINDOW);
- if (active_context & F_CONTEXT_ICON)
- greyed_context &= ~(F_CONTEXT_ICON);
-
- for (current = pSD->clientList;
- current != (ClientListEntry *) NULL;
- current = current->nextSibling)
- {
- /* Ignore client list entries for icons. */
- if (current->type == MINIMIZED_STATE)
- continue;
- InsertTreeOnClient(pSD, current->pCD, tree, &client_matchlist,
- &global_matchlist, current->pCD->systemMenuSpec,
- NULL, NULL, FALSE,
- selection, greyed_context, inLine);
- PerformInsertionsOnMatchList(&client_matchlist);
- RecreateMenuWidgets(pSD, current->pCD, &client_matchlist);
- FreeMatchList(&client_matchlist);
- }
- PerformInsertionsOnMatchList(&global_matchlist);
- RecreateMenuWidgets(pSD, NULL /* no pcd */, &global_matchlist);
- FreeMatchList(&global_matchlist);
-}
-
-\f
-/*************************************<->*************************************
- *
- * InsertTreeOnSingleClient (pSD, pCD, tree, selection, inLine)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- * pSD = per screen data
- * tree = command tree
- * selection = owned by inserting client
- *
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-void InsertTreeOnSingleClient (WmScreenData *pSD, ClientData *pCD,
- CmdTree *tree, Atom selection,
- Context active_context, Boolean inLine)
-{
- MatchList *global_matchlist = (MatchList *) NULL;
- MatchList *client_matchlist = (MatchList *) NULL;
- Context greyed_context = F_CONTEXT_ALL;
-
- /* A quick sanity check */
- if (pCD == (ClientData *) NULL)
- return;
-
- /* Setup the greyed context based on the active context */
- if (active_context & F_CONTEXT_WINDOW)
- greyed_context &= ~(F_CONTEXT_WINDOW);
- if (active_context & F_CONTEXT_ICON)
- greyed_context &= ~(F_CONTEXT_ICON);
-
- InsertTreeOnClient(pSD, pCD, tree, &client_matchlist,
- &global_matchlist, pCD->systemMenuSpec,
- NULL, NULL, TRUE, selection, greyed_context, inLine);
- PerformInsertionsOnMatchList(&client_matchlist);
- RecreateMenuWidgets(pSD, pCD, &client_matchlist);
- FreeMatchList(&client_matchlist);
-}
-
-\f
-/*************************************<->*************************************
- *
- * InsertTreeOnRootMenu (pSD, tree, selection, active_context, inLine)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- * pSD = per screen data
- * tree = command tree
- * selection = owned by inserting client
- *
- *
- * Outputs:
- * -------
- * Return =
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-void InsertTreeOnRootMenu (WmScreenData *pSD, CmdTree *tree, Atom selection,
- Boolean inLine)
-{
- MatchList *global_matchlist = (MatchList *) NULL;
- MatchList *client_matchlist = (MatchList *) NULL;
- Context greyed_context = F_CONTEXT_WINDOW | F_CONTEXT_ICON;
- MenuSpec *rootMenu;
-
- /* Find the root menu spec */
- for (rootMenu = pSD->menuSpecs;
- rootMenu != (MenuSpec *) NULL;
- rootMenu = rootMenu->nextMenuSpec)
- {
- if (strcmp(rootMenu->name, pSD->rootMenu) == 0)
- break;
- }
-
- /* If we couldn't find the root menu, then do nothing. */
- if (rootMenu == (MenuSpec *) NULL) return;
-
- InsertTreeOnClient(pSD, NULL, tree, &client_matchlist,
- &global_matchlist, rootMenu,
- NULL, NULL, FALSE, selection, greyed_context, inLine);
- PerformInsertionsOnMatchList(&client_matchlist);
- RecreateMenuWidgets(pSD, NULL, &client_matchlist);
- FreeMatchList(&client_matchlist);
- PerformInsertionsOnMatchList(&global_matchlist);
- RecreateMenuWidgets(pSD, NULL, &global_matchlist);
- FreeMatchList(&global_matchlist);
-}
-
-\f
-/*************************************<->*************************************
- *
- * RemoveClientCommandFromMenuSpec (menuSpec, id)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static Boolean RemoveClientCommandFromMenuSpec (MenuSpec *menuSpec,
- CARD32 id)
-{
- MenuItem *curMenuItem, *prevMenuItem = (MenuItem *) NULL;
- MenuItem *tmpMenuItem;
- Boolean was_changed = FALSE;
-
- curMenuItem = menuSpec->menuItems;
- while (curMenuItem != (MenuItem *) NULL)
- {
- if (curMenuItem->clientCommandID == id)
- {
- tmpMenuItem = curMenuItem;
- curMenuItem = curMenuItem->nextMenuItem;
- if (prevMenuItem == (MenuItem *) NULL)
- menuSpec->menuItems = tmpMenuItem->nextMenuItem;
- else
- prevMenuItem->nextMenuItem = tmpMenuItem->nextMenuItem;
- FreeMenuItem(tmpMenuItem);
- was_changed = TRUE;
- }
- else
- {
- prevMenuItem = curMenuItem;
- curMenuItem = curMenuItem->nextMenuItem;
- }
- }
- return(was_changed);
-}
-
-\f
-/*************************************<->*************************************
- *
- * ModifyClientCommandForMenuSpec (menuSpec, id, modifier, context, newname)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static Boolean ModifyClientCommandForMenuSpec (MenuSpec *menuSpec,
- CARD32 id,
- CmdModifier modifier,
- Context context,
- String newname)
-{
- MenuItem *curMenuItem;
- Boolean was_changed = FALSE;
- int i, freebutton, buttoncount;
-
- /* If the menuspec doesn't have any buttons or a valid menu widget
- then we don't want to search it. */
- if (menuSpec->menuWidget == (Widget) NULL ||
- menuSpec->menuButtons == (MenuButton *) NULL ||
- menuSpec->menuButtonCount == 0)
- return(FALSE);
-
- /* Search through all the menu buttons of the menuspec for buttons
- which match the command ID to be removed. */
- for (i = 0; i < menuSpec->menuButtonCount; ++i)
- {
- curMenuItem = menuSpec->menuButtons[i].menuItem;
-
- if ((curMenuItem->clientCommandID == id) &&
- (curMenuItem->wmFunction == F_InvokeCommand))
+ else
{
- switch(modifier)
+ if (XtIsManaged((Widget)children[wPos -1]))
{
- case ENABLE:
- /* "context" is an active context */
- curMenuItem->greyedContext &= ~(context);
- /* Adjust the pushbutton to the state it would have had
- given the last posting context. */
- if (menuSpec->currentContext & curMenuItem->greyedContext)
- XtSetSensitive(menuSpec->menuButtons[i].buttonWidget,
- FALSE);
- else
- XtSetSensitive(menuSpec->menuButtons[i].buttonWidget,
- TRUE);
- break;
- case DISABLE:
- /* "context" is a greyed context */
- curMenuItem->greyedContext |= context;
- /* Adjust the pushbutton to the state it would have had
- given the last posting context. */
- if (menuSpec->currentContext & curMenuItem->greyedContext)
- XtSetSensitive(menuSpec->menuButtons[i].buttonWidget,
- FALSE);
- else
- XtSetSensitive(menuSpec->menuButtons[i].buttonWidget,
- TRUE);
- break;
- case RENAME:
- if (newname != NULL && *newname != '\0')
- {
- /* When renaming a command, we shouldn't cause the
- * entire menu to be recreated. Recreating the menu
- * will cause problems with tearoffs since the menu
- * will disappear when it is destroyed. CR 9719
- */
- XmString labelString;
-
- /* Change the label of the menu item */
- XtFree(curMenuItem->label);
- /* Give the menu item the new name */
- curMenuItem->label = XtNewString(newname);
- was_changed = False; /* all taken care of here. */
-
- /* This is needed when changing the label since
- * mwm will wait for a geometry reply from itself which
- * it can never service. CR 9719
- */
- XtVaSetValues(XtParent(XtParent(menuSpec->menuButtons[i].buttonWidget)),
- XmNuseAsyncGeometry, TRUE, NULL);
-
- labelString = XmStringGenerate(curMenuItem->label,
- XmFONTLIST_DEFAULT_TAG,
- XmCHARSET_TEXT, NULL);
- XtVaSetValues(menuSpec->menuButtons[i].buttonWidget,
- XmNlabelString, labelString,
- NULL);
- XmStringFree(labelString);
- }
- break;
- case REMOVE:
- XtDestroyWidget(menuSpec->menuButtons[i].buttonWidget);
- menuSpec->menuButtons[i].managed = FALSE;
- menuSpec->menuButtons[i].menuItem = (MenuItem *) NULL;
- menuSpec->menuButtons[i].buttonWidget = (Widget) NULL;
- break;
+ XtUnmanageChild((Widget)children[wPos -1]);
}
}
}
- /* If we are being asked to remove a client command, then we need
- * to search through all the menu items as well as the buttons.
- * Do the menu items here.
- */
- if (modifier == REMOVE)
- was_changed = RemoveClientCommandFromMenuSpec(menuSpec, id);
+} /* END OF FUNCTION CheckTerminalSeparator */
- /* Compact the menu buttons array. */
- buttoncount = menuSpec->menuButtonCount;
- freebutton = 0;
- for (i = 0; i < buttoncount; ++i)
- {
- if (menuSpec->menuButtons[i].buttonWidget == (Widget) NULL)
- --menuSpec->menuButtonCount;
- else
- {
- menuSpec->menuButtons[freebutton].menuItem =
- menuSpec->menuButtons[i].menuItem;
- menuSpec->menuButtons[freebutton].buttonWidget =
- menuSpec->menuButtons[i].buttonWidget;
- menuSpec->menuButtons[freebutton].managed =
- menuSpec->menuButtons[i].managed;
- ++freebutton;
- }
- }
- return(was_changed);
-}
-\f
/*************************************<->*************************************
*
- * ModifyClientCommandID (pSD, pCD, range, id, modifier, context, newname)
+ * DuplicateMenuItems (menuItems)
+ *
*
*
* Description:
* -----------
+ * This function creates an indentical duplicate of the given menuItems
+ * list.
+ *
*
* Inputs:
* ------
+ * menuItems = the linked list of menuItems to duplicate
+ *
*
* Outputs:
* -------
+ * Return = pointer to a new MenuItems list, identical to the original
+ *
*
* Comments:
* --------
*
*************************************<->***********************************/
-static void ModifyClientCommandID (WmScreenData *pSD,
- ClientData *pCD,
- OpRange range,
- CARD32 id,
- CmdModifier modifier,
- Context context,
- String newname)
+static MenuItem *
+DuplicateMenuItems (MenuItem *menuItems)
{
- MenuSpec *curMenuSpec;
- ClientListEntry *curClient;
-
- switch(range)
+ MenuItem *newMenuItem = (MenuItem *) NULL, *returnMenuItem, *curMenuItem;
+
+ for (curMenuItem = menuItems;
+ curMenuItem != (MenuItem *) NULL;
+ curMenuItem = curMenuItem->nextMenuItem)
{
- case ALL:
- /* Search through all the menu specs of all the clients. */
- for (curClient = pSD->clientList;
- curClient != (ClientListEntry *) NULL;
- curClient = curClient->nextSibling)
+ /* If its the first one ... */
+ if (newMenuItem == (MenuItem *) NULL)
{
- for (curMenuSpec = curClient->pCD->systemMenuSpec;
- curMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
- {
- /* If the menu spec is global then stop searching
- for this client. */
- if (curMenuSpec->clientLocal == FALSE)
- break;
- if (ModifyClientCommandForMenuSpec(curMenuSpec, id,
- modifier, context,
- newname) == TRUE)
- {
- DestroyMenuSpecWidgets(curMenuSpec);
- curMenuSpec->menuWidget =
- CreateMenuWidget (pSD, curClient->pCD, curMenuSpec->name,
- pSD->screenTopLevelW, TRUE,
- curMenuSpec, NULL);
- }
- }
+ newMenuItem = (MenuItem *)XtMalloc(sizeof(MenuItem));
+ returnMenuItem = newMenuItem;
}
- /* Search through all the global menu specs. */
- for (curMenuSpec = pSD->menuSpecs;
- curMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
+ else /* ... otherwise, get the next menuItem. */
{
- if (ModifyClientCommandForMenuSpec(curMenuSpec, id, modifier,
- context, newname) == TRUE)
- {
- DestroyMenuSpecWidgets(curMenuSpec);
- curMenuSpec->menuWidget =
- CreateMenuWidget (pSD, NULL, curMenuSpec->name,
- pSD->screenTopLevelW, TRUE,
- curMenuSpec, NULL);
- }
+ newMenuItem->nextMenuItem =
+ (MenuItem *)XtMalloc(sizeof(MenuItem));
+ newMenuItem = newMenuItem->nextMenuItem;
}
- break;
- case ROOT:
- {
+
+ newMenuItem->labelType = curMenuItem->labelType;
+ if (curMenuItem->label != (String) NULL)
+ newMenuItem->label = XtNewString(curMenuItem->label);
+ else
+ newMenuItem->label = NULL;
+ newMenuItem->labelBitmapIndex = curMenuItem->labelBitmapIndex;
+ newMenuItem->mnemonic = curMenuItem->mnemonic;
+ newMenuItem->accelState = curMenuItem->accelState;
+ newMenuItem->accelKeyCode = curMenuItem->accelKeyCode;
+ if (curMenuItem->accelText != (String) NULL)
+ newMenuItem->accelText = XtNewString(curMenuItem->accelText);
+ else
+ newMenuItem->accelText = NULL;
+ newMenuItem->wmFunction = curMenuItem->wmFunction;
+
+ if ((curMenuItem->wmFunction == F_Send_Msg)
+ || (curMenuItem->wmFunction == F_Set_Context)
/*
- * This section was changed to search the entire global menu list.
- * This was done to allow access to menu entries included using the
- * cci/.mwmrc interface. Before, only the actual root menu could
- * be modified; however, the user could still include commands in
- * other menus specified in the .mwmrc file using the f.cci command.
+ * NOTE: For now, in dtwm this function is used only
+ * to copy the FrontPanel menu. So, we know that
+ * curMenuItem->wmFuncArgs isn't going anywhere,
+ * so it's safe to simply point at it. If at some
+ * point it becomes possible that curMenuItem->wmFuncArgs
+ * can go away, we'll need to make a (deep) copy of
+ * the WmActionArg. 11/20/96
*/
+ || (curMenuItem->wmFunction == F_Action)
+ )
+ newMenuItem->wmFuncArgs = curMenuItem->wmFuncArgs;
+ else if (curMenuItem->wmFuncArgs != (String) NULL)
+ newMenuItem->wmFuncArgs = XtNewString(curMenuItem->wmFuncArgs);
+ else
+ newMenuItem->wmFuncArgs = NULL;
-
- MenuSpec *curMenuSpec;
-
- /* Search through all the global menu specs. */
- for (curMenuSpec = pSD->menuSpecs;
- curMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
- {
- if (ModifyClientCommandForMenuSpec(curMenuSpec, id, modifier,
- context, newname) == TRUE)
- {
- DestroyMenuSpecWidgets(curMenuSpec);
- curMenuSpec->menuWidget =
- CreateMenuWidget (pSD, NULL, curMenuSpec->name,
- pSD->screenTopLevelW, TRUE,
- curMenuSpec, NULL);
- }
- }
- }
- break;
- case SINGLE:
- /* If we weren't passed a valid pCD, then just return. */
- if (pCD == (ClientData *) NULL) return;
-
- /* Search through the clients menu specs. If we find one that
- is global then stop search if we are ENABLING or DISABLING.
- If we are REMOVING and we find a global, we may need to
- perform some menu spec replacing to make the menu spec that
- needs modification local to the client. */
- for (curMenuSpec = pCD->systemMenuSpec;
- curMenuSpec != (MenuSpec *) NULL;
- curMenuSpec = curMenuSpec->nextMenuSpec)
- {
- if (curMenuSpec->clientLocal == FALSE)
- {
- MenuSpec *last, *cur;
-
- /* Find the last global menuspec in the clients list
- that needs to be changed and return it. Replace
- all menuspecs between the current one and the
- "last" one that needs changing. All the replaced
- menuspecs will be marked as local, so that next
- time clientLocal is FALSE in the enclosing for
- loop above, there will be no global menu specs
- needing changes. In other words, all the required
- menu spec replacing will occur the first time we
- find a global menu spec. */
- last = FindLastMenuSpecToModify(curMenuSpec, id);
- if (last != (MenuSpec *) NULL)
- {
- MenuSpec *newMenuSpec = (MenuSpec *) NULL;
- MenuSpec *firstMenuSpec = (MenuSpec *) NULL;
- MenuSpec *lastMenuSpec = (MenuSpec *) NULL;
-
- /* Replace all the global menu specs with local
- ones. */
- for (cur = curMenuSpec;
- cur != (MenuSpec *) NULL && cur != last->nextMenuSpec;
- cur = cur->nextMenuSpec)
- {
- newMenuSpec = ReplaceMenuSpecForClient(cur, pCD);
- if (cur == curMenuSpec)
- curMenuSpec = firstMenuSpec = newMenuSpec;
- /* If there is only one menu spec to change,
- the first will also be the last. */
- if (cur == last)
- lastMenuSpec = newMenuSpec;
- }
-
- /* Now that we have replaced all the menu specs,
- recreate all the widgets for the new menu specs. */
- for (cur = firstMenuSpec;
- cur != (MenuSpec *) NULL &&
- cur != lastMenuSpec->nextMenuSpec;
- cur = cur->nextMenuSpec)
- {
- DestroyMenuSpecWidgets(newMenuSpec);
- newMenuSpec->menuWidget =
- CreateMenuWidget(pSD, pCD, newMenuSpec->name,
- pSD->screenTopLevelW,
- TRUE, newMenuSpec, NULL);
- }
-
- }
- /* None of the globals need changing. */
- else break;
- }
- if (ModifyClientCommandForMenuSpec(curMenuSpec, id, modifier,
- context, newname) == TRUE)
- {
- DestroyMenuSpecWidgets(curMenuSpec);
- curMenuSpec->menuWidget =
- CreateMenuWidget (pSD, pCD, curMenuSpec->name,
- pSD->screenTopLevelW, TRUE,
- curMenuSpec, NULL);
- }
- }
- break;
+ newMenuItem->greyedContext = curMenuItem->greyedContext;
+ newMenuItem->mgtMask = curMenuItem->mgtMask;
+ newMenuItem->nextMenuItem = (MenuItem *) NULL;
}
+
+ return(returnMenuItem);
}
-\f
/*************************************<->*************************************
*
- * ModifyClientCommandTree (pSD, pCD, range, tree, modifier, context, newname)
+ * DuplicateMenuSpec (menuSpec)
+ *
*
*
* Description:
* -----------
+ * This function creates an indentical duplicate of the given menuSpec.
+ * The menuItems list in the menuSpec is also duplicated.
+ *
*
* Inputs:
* ------
+ * menuSpec = the menuSpec to duplicate
+ *
*
* Outputs:
* -------
+ * Return = pointer to a new MenuSpec structure with the same field
+ * values as the original
+ *
*
* Comments:
* --------
+ * A new MenuSpec structure is allocated. Most of he fields of the new
+ * structure are set to the same values as the passed in menuSpec.
+ * There are some differences between the two final structures.
+ * One difference: any fields related to push buttons and other
+ * widgets are left blank in the new MenuSpec to be filled in later.
*
*************************************<->***********************************/
-void ModifyClientCommandTree (WmScreenData *pSD,
- ClientData *pCD,
- OpRange range,
- CmdTree *tree,
- CmdModifier modifier,
- Context context,
- String newname)
+MenuSpec *
+DuplicateMenuSpec (MenuSpec *menuSpec)
{
- CmdTree *curTree;
- CARD32 cmdID;
-
- /* Run through the top level of the tree. */
- for (curTree = tree; curTree != (CmdTree *) NULL; curTree = curTree->next)
+ MenuSpec *newMenuSpec;
+
+ if ((newMenuSpec = (MenuSpec *) XtMalloc (sizeof (MenuSpec))) == NULL)
+ /* Handle insufficent memory */
{
- cmdID = curTree->commandID;
- ModifyClientCommandID(pSD, pCD, range, cmdID, modifier,
- context, newname);
- if (curTree->subTrees != (CmdTree *) NULL)
- ModifyClientCommandTree(pSD, pCD, range, curTree->subTrees,
- modifier, context, newname);
+ Warning((char *)GETMESSAGE(48, 9,
+ "Insufficient memory for menu specification\n"));
+ return (NULL);
}
+ newMenuSpec->name = XtNewString(menuSpec->name);
+ newMenuSpec->currentContext = menuSpec->currentContext;
+ newMenuSpec->menuWidget = (Widget) NULL;
+ newMenuSpec->whichButton = menuSpec->whichButton;
+ newMenuSpec->height = menuSpec->height;
+ newMenuSpec->menuItems = DuplicateMenuItems(menuSpec->menuItems);
+ newMenuSpec->menuButtons = (MenuButton *) NULL;
+ newMenuSpec->menuButtonSize = 0;
+ newMenuSpec->menuButtonCount = 0;
+ newMenuSpec->accelContext = menuSpec->accelContext;
+ newMenuSpec->accelKeySpecs = (KeySpec *) NULL;
+ newMenuSpec->nextMenuSpec = (MenuSpec *) NULL;
+
+ return(newMenuSpec);
}
-#endif /* defined(MWM_QATS_PROTOCOL) */
-\f
+
/*************************************<->*************************************
*
* static Boolean
}
-
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * AdjustTearOffControl (cascade, closure, cbackdata)
- *
- *
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- *
- * Outputs:
- * -------
- * returns true iff the tearoff control was enabled or diabled
- * resulting in a change in height.
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static Boolean
-AdjustTearOffControl (Widget cascade,
- XtPointer closure,
- XtPointer cbackdata)
-{
- Widget submenu = (Widget) closure;
- int argn;
- Arg args[10];
- unsigned char tearoff_model;
- Boolean isMwmMenu;
-
- argn = 0;
- XtSetArg(args[argn], XmNtearOffModel, &tearoff_model); ++argn;
- XtGetValues(submenu, args, argn);
-
- /* Is this a root menu or a cascade of a root menu? */
- /* If cbackdata is not null, then we got here by cascading. */
- /* Cascade menus from a tearoff menu-pane are not allowed. */
- /* there is no way to know if the cascade is from a tearoff */
- /* or from a cascade on a system menu. */
- if ((wmGD.menuClient == NULL) && (cbackdata == NULL))
- isMwmMenu = True;
- else
- isMwmMenu = False;
-
- if ((tearoff_model == XmTEAR_OFF_ENABLED) && !isMwmMenu)
- {
- PRINT("Disabling the tear off\n");
- argn = 0;
- XtSetArg(args[argn], XmNtearOffModel, XmTEAR_OFF_DISABLED); ++argn;
- XtSetValues(submenu, args, argn);
-
- return (True);
- }
-
- /* If this was invoked as a cascadingCallback and not by hand and if
- the menuActive field of the global data has not yet been set, then
- we can safely assume that we have just cascaded off of a torn off
- menu. In that case, set the menuActive field to be the menu spec of
- the torn off menu and register an unmap callback on the cascaded
- menu that will clear the menuActive field. */
- if (cbackdata != (XtPointer) NULL && wmGD.menuActive == (MenuSpec *) NULL)
- {
- MenuSpec *menuspec;
- Widget tearoff_widget = XtParent(cascade);
-
- for (menuspec = wmGD.Screens[0].menuSpecs;
- menuspec != (MenuSpec *) NULL;
- menuspec = menuspec->nextMenuSpec)
- {
- if (tearoff_widget == menuspec->menuWidget)
- {
- wmGD.menuActive = menuspec;
- break;
- }
- }
-
- /* If we can't find a menuspec for the torn off menu, then just
- take the first menu spec in the list of menuSpecs for the
- active pSD. NOTE: THIS SHOULD NEVER HAPPEN. In fact if it
- does, I'm not sure how mwm will behave having been given
- the wrong menu spec as the active menu. */
- if (wmGD.menuActive == (MenuSpec *) NULL)
- {
- wmGD.menuActive = ACTIVE_PSD->menuSpecs;
- PRINT("Couldn't find menu spec for tear off\n");
- }
-
- /* Add a callback that will clear menuActive when this cascade
- is unmapped. */
-#if 0
- XtAddCallback (submenu, XmNunmapCallback,
-#else
- XtAddCallback (XtParent(submenu), XmNpopdownCallback,
-#endif
- UnmapPulldownCallback,
- (XtPointer) NULL);
- }
-
- return (False);
-}
-\f
-
-/*************************************<->*************************************
- *
- * static Boolean
- * CreateClientCommandSeparator (menuItem, child_position, last_child,
- * newMenuItem)
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-static Boolean CreateClientCommandSeparator (MenuItem *menuItem,
- int child_position,
- Widget last_child,
- MenuItem **newMenuItem)
-{
- MenuItem *curMenuItem;
-
- /* If it is a client command, then we only want to create the
- * separator under particular circumstances. Specifically, we
- * want to make sure that:
- * 1. a separator doesn't directly precede this one
- * 2. a separator doesn't directly follow this one
- * 3. this separator won't be the first or last item in the menu
- * 4. the client command that this separator surrounds actually
- * matched something and is not an unmatched template
- */
-
- /* Check if a separator directly precedes this one. */
- if (child_position > 0 && last_child != (Widget) NULL &&
- XmIsSeparator(last_child))
- return(FALSE);
-
- /* Check if a separator directly follows this one. */
- if (menuItem->nextMenuItem != (MenuItem *) NULL &&
- menuItem->nextMenuItem->wmFunction == F_Separator &&
- IsClientCommand(menuItem->nextMenuItem->label) == FALSE)
- return(FALSE);
-
- /* Make sure this separator won't be the first item in the menu. */
- if (child_position == 0) return(FALSE);
-
- /* Make sure this separator won't be the last item in the menu. */
- if (menuItem->nextMenuItem == (MenuItem *) NULL)
- return(FALSE);
-
- /* Make sure that the client command this separator surrounds actually
- matches something. We only do this check if the separator is the
- TOP separator in the separator pair. If we are looking at a bottom
- separator then we can safely assume something matched, otherwise
- we would have passed over it when we look at the corresponding top
- separator. */
- if (menuItem->labelType == TOP_SEPARATOR)
- {
- /* If we find a real menu item (not just a template) before we find
- a bottom separator, then create the separator. */
- for (curMenuItem = menuItem;
- curMenuItem != (MenuItem *) NULL;
- curMenuItem = curMenuItem->nextMenuItem)
- {
- /* If we found the closing separator, then return FALSE and
- our new menu item position. */
- if (curMenuItem->wmFunction == F_Separator &&
- IsClientCommand(curMenuItem->label) &&
- curMenuItem->labelType == BOTTOM_SEPARATOR)
- {
- *newMenuItem = curMenuItem;
- return(FALSE);
- }
- /* If we found a real menu item, then return TRUE. */
- if (curMenuItem->wmFunction != F_Separator &&
- !IsClientCommand(curMenuItem->label))
- {
- return(TRUE);
- }
- }
- /* If by some bizarre chance we get to the end of the list
- without finding either, then return FALSE. Something is wrong. */
- if (curMenuItem == (MenuItem *) NULL) return(FALSE);
- }
-
- /* Well, nothing failed so let's create it. */
- return(TRUE);
-}
-#endif /* defined(MWM_QATS_PROTOCOL) */
-\f
/*************************************<->*************************************
*
* CreateMenuWidget (pSD, menuName, parent, fTopLevelPane, topMenuSpec,
} StrList;
Widget CreateMenuWidget (WmScreenData *pSD,
-#if (defined(MWM_QATS_PROTOCOL))
- ClientData *pCD,
-#endif /* defined(MWM_QATS_PROTOCOL) */
String menuName, Widget parent,
Boolean fTopLevelPane, MenuSpec *topMenuSpec,
MenuItem *moreMenuItems)
KeySpec *accelKeySpec;
Dimension menuHeight;
Boolean fUseTitleSep = False;
-#if (defined(MWM_QATS_PROTOCOL))
- Boolean labelIsClientCommand = False;
-#endif /* defined(MWM_QATS_PROTOCOL) */
StrList *stringsToFree = NULL, *sPtr;
XmString tmpstr;
#ifndef IBM_151913
{
i = 0;
-#if (defined(MWM_QATS_PROTOCOL))
- labelIsClientCommand = IsClientCommand(menuItem->label);
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
if (menuItem->wmFunction == F_Separator)
/*
* Add a Separator gadget for a menu separator.
* An immediately following title will not have a top separator.
*/
{
-#if (defined(MWM_QATS_PROTOCOL))
- /* If it is a client command, then we only want to create the
- * separator under particular circumstances. Specifically, we
- * want to make sure that:
- * 1. a separator doesn't directly precede this one
- * 2. a separator doesn't directly follow this one
- * 3. this separator won't be the first or last item in the menu
- */
- if (labelIsClientCommand)
- {
- if (CreateClientCommandSeparator(menuItem, n,
- (n > 0 ? children[n - 1] :
- (Widget) NULL),
- &menuItem))
- {
- /* Increment the counter here because we only increment
- at the end of the loop if the item is not a client
- command item (i.e. labelIsClientCommand == FALSE) */
- children[n++] =
- XmCreateSeparatorGadget (menuW, SEPARATOR_NAME,
- (ArgList)NULL, 0);
- fUseTitleSep = FALSE;
- }
- }
- else
-#endif /* defined(MWM_QATS_PROTOCOL) */
{
children[n] =
XmCreateSeparatorGadget (menuW, SEPARATOR_NAME,
} /* F_Separator */
else
-#if (defined(MWM_QATS_PROTOCOL))
- if (!labelIsClientCommand)
-#endif /* defined(MWM_QATS_PROTOCOL) */
/*
* We will use one of:
*
i++;
children[n] = XmCreateCascadeButtonGadget (menuW,
CASCADE_BTN_NAME, (ArgList) args, i);
-#if (defined(MWM_QATS_PROTOCOL))
- XtAddCallback(children[n], XmNcascadingCallback,
- (XtCallbackProc)AdjustTearOffControl,
- (XtPointer)subMenuW);
-#endif /* defined(MWM_QATS_PROTOCOL) */
}
else
/*
* Increment the children array count if we actually
* created a new child.
*/
-#if (defined(MWM_QATS_PROTOCOL))
- if (!labelIsClientCommand)
-#endif /* defined(MWM_QATS_PROTOCOL) */
- n++;
+ n++;
/*
* Next menu item: handle custom items and full children[].
XButtonPressedEvent event;
Window saveWindow;
Display *saveDisplay;
-#if (defined(MWM_QATS_PROTOCOL))
- Boolean menuAdjusted;
-#endif /* defined(MWM_QATS_PROTOCOL) */
if ((menuSpec == NULL) || (menuSpec->menuWidget == NULL))
{
}
-#if (defined(MWM_QATS_PROTOCOL))
- menuAdjusted =
- AdjustTearOffControl(NULL, (XtPointer) (menuSpec->menuWidget), NULL);
-#endif /* defined(MWM_QATS_PROTOCOL) */
- if (AdjustPBs (menuSpec, pCD, newContext)
-#if (defined(MWM_QATS_PROTOCOL))
- || menuAdjusted
-#endif /* defined(MWM_QATS_PROTOCOL) */
- )
+ if (AdjustPBs (menuSpec, pCD, newContext))
{
i = 0;
XtSetArg (args[i], XtNheight, &menuHeight); i++;
} /* END OF FUNCTION MWarning */
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * UnmapPulldownCallback (w, client_data, call_data)
- *
- *
- * Description:
- * -----------
- *
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void UnmapPulldownCallback (Widget w, XtPointer client_data,
- XtPointer call_data)
-{
- wmGD.menuActive = (MenuSpec *) NULL;
-} /* END OF FUNCTION UnmapPulldownCallback */
-#endif /* defined(MWM_QATS_PROTOCOL) */
-\f
/*************************************<->*************************************
*
* TraversalOff (menuSpec)
#define MBBSIZ 4096
-#if (defined(MWM_QATS_PROTOCOL))
-# define PARSE_MENU_ITEMS(pSD, mSpec) ParseMenuItems(pSD, mSpec)
-#else
-# define PARSE_MENU_ITEMS(pSD, mSpec) ParseMenuItems(pSD)
-#endif /* defined(MWM_QATS_PROTOCOL) */
+#define PARSE_MENU_ITEMS(pSD, mSpec) ParseMenuItems(pSD)
/*
* include extern functions
Boolean fClick;
} EventTableEntry;
-#if (defined(MWM_QATS_PROTOCOL))
-
-# define CCI_USE_DEFAULT_NAME_TAG "DEFAULT_NAME"
-
-String CCIEntryModifierNames[] = {
- "none",
- "inline",
- "cascade",
- "delimit",
- "delimit_inline",
- "delimit_cascade",
- "exclude"
-};
-
-typedef enum {
- NONE, /* internal only. */
- INLINE, /* not supported. */
- CASCADE,
- DELIMIT,
- DELIMIT_INLINE, /* not supported. */
- DELIMIT_CASCADE,
- EXCLUDE
-} CCIEntryModifier;
-
-typedef struct _CCIFuncArg {
- CCIEntryModifier mod;
- String cciEntry;
-} CCIFuncArg;
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
static String GetNetworkFileName (char *pchFile);
-#if (defined(MWM_QATS_PROTOCOL))
-static MenuItem *MakeSeparatorTemplate (int);
-static void ParseMenuItemName (unsigned char **linePP, MenuItem *menuItem);
-static Boolean ParseClientCommand (unsigned char **linePP, MenuSpec *menuSpec,
- MenuItem *menuItem, unsigned char *string,
- Boolean *use_separators);
-static void FixMenuItem (MenuSpec *menuSpec, MenuItem *menuItem);
-static Boolean GetCCIModifier (String modString, CCIEntryModifier *mod);
-static Boolean ParseWmFuncCCIArgs (unsigned char **linePP,
- WmFunction wmFunction, String *pArgs);
-#endif /* defined(MWM_QATS_PROTOCOL) */
FILE *FopenConfigFile (void);
void SaveMenuAccelerators (WmScreenData *pSD, MenuSpec *newMenuSpec);
static void ParseMenuSet (WmScreenData *pSD, unsigned char *lineP);
MenuItem *ParseMwmMenuStr (WmScreenData *pSD, unsigned char *menuStr);
-static MenuItem *ParseMenuItems (WmScreenData *pSD
-#if (defined(MWM_QATS_PROTOCOL))
- , MenuSpec *menuSpec
-#endif /* defined(MWM_QATS_PROTOCOL) */
- );
+static MenuItem *ParseMenuItems (WmScreenData *pSD);
static Boolean ParseWmLabel (WmScreenData *pSD, MenuItem *menuItem,
unsigned char *string);
static void ParseWmMnemonic (unsigned char **linePP, MenuItem *menuItem);
0,
F_Beep,
ParseWmFuncNoArg},
-#if (defined(MWM_QATS_PROTOCOL))
- {"f.cci", 0,
- CRS_ANY,
- 0,
- F_Nop,
- ParseWmFuncCCIArgs},
-#endif /* defined(MWM_QATS_PROTOCOL) */
{"f.circle_down", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON,
CRS_ANY,
0,
0,
F_Help_Mode,
ParseWmFuncNoArg}, /* for now */
-#if (defined(MWM_QATS_PROTOCOL))
- {"f.invoke_command",
- 0, CRS_ANY,
- 0,
- F_InvokeCommand,
- ParseWmFuncStrArg},
-#endif /* defined(MWM_QATS_PROTOCOL) */
{"f.kill", F_CONTEXT_ROOT,
CRS_ANY,
MWM_FUNC_CLOSE,
0,
F_Pass_Key,
ParseWmFuncNoArg},
-#if (defined(MWM_QATS_PROTOCOL))
- {"f.post_rmenu", 0,
- CRS_KEY,
- 0,
- F_Post_RMenu,
- ParseWmFuncNoArg},
-#endif /* defined(MWM_QATS_PROTOCOL) */
{"f.post_wmenu", 0,
CRS_BUTTON|CRS_KEY,
0,
/*
* Be sure to update these define, whenever adding/deleting a function.
*/
-#if (defined(MWM_QATS_PROTOCOL))
-# define F_CCI_INDEX 2
-#endif /* defined(MWM_QATS_PROTOCOL) */
int F_ACTION_INDEX;
int F_EXEC_INDEX;
int F_NOP_INDEX;
menuSpec->menuItems = NULL;
menuSpec->accelContext = 0;
menuSpec->accelKeySpecs = NULL;
-#if (defined(MWM_QATS_PROTOCOL))
- menuSpec->exclusions = NULL;
- menuSpec->clientLocal = FALSE;
-#endif /* defined(MWM_QATS_PROTOCOL) */
menuSpec->nextMenuSpec = NULL;
/*
*
*************************************<->***********************************/
-static MenuItem *ParseMenuItems (WmScreenData *pSD
-#if (defined(MWM_QATS_PROTOCOL))
- , MenuSpec *menuSpec
-#endif /* defined(MWM_QATS_PROTOCOL) */
- )
+static MenuItem *ParseMenuItems (WmScreenData *pSD)
{
unsigned char *string;
unsigned char *lineP;
MenuItem *lastMenuItem;
MenuItem *menuItem;
register int ix;
-#if (defined(MWM_QATS_PROTOCOL))
- Boolean use_separators = False;
-#endif /* defined(MWM_QATS_PROTOCOL) */
/*
* Parse "label [mnemonic] [accelerator] function" or
menuItem->nextMenuItem = NULL;
menuItem->wmFunction = (WmFunction)NULL;
menuItem->wmFuncArgs = NULL;
-#if (defined(MWM_QATS_PROTOCOL))
- menuItem->clientCommandName = NULL;
- menuItem->clientCommandID = 0;
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-#if (defined(MWM_QATS_PROTOCOL))
- /*
- * Is this a simple menu item label or is it a
- * client command specification.
- */
- if (IsClientCommand((String) string))
- {
- if (!ParseClientCommand(&lineP, menuSpec, menuItem, string,
- &use_separators))
- {
- XtFree ((char *)menuItem);
- continue;
- }
-
- for (ix = 0; ix < WMFUNCTIONTABLESIZE - 1; ++ix)
- if (functionTable[ix].wmFunction == F_InvokeCommand)
- break;
-
- if (ix == WMFUNCTIONTABLESIZE - 1)
- {
- ix = F_NOP_INDEX;
- menuItem->wmFunction = F_Nop;
- }
- else menuItem->wmFunction = F_InvokeCommand;
- }
- else /* It must be a menu item label */
-#endif /* defined(MWM_QATS_PROTOCOL) */
{
/*
* Parse the menu item label.
* but we do want to search for a menu item name that occupies
* the same place as the function does for normal menu items.
*/
-#if (defined(MWM_QATS_PROTOCOL))
- if (menuItem->wmFunction != NULL)
- ParseMenuItemName(&lineP, menuItem);
- else
-#endif /* defined(MWM_QATS_PROTOCOL) */
- ix = ParseWmFunction (&lineP, CRS_MENU, &menuItem->wmFunction);
+ ix = ParseWmFunction (&lineP, CRS_MENU, &menuItem->wmFunction);
/*
* Determine context sensitivity and applicability mask.
continue; /* skip this menu item */
}
-#if (defined(MWM_QATS_PROTOCOL))
- /*
- * If we're working on the f.cci function, this will fix-up
- * the menuItem entries so that it appears that we read-in
- * an old-style client-command entry. Eventually, the cci
- * handling should be changed to make use of the wmFuncArgs.
- * Note that if DEFAULT_NAME was specified as the label, it
- * is first set to NULL.
- * FixMenuItem needs menuSpec since this is when the EXCLUDE
- * items are stored.
- */
- if (ix == F_CCI_INDEX)
- {
- CCIEntryModifier mod = ((CCIFuncArg *)menuItem->wmFuncArgs)->mod;
-
- /* first fix the label if needed. */
- if (!strcmp(menuItem->label, CCI_USE_DEFAULT_NAME_TAG))
- {
- XtFree(menuItem->label);
- menuItem->label = NULL;
- }
-
- FixMenuItem(menuSpec, menuItem);
-
- if (mod == DELIMIT || mod == DELIMIT_CASCADE || mod == DELIMIT_INLINE)
- use_separators = True;
- }
-
- /*
- * If this menu item is supposed to be wrapped in separators,
- * then create a separator template before the menu item
- */
- if (use_separators)
- {
- MenuItem *separator = MakeSeparatorTemplate(TOP_SEPARATOR);
- if (lastMenuItem != NULL) lastMenuItem->nextMenuItem = separator;
- else firstMenuItem = separator;
- lastMenuItem = separator;
- }
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
/*
* Add this item to the menu specification.
*/
firstMenuItem = menuItem;
}
lastMenuItem = menuItem;
-
-#if (defined(MWM_QATS_PROTOCOL))
- /* If this menu item is supposed to be wrapped in separators
- * then create a separator template after the menu item
- */
- if (use_separators)
- {
- MenuItem *separator = MakeSeparatorTemplate(BOTTOM_SEPARATOR);
- if (lastMenuItem != NULL) lastMenuItem->nextMenuItem = separator;
- else firstMenuItem = separator;
- lastMenuItem = separator;
- }
-
- use_separators = FALSE;
-#endif /* defined(MWM_QATS_PROTOCOL) */
}
return (firstMenuItem);
} /* END OF FUNCTION ParseMenuItems */
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * StoreExclusion (menuSpec, string)
- *
- *
- * Description:
- * -----------
- * Store the exclusion string in the menuspec. The list of exclusion
- * strings are used to determine whether an insertion should be disallowed.
- *
- *
- * Inputs:
- * ------
- * menuSpec = the menu specification structure
- * string = exclusion client command string
- *
- *
- * Outputs:
- * -------
- * Return = nothing
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void StoreExclusion (MenuSpec *menuSpec, String string)
-{
- MenuExclusion *exclusion;
-
- exclusion = (MenuExclusion *)XtMalloc(sizeof(MenuExclusion));
- exclusion->command_string = XtNewString(string);
-
- /* We don't care what order the exclusions are in so stick it
- at the head of the list because it is easier. */
- exclusion->nextExclusion = menuSpec->exclusions;
- menuSpec->exclusions = exclusion;
-}
-
-\f
-/*************************************<->*************************************
- *
- * IsClientCommand (string)
- *
- *
- * Description:
- * -----------
- * Determine whether the string is a client command by the prefix
- * characters.
- *
- *
- * Inputs:
- * ------
- * string = possible client command string
- *
- *
- * Outputs:
- * -------
- * Return = (Boolean) TRUE iff the string is a client command.
- * Otherwise, FALSE is returned.
- *
- *
- * Comments:
- * --------
- * This function simply checks what the first two or three characters of
- * the string are. If they match the beginning of a client command
- * specification, then TRUE is returned. This function does no go on to
- * parse the rest of the specification. The legal client command beginning
- * characters are:
- *
- * characters: meaning:
- * -----------------------------------------------
- * < simple client command beginning
- * ->< forced cascade menu
- * =< client command with separators
- * ~< exclusion operator
- *
- * Assumes:
- * --------
- * There is no leading whitespace on the string
- *
- *************************************<->***********************************/
-
-Boolean IsClientCommand (String string)
-{
- if ((mblen ((char *)string, MB_CUR_MAX) == 1 && *string == '<') ||
- (strncmp(string, "-><", 3) == 0) ||
- (strncmp(string, "=<", 2) == 0) ||
- (strncmp(string, "=><", 3) == 0) ||
- (strncmp(string, "~<", 2) == 0))
- return(TRUE);
-
- return(FALSE);
-}
-
-\f
-/*************************************<->*************************************
- *
- * ParseClientCommand (linePP, menuSpec, menuitem, string, use_separators)
- *
- *
- * Description:
- * -----------
- * Parse the string and whatever is left of the line to verify whether
- * correct syntax was used for a client command. Store the client command
- * string in the menuitem, unless it is an exclusion. If it is an
- * exclusion, then store the exclusion string in the menuSpec and return
- * FALSE to indicate that the menuitem is no longer needed.
- *
- *
- * Inputs:
- * ------
- * linePP = pointer to current line buffer pointer.
- * menuItem = pointer to MenuItem structure
- * string = first token of client command
- *
- *
- * Outputs:
- * -------
- * Return = (Boolean) TRUE iff the line is a valid client command
- * that can used to match insertions.
- * Otherwise, FALSE is returned meaning that the client
- * command had incorrect syntax or it was an exclusion, in
- * which case any useful information was stored in the
- * menuSpec.
- *
- *
- * Comments:
- * --------
- * This function parses the entire line to determine if correct
- * syntax was used for the client command. We assume at this point
- * that the line is a client command. We are just syntax checking.
- * If the syntax is correct, the client command is stored in the
- * menuitem structure, in the "label" field.
- *
- * Valid syntax for a client command (single quoted characters are
- * literals):
- *
- * modifier = { '->' | '=' | '~' }
- * reference = '<' { name | '*' } '>'
- * command = [ modifier ] reference [ { modifier | '.' } reference ]*
- * name = alpha-numeric string, white space allowed
- *
- * Assumes:
- * --------
- * There is no leading whitespace on the string argument
- *
- *************************************<->***********************************/
-
-enum { PRS_NO_STATE, PRS_BEGIN, PRS_MODIFIER, PRS_REFERENCE,
- PRS_SEPARATOR, PRS_END, PRS_ERROR, PRS_MAX_STATES };
-
-/* This table lists for each parse state, the legal states that can
- be moved to. Each list must end with a PRS_NO_STATE value to
- terminate the list. */
-static int cmd_parse_table[PRS_END][PRS_END] =
-{
- /* PRS_NO_STATE */ { PRS_NO_STATE },
- /* PRS_BEGIN */ { PRS_MODIFIER, PRS_REFERENCE, PRS_NO_STATE },
- /* PRS_MODIFIER */ { PRS_REFERENCE, PRS_NO_STATE },
- /* PRS_REFERENCE */ { PRS_SEPARATOR, PRS_END, PRS_NO_STATE },
- /* PRS_SEPARATOR */ { PRS_REFERENCE, PRS_NO_STATE },
-};
-
-static Boolean ParseClientCommand (unsigned char **linePP, MenuSpec *menuSpec,
- MenuItem *menuItem, unsigned char *string,
- Boolean *use_separators)
-{
- int token, linelen, i;
- int state = PRS_BEGIN;
- String stream, unchanged_stream, exclusion_text;
- Boolean return_val = FALSE;
- Boolean exclusion = FALSE; /* this will be set to TRUE if the client
- command was parsed to be an exclusion
- command. */
-
- /* Construct one input stream out of the string and the linePP that
- we were given. */
- linelen = strlen((char *)string) + strlen((char *)*linePP) + 1;
- if ((unchanged_stream = stream = (String)
- XtMalloc((unsigned int)(sizeof(unsigned char) * linelen))) == NULL)
- {
- PWarning (((char *)GETMESSAGE(60, 42,
- "Insufficient memory for menu item label")));
- return (FALSE);
- }
- strcpy(stream, (char *) string);
- strcat(stream, " ");
- strcat(stream, (char *) *linePP);
-
- for (;;)
- {
- token = PRS_NO_STATE;
- while (token == PRS_NO_STATE)
- {
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
-
- switch (*stream)
- {
- case '\0':
- case '\n':
- /* We've reached the end of the stream. Return the
- PRS_END token. */
- token = PRS_END;
- break;
- case '-':
- /* This should be a cascade-force modifier */
- ++stream;
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
- if (*stream == '>')
- {
- ++stream; token = PRS_MODIFIER;
- }
- else token = PRS_ERROR;
- break;
- case '=':
- /* This is either a separators modifier or
- a combination separators and cascade-force
- modifier */
- ++stream;
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
- if (*stream == '>') ++stream;
- token = PRS_MODIFIER;
- *use_separators = TRUE;
- break;
- case '~':
- /* This is a exclude-command modifier */
- ++stream; token = PRS_MODIFIER;
- exclusion = TRUE;
- /* Setup a pointer to the text following the ~ so
- we can do matching later for exclusions. */
- exclusion_text = stream;
- break;
- case '<':
- /* Skip the open bracket */
- ++stream;
-
- /* This should be the beginning of a reference. First
- skip any leading whitespace. */
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
- while (mblen ((char *)stream, MB_CUR_MAX) == 1 &&
- (*stream == ' ' || *stream == '\t'))
- ++stream;
-
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
- /* Now check for a reference name wild card or a
- full reference name */
- if (*stream == '*')
- ++stream;
- else
- {
- while (mblen ((char *)stream, MB_CUR_MAX) == 1 &&
- (isalnum(*stream) || *stream == ' ' ||
- *stream == '\t' || *stream == '_' ))
- ++stream;
- }
-
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
-
- /* Now skip past any trailing white space */
- while (mblen ((char *)stream, MB_CUR_MAX) == 1 &&
- (*stream == ' ' || *stream == '\t'))
- ++stream;
-
- if (mblen ((char *)stream, MB_CUR_MAX) > 1) {
- token = PRS_ERROR;
- continue;
- }
- /* At this point, we should be looking at the close
- of the reference */
- if (*stream == '>')
- {
- token = PRS_REFERENCE;
- ++stream;
- }
- else token = PRS_ERROR;
- break;
- case '.':
- /* This is a reference separator */
- ++stream; token = PRS_SEPARATOR;
- break;
- case ' ':
- case '\t':
- /* The only place white space is allowed as at the
- beginning of the line, after all the client command
- text and within the delimiters of a REFERENCE. We
- are guaranteed not to have whitespace at the
- beginning of the line by the time this function is
- called. Also, the REFERENCE parsing above handles
- all white space internal to the client command. Therefore,
- since we are seeing white space, we must be at the
- end of the client command. */
- token = PRS_END;
- break;
- default:
- token = PRS_ERROR;
-
- } /* end switch (*stream) */
- } /* end while (token == PRS_NO_STATE) */
-
- /* If we got an error then just return an error */
- if (token == PRS_ERROR)
- {
- return_val = FALSE; break;
- }
-
- /* Check whether the token we got is a valid transition */
- for (i = 0; cmd_parse_table[state][i] != PRS_NO_STATE; ++i)
- {
- if (token == cmd_parse_table[state][i])
- {
- /* It is a valid transition, so break out of the loop */
- break;
- }
- }
-
- /* If i is not indexing the NO_STATE value in the parse_table,
- then the parse succeeded. Check if the new state is PRS_END.
- If so then we are done. If the state isn't the same as the
- current token, then we hit a parse error. */
- if (cmd_parse_table[state][i] != PRS_NO_STATE)
- {
- if (token == PRS_END)
- {
- return_val = TRUE;
- break;
- }
- }
- else
- {
- /* parse error */
- return_val = FALSE;
- break;
- }
-
- /* The transition was valid so make the transition by
- setting the state to be the current token. */
- state = token;
-
- } /* end for (;;) */
-
- /* If the return_val is TRUE, then the parse succeeded and we
- want to save the string we parsed into the label field of
- the menu item. */
- if (return_val == TRUE)
- {
- /* NULL terminate the string */
- *stream = '\0';
-
- /* Check whether this client command was an exclusion. If not,
- then store the client command string in the menu item. */
- if (exclusion == TRUE)
- {
- /* Since the command was an exclusion, store the command
- string in the menuSpec and change the return value to
- FALSE. */
- StoreExclusion(menuSpec, exclusion_text);
- return_val = FALSE;
- }
- else
- {
- menuItem->label = XtNewString(unchanged_stream);
- menuItem->labelType = XmSTRING;
- }
- }
-
- /* Free the string we allocated and return. */
- XtFree((char *)unchanged_stream);
-
- return(return_val);
-}
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-\f
/*************************************<->*************************************
*
* ParseWmLabel (pSD, menuItem, string)
if ((*lineP != '\0') && /* something follows */
(*lineP != '!') && /* skip if we have the ! WmFunction */
-#if (defined(MWM_QATS_PROTOCOL))
- /* skip label name for client command */
- ((*lineP != '"') || (menuItem->wmFunction != F_InvokeCommand)) &&
-#endif /* defined(MWM_QATS_PROTOCOL) */
(*lineP != 'f') &&
(*(lineP+1) != '.')) /* skip if we have f.xxx WmFunction */
{
} /* END OF FUNCTION ParseWmAccelerator */
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * ParseMenuItemName (linePP, menuItem)
- *
- *
- * Description:
- * -----------
- * Parse a user defined client command menu item
- *
- *
- * Inputs:
- * ------
- * linePP = pointer to current line buffer pointer.
- * menuItem = pointer to MenuItem structure
- *
- *
- * Outputs:
- * -------
- * menuItem->label will have menu item name appended to it
- *
- * Comments:
- * --------
- * This function attempts to find a menu item label string at the end
- * of the client command specification line. A menu item label string
- * must be delimited by double quotes. If found, the label string is
- * appended to the menuItem->label field, after being reallocated to
- * accommodate the new space requirement.
- *
- *************************************<->***********************************/
-
-static void ParseMenuItemName (unsigned char **linePP, MenuItem *menuItem)
-{
- unsigned char *lineP, *endquote;
- int chlen;
-
- /* Skip past any whitespace */
- ScanWhitespace (linePP);
- lineP = *linePP;
-
- /* Look for a double quote */
- if (mblen ((char *)lineP, MB_CUR_MAX) == 1 && *lineP == '"')
- {
- /* Move past the first quote. */
- ++lineP;
-
- endquote = lineP;
-
- /* Search for closing quote */
- while (*endquote != '\0' &&
- (chlen = mblen ((char *)endquote, MB_CUR_MAX)) > 0 &&
- (chlen > 1 || *endquote != '"'))
- {
- /* If we ran off the end of the line, then just abort. Bad
- syntax. */
- if ((chlen == 1 && *endquote == '\n') || *endquote == '\0') return;
- endquote += chlen;
- }
- if (chlen < 0) return; /* invalid character */
-
- /* Well, we have a valid menu item name. Store it in the
- client command name field. Don't include the double quotes. */
- menuItem->clientCommandName =
- XtMalloc(sizeof(char) * (endquote - lineP) + 1);
- strncpy(menuItem->clientCommandName, (char *) lineP,
- endquote - lineP);
- menuItem->clientCommandName[strlen(menuItem->clientCommandName)+1] = '\0';
- }
- else
- {
- /* If there was no double quote, then just advance to the end
- of the line. */
- while (*lineP != '\0' &&
- ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) > 1 ||
- *lineP != '\n'))
- lineP += chlen > 0 ? chlen : 1;
- *linePP = lineP;
- }
-}
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-\f
/*************************************<->*************************************
*
* int
} /* END OF FUNCTION ParseWmFuncNbrArg */
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * ParseWmFuncCCIArgs (linePP, wmFunction, pArgs)
- *
- *
- * Description:
- * -----------
- * Parses a Client-Command entry's arguments.
- *
- *
- * Inputs:
- * ------
- * linePP = pointer to current line buffer pointer.
- * wmFunction = function for which the argument string is intended.
- * pArgs = pointer to argument string destination.
- *
- *
- * Outputs:
- * -------
- * linePP = pointer to revised line buffer pointer.
- * pArgs = pointer to parsed argument string.
- * Return = FALSE iff insufficient memory
- *
- *
- * Comments:
- * --------
- * None.
- *
- *************************************<->***********************************/
-
-static Boolean ParseWmFuncCCIArgs (unsigned char **linePP,
- WmFunction wmFunction, String *pArgs)
-{
- /*
- * Format:
- * cci_func_args:
- * cci_entry
- * modifier cci_entry_list
- *
- * cci_entry_list:
- * cci_entry
- * cci_entry . cci_entry
- *
- * cci_entry:
- * '<' cci_label '>'
- *
- * cci_label:
- * any combination of alpha and '_'
- */
-
- CCIEntryModifier mod;
- CCIFuncArg *cciArg;
- unsigned char *string;
-
-
- cciArg = XtNew(CCIFuncArg);
-
- if ((string = GetString(linePP)) == NULL)
- {
- /* Error - no data for f.cci command. cci_entry_list is required. */
- fprintf(stderr, "Incorrect format for f.cci command.\n");
- return (FALSE);
- }
- else
- {
- /* check if no modifier was specified. */
- if (string[0] == '<')
- {
- cciArg->mod = NONE;
- cciArg->cciEntry = XtNewString((char*)string);
- }
- else
- {
- if (! GetCCIModifier((String)string, &mod))
- {
- cciArg->mod = NONE;
- cciArg->cciEntry = XtNewString("");
- }
- else
- {
- cciArg->mod = mod;
-
- if ((string = GetString(linePP)) == NULL)
- {
- /* Found a modifier, but there's no cci_entry_list. */
- fprintf(stderr, "Incorrect format for f.cci command.\n");
- return(FALSE);
- }
- else
- {
- cciArg->cciEntry = XtNewString((char*)string);
- }
- }
- }
-
- *pArgs = (String)cciArg;
- }
-
- return(TRUE);
-} /* END OF FUNCTION ParseWmFuncCCIArgs */
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-\f
/*************************************<->*************************************
*
* ParseButtonStr ()
} /* END OF FUNCTION LookupModifier */
-\f
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * GetCCIModifier (modString, mod)
- *
- *
- * Description:
- * -----------
- * Return the cci modifier corresponding to the specified string
- *
- *
- * Inputs:
- * ------
- * modString = cci modifier string; may be null
- *
- *
- * Outputs:
- * -------
- * mod = cci modifier.
- * Return = (Boolean) true iff valid modifier string
- *
- *
- * Comments:
- * --------
- * None.
- *
- *************************************<->***********************************/
-
-static Boolean GetCCIModifier (String modString, CCIEntryModifier *mod)
-{
- CCIEntryModifier i;
-
-
- if (modString != NULL)
- {
- ToLower (modString);
- for (i=NONE; i<=EXCLUDE; i++)
- {
- if (!strcmp (CCIEntryModifierNames[i], modString))
- {
- *mod = i;
- return (TRUE);
- }
- }
- }
-
- return (FALSE);
-
-} /* END OF FUNCTION GetCCIModifier */
-
-\f
-/*************************************<->*************************************
- *
- * FixMenuItem (menuSpec, menuItem)
- *
- *
- * Description:
- * -----------
- * Fix-up the menuItem so that it appears an old-style cci command was
- * read from the .mwmrc file
- *
- *
- * Inputs:
- * ------
- * menuItem = the menu item structure
- * menuSpec = the menu specification structure
- *
- *
- * Outputs:
- * -------
- * menuItem = the fixed-up menuitem
- * menuSpec = the fixed-up menu specification structure if EXCLUDE found
- * Return = nothing
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
-
-static void FixMenuItem (MenuSpec *menuSpec, MenuItem *menuItem)
-{
- String tmp;
- CCIFuncArg *cciArg;
-
-
- if (menuItem == NULL)
- return;
-
- cciArg = (CCIFuncArg *)menuItem->wmFuncArgs;
-
- menuItem->clientCommandName = menuItem->label;
- menuItem->label = cciArg->cciEntry;
-
- /*
- * Fix-up the label to handle the modifier.
- */
-
- switch (cciArg->mod)
- {
- case NONE:
- break;
-
- case INLINE:
- break;
-
- case CASCADE:
- /* -> */
- tmp = (String) XtMalloc(strlen(menuItem->label) + 3);
- sprintf(tmp, "->%s", menuItem->label);
- XtFree(menuItem->label);
- menuItem->label = tmp;
- break;
-
- case DELIMIT:
- /* = */
- tmp = (String) XtMalloc(strlen(menuItem->label) + 2);
- sprintf(tmp, "=%s", menuItem->label);
- XtFree(menuItem->label);
- menuItem->label = tmp;
- break;
-
- case DELIMIT_INLINE:
- break;
-
- case DELIMIT_CASCADE:
- /* => */
- tmp = (String) XtMalloc(strlen(menuItem->label) + 3);
- sprintf(tmp, "=>%s", menuItem->label);
- XtFree(menuItem->label);
- menuItem->label = tmp;
- break;
-
- case EXCLUDE:
- /* ~ */
- StoreExclusion(menuSpec, menuItem->label);
-
- tmp = (String) XtMalloc(strlen(menuItem->label) + 2);
- sprintf(tmp, "~%s", menuItem->label);
- XtFree(menuItem->label);
- menuItem->label = tmp;
- break;
- }
-}
-#endif /* defined(MWM_QATS_PROTOCOL) */
-
-\f
/*************************************<->*************************************
*
* ParseEventType(linePP, table, eventType, ix)
}
/**************************** eof ***************************/
-#if (defined(MWM_QATS_PROTOCOL))
-/*************************************<->*************************************
- *
- * SetGreyedContextAndMgtMask (menuItem, wmFunction)
- *
- *
- * Description:
- * -----------
- * This function sets up the greyed context and management mask
- * for a menu item based on the menu function passed in.
- *
- * Inputs:
- * ------
- * menuItem = the menu item to be set up
- * wmFunction = the menu function to find in the function table
- * to determine how to set up the relevant fields
- *
- * Outputs:
- * -------
- * The menuItem will have its greyed context and management mask fields
- * set appropriately. If the given function cannot be found, the fields
- * will be set to the appropriate values as if the function were F_Nop.
- * Return = True if the function could be found. False otherwise.
- *
- *************************************<->***********************************/
-
-Boolean SetGreyedContextAndMgtMask (MenuItem *menuItem,
- WmFunction wmFunction)
-{
- int ix;
-
- for (ix = 0; ix < WMFUNCTIONTABLESIZE - 1; ++ix)
- {
- if (functionTable[ix].wmFunction == wmFunction)
- {
- /* Success! The function was found. Set up the
- values and get the heck out of here. */
- menuItem->greyedContext = functionTable[ix].greyedContext;
- menuItem->mgtMask = functionTable[ix].mgtMask;
- return(True);
- }
- }
-
- /* We couldn't find the given command in the function table.
- Set up the values as if the F_Nop function were found
- and return False. */
- menuItem->greyedContext = functionTable[F_NOP_INDEX].greyedContext;
- menuItem->mgtMask = functionTable[F_NOP_INDEX].mgtMask;
- return(False);
-}
-
-
-\f
-/*************************************<->*************************************
- *
- * MakeSeparatorTemplate ()
- *
- *
- * Description:
- * -----------
- *
- * Inputs:
- * ------
- *
- * Outputs:
- * -------
- *
- *************************************<->***********************************/
-static
-MenuItem *MakeSeparatorTemplate (int position)
-{
- MenuItem *item;
-
- item = (MenuItem *)XtMalloc(sizeof(MenuItem));
-
- /* We use the labelType to determine where this separator is positioned
- relative to the client command(s) it is surrounding, i.e. TOP or
- BOTTOM */
- item->labelType = position;
- /* Make it look like a client command: */
- item->label = XtNewString("<label-template>");
- item->labelBitmapIndex = -1;
- item->mnemonic = (KeySym) 0;
- item->accelState = 0;
- item->accelKeyCode = (KeyCode) NULL;
- item->accelText = (String) NULL;
- item->wmFunction = (WmFunction) F_Separator;
- item->wmFuncArgs = (String) NULL;
- item->greyedContext = 0;
- item->mgtMask = 0;
- item->clientCommandName = (String) NULL;
- item->nextMenuItem = (MenuItem *) NULL;
-
- return(item);
-}
-#endif /* defined(MWM_QATS_PROTOCOL) */