From 23191655373ae5bdca4d1a89831d82e215443146 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 15 2020 17:35:16 +0000 Subject: Apply patch motif-2.3.4-mwmrc_dir.patch patch_name: motif-2.3.4-mwmrc_dir.patch present_in_specfile: true --- diff --git a/clients/mwm/WmResParse.c b/clients/mwm/WmResParse.c index f64207c..465f5b4 100644 --- a/clients/mwm/WmResParse.c +++ b/clients/mwm/WmResParse.c @@ -2392,7 +2392,7 @@ FILE *FopenConfigFile (void) #endif /* PANELIST */ #ifndef MWMRCDIR -#define MWMRCDIR "/usr/lib/X11" +#define MWMRCDIR "/etc/X11/mwm" #endif if (LANG != NULL) { diff --git a/clients/mwm/WmResParse.c.mwmrc_dir b/clients/mwm/WmResParse.c.mwmrc_dir new file mode 100644 index 0000000..f64207c --- /dev/null +++ b/clients/mwm/WmResParse.c.mwmrc_dir @@ -0,0 +1,8395 @@ +/* + * Motif + * + * Copyright (c) 1987-2012, The Open Group. All rights reserved. + * + * These libraries and programs are free software; you can + * redistribute them and/or modify them under the terms of the GNU + * Lesser General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * These libraries and programs are distributed in the hope that + * they will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with these librararies and programs; if not, write + * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + * Floor, Boston, MA 02110-1301 USA +*/ +/* + * Motif Release 1.2.4 +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + + +#ifdef REV_INFO +#ifndef lint +static char rcsid[] = "$XConsortium: WmResParse.c /main/9 1996/11/01 10:17:34 drk $" +#endif +#endif +/* + * (c) Copyright 1987, 1988, 1989, 1990, 1993, 1994 Hewlett-Packard Company + * (c) Copyright 1993, 1994 International Business Machines Corp. + * (c) Copyright 1993, 1994 Sun Microsystems, Inc. + * (c) Copyright 1993, 1994 Novell, Inc. + */ +/* + * (c) Copyright 1987, 1988 DIGITAL EQUIPMENT CORPORATION */ +/* + * (c) Copyright 1988 MASSACHUSETTS INSTITUTE OF TECHNOLOGY */ + +/* + * Included Files: + */ + +#include "WmGlobal.h" +#include "WmResNames.h" +#ifdef WSM +#include
+#include
+#include +#endif /* WSM */ +#ifdef PANELIST +#include "WmParse.h" +#include "WmParseP.h" +#include "WmPanelP.h" +#endif /* PANELIST */ +#include "WmResource.h" + +#include + +#include +#include +#include +#include + +#include + +#ifndef NO_MULTIBYTE +#include +#endif + +#ifdef MOTIF_ONE_DOT_ONE +#include +#include +#else +#include /* for XmeGetHomeDirName */ +#endif +#ifdef WSM +#include +#endif /* WSM */ + +#define FIX_1127 + +/* maximum string lengths */ + +#define MAX_KEYSYM_STRLEN 100 +#define MAX_EVENTTYPE_STRLEN 20 +#define MAX_MODIFIER_STRLEN 20 +#define MAX_CONTEXT_STRLEN 20 +#define MAX_GROUP_STRLEN 20 + +#ifdef min +#undef min +#endif +#define min(a,b) ((a)>(b) ? (b) : (a)) + +#define MAXLINE (MAXWMPATH+1) + +#define MBBSIZ 4096 + +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) +# define PARSE_MENU_ITEMS(pSD, mSpec) ParseMenuItems(pSD, mSpec) +#else +# define PARSE_MENU_ITEMS(pSD, mSpec) ParseMenuItems(pSD) +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + +/* + * include extern functions + */ +#include "WmResParse.h" +#ifdef WSM +#include "WmWrkspace.h" +#endif /* WSM */ +#include "WmError.h" +#include "WmFunction.h" +#include "WmImage.h" +#include "WmXSMP.h" + +#ifdef MOTIF_ONE_DOT_ONE +extern char *getenv (); +#endif +#ifdef PANELIST +# include +# ifdef X_NOT_STDC_ENV +extern int errno; +# endif +# define HOME_DT_WMRC "/.dt/dtwmrc" +# define LANG_DT_WMRC "/dtwmrc" +# define SYS_DT_WMRC CDE_CONFIGURATION_TOP "/sys.dtwmrc" +#endif /* PANELIST */ + +/* + * Global Variables And Tables: + */ +static char cfileName[MAXWMPATH+1]; +#ifdef WSM +#ifndef NO_MESSAGE_CATALOG +char * pWarningStringFile; +char * pWarningStringLine; +#else +char pWarningStringFile[] = "%s: %s on line %d of configuration file %s\n"; +char pWarningStringLine[] = "%s: %s on line %d of specification string\n"; +#endif +#define cfileP (wmGD.pWmPB->pFile) +#define parseP (wmGD.pWmPB->pchNext) +#define line (wmGD.pWmPB->pchLine) +#define linec (wmGD.pWmPB->lineNumber) +#else /* WSM */ +static FILE *cfileP = NULL; /* fopen'ed configuration file or NULL */ +static unsigned char line[MAXLINE+1]; /* line buffer */ +static int linec = 0; /* line counter for parser */ +static unsigned char *parseP = NULL; /* pointer to parse string */ +#endif /* WSM */ + + +typedef struct { + char *name; + unsigned int mask; +} MaskTableEntry; + +static MaskTableEntry modifierStrings[] = { + + {"none", None}, + {"ctrl", ControlMask}, + {"shift", ShiftMask}, + {"alt", Mod1Mask}, + {"meta", Mod1Mask}, + {"lock", LockMask}, + {"mod1", Mod1Mask}, + {"mod2", Mod2Mask}, + {"mod3", Mod3Mask}, + {"mod4", Mod4Mask}, + {"mod5", Mod5Mask}, + {NULL, (unsigned int)NULL}, +}; + +#define ALT_INDEX 3 +#define META_INDEX 4 + +typedef struct { + char *event; + unsigned int eventType; + Boolean (*parseProc)(); + unsigned int closure; + Boolean fClick; +} EventTableEntry; + +#if ((!defined(WSM)) || 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + +#ifdef MOTIF_ONE_DOT_ONE +void GetHomeDirName(String fileName); +#endif +#ifdef WSM +static String GetNetworkFileName (char *pchFile); +#endif /* WSM */ +#if ((!defined(WSM)) || 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(WSM) || 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(WSM)) || defined(MWM_QATS_PROTOCOL)) + , MenuSpec *menuSpec +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + ); +static Boolean ParseWmLabel (WmScreenData *pSD, MenuItem *menuItem, + unsigned char *string); +static void ParseWmMnemonic (unsigned char **linePP, MenuItem *menuItem); +static Boolean ParseWmAccelerator (unsigned char **linePP, MenuItem *menuItem); +int ParseWmFunction (unsigned char **linePP, unsigned int res_spec, + WmFunction *pWmFunction); +#ifndef PANELIST +static Boolean ParseWmFuncMaybeStrArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs); +#endif /* PANELIST */ +static Boolean ParseWmFuncNoArg (unsigned char **linePP, WmFunction wmFunction, + String *pArgs); +#ifndef PANELIST +static Boolean ParseWmFuncStrArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs); +#endif /* PANELIST */ +void FreeMenuItem (MenuItem *menuItem); +static Boolean ParseWmFuncGrpArg (unsigned char **linePP, + WmFunction wmFunction, GroupArg *pGroup); +static Boolean ParseWmFuncNbrArg (unsigned char **linePP, + WmFunction wmFunction, + unsigned long *pNumber); +void ParseButtonStr (WmScreenData *pSD, unsigned char *buttonStr); +static void ParseButtonSet (WmScreenData *pSD, unsigned char *lineP); +static Boolean ParseContext (unsigned char **linePP, Context *context, + Context *subContext); +void +ParseKeyStr (WmScreenData *pSD, unsigned char *keyStr); +static void ParseKeySet (WmScreenData *pSD, unsigned char *lineP); +Boolean ParseBtnEvent (unsigned char **linePP, + unsigned int *eventType, + unsigned int *button, + unsigned int *state, + Boolean *fClick); +Boolean ParseKeyEvent (unsigned char **linePP, unsigned int *eventType, + KeyCode *keyCode, unsigned int *state); +static Boolean ParseEvent (unsigned char **linePP, EventTableEntry *table, + unsigned int *eventType, unsigned int *detail, + unsigned int *state, Boolean *fClick); +static Boolean ParseModifiers(unsigned char **linePP, unsigned int *state); +static Boolean LookupModifier (unsigned char *name, unsigned int *valueP); +static Boolean ParseEventType (unsigned char **linePP, EventTableEntry *table, + unsigned int *eventType, Cardinal *ix); +static Boolean ParseImmed (unsigned char **linePP, unsigned int closure, + unsigned int *detail); +static Boolean ParseKeySym (unsigned char **linePP, unsigned int closure, + unsigned int *detail); +static unsigned int StrToNum(unsigned char *str); +static unsigned int StrToHex(unsigned char *str); +static unsigned int StrToOct(unsigned char *str); +void ScanAlphanumeric (unsigned char **linePP); +void ScanWhitespace(unsigned char **linePP); +void ToLower (unsigned char *string); +void +PWarning (char *message); +static void ProcessAccelText (unsigned char *startP, unsigned char *endP, + unsigned char *destP); +void ProcessCommandLine (int argc, char *argv[]); +static void ParseScreensArgument (int argc, char *argv[], int *pArgnum, + unsigned char *lineP); +void ProcessMotifBindings (void); +#ifdef PANELIST +static void ParseIncludeSet (WmScreenData *pSD, unsigned char *lineP); +static void ConfigStackInit (char *pchFileName); +static FILE *ConfigStackPush (unsigned char *pchFileName); +static void ConfigStackPop (void); +Boolean ParseWmFuncActionArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs); +static void PreprocessConfigFile (void); +#endif /* PANELIST */ + +static EventTableEntry buttonEvents[] = { + + {"btn1down", ButtonPress, ParseImmed, SELECT_BUTTON, FALSE}, + {"btn1up", ButtonRelease, ParseImmed, SELECT_BUTTON, FALSE}, + {"btn1click", ButtonRelease, ParseImmed, SELECT_BUTTON, TRUE}, + {"btn1click2", ButtonPress, ParseImmed, SELECT_BUTTON, TRUE}, + {"btn2down", ButtonPress, ParseImmed, DMANIP_BUTTON, FALSE}, + {"btn2up", ButtonRelease, ParseImmed, DMANIP_BUTTON, FALSE}, + {"btn2click", ButtonRelease, ParseImmed, DMANIP_BUTTON, TRUE}, + {"btn2click2", ButtonPress, ParseImmed, DMANIP_BUTTON, TRUE}, + {"btn3down", ButtonPress, ParseImmed, BMENU_BUTTON, FALSE}, + {"btn3up", ButtonRelease, ParseImmed, BMENU_BUTTON, FALSE}, + {"btn3click", ButtonRelease, ParseImmed, BMENU_BUTTON, TRUE}, + {"btn3click2", ButtonPress, ParseImmed, BMENU_BUTTON, TRUE}, + {"btn4down", ButtonPress, ParseImmed, Button4, FALSE}, + {"btn4up", ButtonRelease, ParseImmed, Button4, FALSE}, + {"btn4click", ButtonRelease, ParseImmed, Button4, TRUE}, + {"btn4click2", ButtonPress, ParseImmed, Button4, TRUE}, + {"btn5down", ButtonPress, ParseImmed, Button5, FALSE}, + {"btn5up", ButtonRelease, ParseImmed, Button5, FALSE}, + {"btn5click", ButtonRelease, ParseImmed, Button5, TRUE}, + {"btn5click2", ButtonPress, ParseImmed, Button5, TRUE}, + { NULL, (unsigned int)NULL, (Boolean(*)())NULL, (unsigned int)NULL, (Boolean)NULL} +}; + + +static EventTableEntry keyEvents[] = { + + {"key", KeyPress, ParseKeySym, 0, FALSE}, + { NULL, (unsigned int)NULL, (Boolean(*)())NULL, (unsigned int)NULL, (Boolean)NULL} +}; + +#ifdef PANELIST +typedef struct _ConfigFileStackEntry { + char *fileName; + char *tempName; + char *cppName; + char *wmgdConfigFile; + long offset; + DtWmpParseBuf *pWmPB; + struct _ConfigFileStackEntry *pIncluder; + +} ConfigFileStackEntry; + +static ConfigFileStackEntry *pConfigStack = NULL; +static ConfigFileStackEntry *pConfigStackTop = NULL; + +#endif /* PANELIST */ + +unsigned int buttonModifierMasks[] = { + 0, + SELECT_BUTTON_MASK, + DMANIP_BUTTON_MASK, + BMENU_BUTTON_MASK, + Button4Mask, + Button5Mask +}; + +/* + * FUNCTION PARSER TABLE (function names must be in alphabetic order) + */ + +typedef struct { + char * funcName; + Context greyedContext; + unsigned int resource; + long mgtMask; + WmFunction wmFunction; + Boolean (*parseProc)(); +} FunctionTableEntry; + + +/* + * NOTE: New functions MUST be added in ALPHABETICAL order. A binary search + * is used to find the correct function name. + */ + +FunctionTableEntry functionTable[] = { +#ifdef WSM +#ifdef PANELIST + {"f.action", 0, + CRS_ANY, + 0, + F_Action, + ParseWmFuncActionArg}, +#else /* PANELIST */ + {"f.action", 0, + CRS_ANY, + 0, + F_Action, + ParseWmFuncStrArg}, +#endif /* PANELIST */ +#endif /* WSM */ + {"f.beep", 0, + CRS_ANY, + 0, + F_Beep, + ParseWmFuncNoArg}, +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + {"f.cci", 0, + CRS_ANY, + 0, + F_Nop, + ParseWmFuncCCIArgs}, +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + {"f.circle_down", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Circle_Down, + ParseWmFuncGrpArg}, + {"f.circle_up", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Circle_Up, + ParseWmFuncGrpArg}, +#ifdef WSM + {"f.create_workspace", 0, + CRS_ANY, + 0, + F_CreateWorkspace, + ParseWmFuncNoArg}, + {"f.delete_workspace", 0, + CRS_ANY, + 0, + F_DeleteWorkspace, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.exec", 0, + CRS_ANY, + 0, + F_Exec, + ParseWmFuncStrArg}, + {"f.focus_color", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Focus_Color, + ParseWmFuncNoArg}, + {"f.focus_key", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Focus_Key, + ParseWmFuncNoArg}, +#ifdef WSM + {"f.goto_workspace", 0, + CRS_ANY, + 0, + F_Goto_Workspace, + ParseWmFuncStrArg}, +#endif /* WSM */ +#ifdef WSM + {"f.help", 0, + CRS_ANY, + 0, + F_Help, + ParseWmFuncStrArg}, /* [helpvolume && helptopic] */ + {"f.help_mode", 0, + CRS_ANY, + 0, + F_Help_Mode, + ParseWmFuncNoArg}, /* for now */ +#endif /* WSM */ +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + {"f.invoke_command", + 0, CRS_ANY, + 0, + F_InvokeCommand, + ParseWmFuncStrArg}, +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + {"f.kill", F_CONTEXT_ROOT, + CRS_ANY, + MWM_FUNC_CLOSE, + F_Kill, + ParseWmFuncNoArg}, + {"f.lower", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Lower, + ParseWmFuncMaybeStrArg}, +#ifdef WSM + {"f.marquee_selection", + F_CONTEXT_WINDOW|F_CONTEXT_ICON|F_SUBCONTEXT_IB_IICON, + CRS_ANY, + 0, + F_Marquee_Selection, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.maximize", F_CONTEXT_ROOT|F_CONTEXT_MAXIMIZE| + F_SUBCONTEXT_IB_WICON, + CRS_ANY, + MWM_FUNC_MAXIMIZE, + F_Maximize, + ParseWmFuncNoArg}, + {"f.menu", 0, + CRS_ANY, + 0, + F_Menu, + ParseWmFuncStrArg}, + {"f.minimize", F_CONTEXT_ICON|F_CONTEXT_ROOT|F_SUBCONTEXT_IB_IICON, + CRS_ANY, + MWM_FUNC_MINIMIZE, + F_Minimize, + ParseWmFuncNoArg}, + {"f.move", F_CONTEXT_ROOT, + CRS_ANY, + MWM_FUNC_MOVE, + F_Move, + ParseWmFuncNoArg}, + {"f.next_cmap", 0, + CRS_ANY, + 0, + F_Next_Cmap, + ParseWmFuncNoArg}, + {"f.next_key", 0, + CRS_ANY, + 0, + F_Next_Key, + ParseWmFuncGrpArg}, +#ifdef WSM + {"f.next_workspace", 0, + CRS_ANY, + 0, + F_Next_Workspace, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.nop", F_CONTEXT_ROOT|F_CONTEXT_ICON|F_CONTEXT_WINDOW| + F_SUBCONTEXT_IB_WICON | F_SUBCONTEXT_IB_IICON, + CRS_ANY, + 0, + F_Nop, + ParseWmFuncNoArg}, + {"f.normalize", F_CONTEXT_ROOT|F_CONTEXT_NORMAL|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Normalize, + ParseWmFuncNoArg}, +#ifdef PANELIST + {"f.normalize_and_raise", + F_CONTEXT_ROOT|F_CONTEXT_NORMAL, + CRS_ANY, + 0, + F_Normalize_And_Raise, + ParseWmFuncMaybeStrArg}, +#else /* PANELIST */ + {"f.normalize_and_raise", + F_CONTEXT_ROOT|F_CONTEXT_NORMAL, + CRS_ANY, + 0, + F_Normalize_And_Raise, + ParseWmFuncNoArg}, +#endif /* PANELIST */ +#ifdef WSM + {"f.occupy_all", F_CONTEXT_ICONBOX|F_CONTEXT_ROOT, + CRS_ANY, + DtWM_FUNC_OCCUPY_WS, + F_AddToAllWorkspaces, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.pack_icons", 0, + CRS_ANY, + 0, + F_Pack_Icons, + ParseWmFuncNoArg}, + {"f.pass_keys", 0, + CRS_ANY, + 0, + F_Pass_Key, + ParseWmFuncNoArg}, +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + {"f.post_rmenu", 0, + CRS_KEY, + 0, + F_Post_RMenu, + ParseWmFuncNoArg}, +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + {"f.post_wmenu", 0, + CRS_BUTTON|CRS_KEY, + 0, + F_Post_SMenu, + ParseWmFuncNoArg}, + {"f.prev_cmap", 0, + CRS_ANY, + 0, + F_Prev_Cmap, + ParseWmFuncNoArg}, + {"f.prev_key", 0, + CRS_ANY, + 0, + F_Prev_Key, + ParseWmFuncGrpArg}, +#ifdef WSM + {"f.prev_workspace", 0, + CRS_ANY, + 0, + F_Prev_Workspace, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.quit_mwm", F_CONTEXT_ICON|F_CONTEXT_WINDOW, + CRS_ANY, + 0, + F_Quit_Mwm, + ParseWmFuncNoArg}, + {"f.raise", F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Raise, + ParseWmFuncMaybeStrArg}, + {"f.raise_lower", F_CONTEXT_ROOT | + F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Raise_Lower, + ParseWmFuncNoArg}, + {"f.refresh", 0, + CRS_ANY, + 0, + F_Refresh, + ParseWmFuncNoArg}, + {"f.refresh_win", F_CONTEXT_ICON|F_CONTEXT_ROOT, + CRS_ANY, + 0, + F_Refresh_Win, + ParseWmFuncNoArg}, +#ifdef WSM + {"f.remove", F_CONTEXT_ROOT, + CRS_ANY, + DtWM_FUNC_OCCUPY_WS, + F_Remove, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.resize", F_CONTEXT_ICON|F_CONTEXT_ROOT| + F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + MWM_FUNC_RESIZE, + F_Resize, + ParseWmFuncNoArg}, +#ifdef WSM + {"f.restart", F_CONTEXT_ICON|F_CONTEXT_WINDOW, + CRS_ANY, + 0, + F_Restart, + ParseWmFuncStrArg}, +#else /* WSM */ + {"f.restart", F_CONTEXT_ICON|F_CONTEXT_WINDOW, + CRS_ANY, + 0, + F_Restart, + ParseWmFuncNoArg}, +#endif /* WSM */ + {"f.restore", F_CONTEXT_ROOT|F_CONTEXT_NORMAL|F_SUBCONTEXT_IB_WICON, + CRS_ANY, + 0, + F_Restore, + ParseWmFuncNoArg}, + {"f.restore_and_raise", + F_CONTEXT_ROOT|F_CONTEXT_NORMAL, + CRS_ANY, + 0, + F_Restore_And_Raise, + ParseWmFuncNoArg}, + {"f.screen", 0, + CRS_ANY, + 0, + F_Screen, + ParseWmFuncStrArg}, + {"f.send_msg", F_CONTEXT_ROOT, + CRS_ANY, + 0, + F_Send_Msg, + ParseWmFuncNbrArg}, + {"f.separator", 0, + CRS_MENU, + 0, + F_Separator, + ParseWmFuncNoArg}, + {"f.set_behavior", 0, + CRS_ANY, + 0, + F_Set_Behavior, + ParseWmFuncNoArg}, +#ifdef WSM + {"f.set_context", 0, + CRS_ANY, + 0, + F_Set_Context, + ParseWmFuncNbrArg}, +#endif /* WSM */ + {"f.title", 0, + CRS_MENU, + 0, + F_Title, + ParseWmFuncNoArg}, +#if defined(PANELIST) + {"f.toggle_frontpanel", 0, + CRS_ANY, + 0, + F_Toggle_Front_Panel, + ParseWmFuncNoArg}, + + {"f.version", 0, + CRS_ANY, + 0, + F_Version, + ParseWmFuncNoArg}, +#endif /* PANELIST */ +#ifdef WSM + +#ifdef OLD + {"f.workspace_presence",F_CONTEXT_ICON|F_CONTEXT_ROOT|F_CONTEXT_ICONBOX| + F_SUBCONTEXT_IB_IICON|F_SUBCONTEXT_IB_WICON, +#endif /* OLD */ + {"f.workspace_presence", F_CONTEXT_ROOT|F_CONTEXT_ICONBOX| + F_SUBCONTEXT_IB_WICON, + CRS_ANY, + DtWM_FUNC_OCCUPY_WS, + F_Workspace_Presence, + ParseWmFuncNoArg}, +#endif /* WSM */ +#if defined(DEBUG) && defined(WSM) + {"f.zz_debug", 0, + CRS_ANY, + 0, + F_ZZ_Debug, + ParseWmFuncStrArg}, +#endif /* DEBUG */ +}; + +/* + * NOTE: New functions MUST be added in ALPHABETICAL order. A binary search + * is used to find the correct function name. + */ + +#define WMFUNCTIONTABLESIZE (sizeof(functionTable)/sizeof(functionTable[0])) + +/* + * Be sure to update these define, whenever adding/deleting a function. + */ +#ifdef WSM +# if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) +# define F_CCI_INDEX 2 +# endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ +int F_ACTION_INDEX; +int F_EXEC_INDEX; +int F_NOP_INDEX; +#else /* WSM */ +# if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) +# define F_CCI_INDEX 1 +# define F_EXEC_INDEX 4 +# define F_NOP_INDEX 16 +# else +# define F_EXEC_INDEX 3 +# define F_NOP_INDEX 14 +# endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ +#endif /* WSM */ +#ifdef WSM + +/******************************<->************************************* + * + * void GetFunctionTableValues (int *execIndex, int *nopIndex, + * int *actionIndex) + * + * Description: + * ----------- + * This routine dynamically computes the size of the functionTable[], + * and the indices for key functions, such as f.exec, f.action, and + * f.nop + * + * Inputs: + * ------ + * We are setting the values of F_EXEC_INDEX, F_ACTION_INDEX, + * and F_NOP_INDEX on a global level. The addresses + * for same are passed in. + * + * Outputs: + * ------- + * + * Comments: + * -------- + * This routine calls smaller routines for efficiency sake. + * + ******************************<->***********************************/ +void +GetFunctionTableValues (int *execIndex, int *nopIndex, + int *actionIndex) +{ + + GetExecIndex (WMFUNCTIONTABLESIZE, execIndex); + + GetActionIndex (WMFUNCTIONTABLESIZE, actionIndex); + + GetNopIndex (WMFUNCTIONTABLESIZE, nopIndex); + +} /* END OF FUNCTION GetFunctionTableValues */ + + + +/******************************<->************************************* + * + + * + * Description: + * ----------- + + * + * Inputs: + * ------ + + * Outputs: + * ------- + * + * Comments: + * -------- + * + ******************************<->***********************************/ + +void +GetExecIndex (int tableSize, int *execIndex) +{ + int i; + + for (i = 0; i < (tableSize); i++) + { + if (!(strcmp ("f.exec", functionTable[i].funcName))) + { + *execIndex = i; + return; + } + else + { + *execIndex = 0; + } + } +} /* END OF FUNCTION GetExecIndex */ + + +/******************************<->************************************* + * + + * + * Description: + * ----------- + + * + * Inputs: + * ------ + + * Outputs: + * ------- + * + * Comments: + * -------- + * + ******************************<->***********************************/ + + +void +GetActionIndex (int tableSize, int *actionIndex) +{ + int i; + + for (i = 0; i < (tableSize); i++) + { + if (!(strcmp ("f.action", functionTable[i].funcName))) + { + *actionIndex = i; + return; + } + else + { + *actionIndex = 0; + } + } +} /* END OF FUNCTION GetActionIndex */ + + + +/******************************<->************************************* + * + + * + * Description: + * ----------- + + * + * Inputs: + * ------ + + * Outputs: + * ------- + * + * Comments: + * -------- + * + ******************************<->***********************************/ +void +GetNopIndex (int tableSize, int *nopIndex) +{ + int i; + + for (i = 0; i < (tableSize); i++) + { + if (!(strcmp ("f.nop", functionTable[i].funcName))) + { + *nopIndex = i; + return; + } + else + { + *nopIndex = 0; + } + } +} /* END OF FUNCTION GetNopIndex */ + + + + +/*************************************<->************************************* + * + * void + * WmDtGetHelpArgs () + * + * + * Description: + * ----------- + * Get Help Args + + * + * Inputs: + * ------ + + * + * Outputs: + * ------- + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ +void +WmDtGetHelpArgs(char *args, + unsigned char* volume, + unsigned char* topic, + int *argsCount) +{ + unsigned char *string; + unsigned char *lineP; + + cfileP = NULL; + linec = 0; + parseP = (unsigned char*) args; + + if(GetNextLine () != NULL) + { + *argsCount = 0; + lineP = line; + if ((string = GetSmartSMString (&lineP)) != NULL) + { + *argsCount = *argsCount + 1; + strcpy ((char*)topic, (char*)string); + } + + if ((string = GetSmartSMString (&lineP)) != NULL) + { + *argsCount = *argsCount + 1; + strcpy ((char*)volume, (char *)string); + } + } + +} /* END OF FUNCTION WmDtGetHelpArgs */ + + + + + +/******************************<->************************************* + * + * void + * ParseDtSessionHints (pSD, property) + * + * + * Description: + * ----------- + * This function parses a DtSessionHints string and returns a list of + * DtSessionItems array. The string should have the syntax: + * + + * + * + * Inputs: + * ------ + * line = (global) line buffer + * pSD->rootWindow = default root window of display + * + * + * Outputs: + * ------- + * Return = + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +void +ParseDtSessionHints (WmScreenData *pSD, unsigned char *property) +{ + + cfileP = NULL; + linec = 0; + parseP = property; + + ParseSessionItems (pSD); + +} /* END OF FUNCTION ParseDtSessionHints */ + + +/*************************************<->************************************* + * + * FindDtSessionMatch(commandArgc, commandArgv, pCD, pSD, pWorkSpaceList, + * clientMachine) + * + * Description: + * ----------- + * Try to find a match for this client in the session hints. + * Set up client-session data. + * + * + * Inputs: + * ------ + * commandArgc - argument count + * commandArgv - WM_COMMAND argument vector + * pCD - pointer to client data + * pSD - pointer to screen data + * pWorkspaceList - pointer to a list of workspaces (to be returned) + * clientMachine - string for -host option in session hints + * + * Outputs: + * ------- + * *pCD - client data (may be modified) + * FindDtSessionMatch - returns True if a match for this client + * was found in the session hints. + * *pWorkspaceList - list of workspaces this client should be put + * into. (needs to be freed) + * + * + * Comments: + * -------- + * Various pieces of client state (in pCD) are reset when a match + * is found. + * + * The caller must free *pWorkspaceList when done. + * + *************************************<->***********************************/ +Boolean FindDtSessionMatch(int commandArgc, char **commandArgv, + ClientData *pCD, WmScreenData *pSD, + char **pWorkSpaceList, char *clientMachine) + +{ + int count, item; + int relCount; + int argNum; + SessionGeom *sessionGeom; + + + for (count = 0; count < pSD->totalSessionItems; count++) + { + if (!pSD->pDtSessionItems[count].processed && + pSD->pDtSessionItems[count].commandArgc == commandArgc) + { + if ((clientMachine) && + (pSD->pDtSessionItems[count].clientMachine) && + (strcmp(clientMachine, + pSD->pDtSessionItems[count].clientMachine))) + { + /* + * This item has clientMachine string but the + * clientMachine does not match. + */ + continue; + } + for (argNum = 0; argNum < commandArgc ; argNum++) + { + if(strcmp(commandArgv[argNum], + pSD->pDtSessionItems[count].commandArgv[argNum])) + + { + /* + * One mismatch and we quit looking at this item. + * Decrement argNum so a mismatch on the last item + * will not look like a match below when comparing + * argNum == commandArgc + */ + argNum--; + break; + } + } + if (argNum == commandArgc) + { + /* + * Made it through all strings so this is a match + */ + + pSD->pDtSessionItems[count].processed = True; + pSD->remainingSessionItems --; + pCD->clientFlags |= SM_LAUNCHED; + + /* + * Free strings malloc'd for commandArgv for this item + */ + + for (relCount = 0; relCount < commandArgc; relCount++) + { + XtFree(pSD->pDtSessionItems[count].commandArgv[relCount]); + } + XtFree((char *)pSD->pDtSessionItems[count].commandArgv); + + if(pSD->pDtSessionItems[count].clientState) + { + pCD->clientState = + pSD->pDtSessionItems[count].clientState; + pCD->clientFlags |= SM_CLIENT_STATE; + } + + if(pSD->pDtSessionItems[count].sessionGeom) + { + sessionGeom = pSD->pDtSessionItems[count].sessionGeom; + if (sessionGeom->flags & XValue) + { + pCD->clientX = sessionGeom->clientX; + pCD->clientFlags |= SM_X; + } + if (sessionGeom->flags & YValue) + { + pCD->clientY = sessionGeom->clientY; + pCD->clientFlags |= SM_Y; + } + if (sessionGeom->flags & WidthValue) + { + pCD->clientWidth = sessionGeom->clientWidth; + pCD->clientFlags |= SM_WIDTH; + } + if (sessionGeom->flags & HeightValue) + { + pCD->clientHeight = sessionGeom->clientHeight; + pCD->clientFlags |= SM_HEIGHT; + } + + /* + * Free SessionGeom malloc'd space for this item + */ + + XtFree((char *)pSD->pDtSessionItems[count].sessionGeom); + } + + if(pSD->pDtSessionItems[count].clientMachine) + { + /* + * Free clientMachine malloc'd space for this item + */ + + XtFree((char *) + pSD->pDtSessionItems[count].clientMachine); + pSD->pDtSessionItems[count].clientMachine = NULL; + } + + + if(pSD->pDtSessionItems[count].workspaces) + { + /* + * The caller is responsible for freeing this + * data. + */ + *pWorkSpaceList = pSD->pDtSessionItems[count].workspaces; + } + + + if(pSD->remainingSessionItems == 0) + { + /* + * Free the whole pSD->pDtSessionHints structure + */ + XtFree((char *)pSD->pDtSessionItems); + } + + return (True); + } + + } /* not processed and argc's are the same */ + + } /* for */ + + return (False); + +} /* END OF FUNCTION FindDtSessionMatch */ + + + + + +/*************************************<->************************************* + * + * void + * ParseSessionItems (pSD) + * + * + * Description: + * ----------- + * Parse session items + + * + * Inputs: + * ------ + * pSD = pointer to screen data + * cfileP = (global) file pointer to NULL + * line = (global) line buffer + * linec = (global) line count + * parseP = (global) parse string pointer if cfileP == NULL + * pSD->rootWindow = default root window of display + + * + * Outputs: + * ------- + * linec = (global) line count incremented + * parseP = (global) parse string pointer if cfileP == NULL + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +void +ParseSessionItems (WmScreenData *pSD) +{ + unsigned char *string; + unsigned char *lineP; + int count; + + + /* + * Parse property string + */ + + + + if(GetNextLine () != NULL) + { + pSD->totalSessionItems = atoi((char *)line); + pSD->remainingSessionItems = pSD->totalSessionItems; + } + + + if((pSD->totalSessionItems < 1) || + !GetSessionHintsInfo(pSD, pSD->totalSessionItems)) + { + /* + * No items or couldn't allocate space + */ + return; + } + + count = 0; + + while ((count < pSD->totalSessionItems) && (GetNextLine () != NULL)) + { + + lineP = line; + while ((string = GetSmartSMString (&lineP)) != NULL) + { + if (!strcmp((char *)string, "-geometry")) + { + /* + * Parse geometry if it is present + */ + string = GetSmartSMString(&lineP); + ParseSessionGeometry (pSD, count, string); + } + + else if (!strcmp((char *)string, "-state")) + { + /* + * Parse the state if it is present + */ + string = GetSmartSMString(&lineP); + ParseSessionClientState (pSD, count, string); + } + + else if (!strcmp((char *)string, "-workspaces")) + { + /* + * Parse the workspaces string if it is present + */ + string = GetSmartSMString(&lineP); + ParseSessionWorkspaces (pSD, count, string); + } + + else if (!strcmp((char *)string, "-cmd")) + { + /* + * Parse the command string if it is present + */ + string = GetSmartSMString(&lineP); + ParseSessionCommand (pSD, count, &string); + } + + else if (!strcmp((char *)string, "-host")) + { + /* + * Parse the host string if it is present + */ + string = GetSmartSMString(&lineP); + ParseSessionHost (pSD, count, string); + } + + } /* while GetSmartSMString */ + + count++; + + } /* while GetNextLine */ + + + +} /* END OF FUNCTION ParseSessionItems */ + + + +/*************************************<->************************************* + * + * ParseSessionClientState (pSD, count, string); + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +void ParseSessionClientState (WmScreenData *pSD, int count, + unsigned char *string) + + + +{ + + if(!strcmp((char *)string, "NormalState")) + { + pSD->pDtSessionItems[count].clientState = NORMAL_STATE; + } + else if(!strcmp((char *)string, "IconicState")) + { + pSD->pDtSessionItems[count].clientState = MINIMIZED_STATE; + } + + +} /* END OF FUNCTION ParseSessionClientState */ + + +/*************************************<->************************************* + * + * ParseSessionGeometry (pSD, count, string) + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +void ParseSessionGeometry (WmScreenData *pSD, int count, + unsigned char *string) + +{ + SessionGeom *pTmpSessionGeom; + int mask /* = 0 */; + int X, Y, width, height; + X = Y = width = height = 0; + + /* + * XParseGeometry + */ + + mask = XParseGeometry((char *)string, &X, &Y, (unsigned int *)&width, + (unsigned int *)&height); + if (mask) + { + /* + * Allocate space for the geometry structure + */ + + if ((pTmpSessionGeom = + (SessionGeom *)XtMalloc (sizeof (SessionGeom))) == NULL) + { + Warning (((char *)GETMESSAGE(60, 1, "Insufficient memory for session geometry item"))); + return; + + } + + pTmpSessionGeom->flags = mask; + pTmpSessionGeom->clientX = X; + pTmpSessionGeom->clientY = Y; + pTmpSessionGeom->clientWidth = width; + pTmpSessionGeom->clientHeight = height; + + pSD->pDtSessionItems[count].sessionGeom = pTmpSessionGeom; + } + +} /* END OF FUNCTION ParseSessionGeometry */ + + +/*************************************<->************************************* + * + * void + * ParseSessionWorkspaces (pSD, count, string) + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +void ParseSessionWorkspaces (WmScreenData *pSD, int count, + unsigned char *string) + +{ + + /* + * Allocate space for the workspaces string + */ + + if ((pSD->pDtSessionItems[count].workspaces = + (String)XtMalloc ((unsigned int) (strlen((char *)string) + 1))) == NULL) + { + Warning (((char *)GETMESSAGE(60, 2, "Insufficient memory for workspaces list in sesssion item"))); + return; + + } + + strcpy(pSD->pDtSessionItems[count].workspaces, (char *)string); + +} /* END OF FUNCTION ParseSessionWorkspaces */ + + + +/*************************************<->************************************* + * + * void + * ParseSessionCommand (pSD, count, string) + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +void ParseSessionCommand (WmScreenData *pSD, int count, + unsigned char **commandString) +{ +#define ARG_AMT 100 + int xindex; + unsigned char **argv; + int argc = 0; + int iSizeArgv; + + unsigned char *string; + + argv = (unsigned char **) XtMalloc (ARG_AMT * sizeof(char *)); + iSizeArgv = ARG_AMT; + + while ((string = GetSmartSMString (commandString)) != NULL) + { + /* + * Get pointers to strings in command line and count them + */ + argv[argc] = string; + argc ++; + + if (argc >= iSizeArgv) + { + iSizeArgv += ARG_AMT; + argv = (unsigned char **) + XtRealloc ((char *)argv, (iSizeArgv * sizeof(char *))); + } + } + if ((pSD->pDtSessionItems[count].commandArgv = + (char **)XtMalloc ((argc) * sizeof(char * ))) == NULL) + { + /* + * Allocate space for saved argv + */ + + Warning (((char *)GETMESSAGE(60, 3, "Insufficient memory for commandArgv array"))); + } + else + { + pSD->pDtSessionItems[count].commandArgc = argc; + for (xindex = 0; xindex < argc ; xindex++) + { + if ((pSD->pDtSessionItems[count].commandArgv[xindex] = + (String) XtMalloc + ((unsigned int) (strlen((char *)argv[xindex]) + 1))) == NULL) + { + /* + * Allocate space for the next command segment. + */ + Warning (((char *)GETMESSAGE(60, 4, "Insufficient memory for commandArgv item"))); + } + else + { + strcpy(pSD->pDtSessionItems[count].commandArgv[xindex], + (char *)argv[xindex]); + } + } + } + + XtFree ((char *) argv); + +} /* END OF FUNCTION ParseSessionCommand */ + + + +/*************************************<->************************************* + * + * void + * ParseSessionHost (pSD, count, string) + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +void ParseSessionHost (WmScreenData *pSD, int count, + unsigned char *string) + +{ + + /* + * Allocate space for the workspaces string + */ + + if ((pSD->pDtSessionItems[count].clientMachine = + (String)XtMalloc ((unsigned int) (strlen((char *)string) + 1))) == + NULL) + { + Warning (((char *)GETMESSAGE(60, 38, + "Insufficient memory for host name in sesssion item"))); + return; + } + + strcpy(pSD->pDtSessionItems[count].clientMachine, (char *)string); + +} /* END OF FUNCTION ParseSessionHost */ + + + +/*************************************<->************************************* + * + * GetSessionHintsInfo (pSD, numItems) + * + * Description: + * ----------- + * Inputs: + * ------ + * Outputs: + * ------- + * Comments: + * -------- + * + *************************************<->***********************************/ +Boolean GetSessionHintsInfo (WmScreenData *pSD, long numItems) + +{ + + if ((pSD->pDtSessionItems = + (DtSessionItem *)XtMalloc (numItems * sizeof (DtSessionItem))) + == NULL) + { + Warning (((char *)GETMESSAGE(60, 5, "Insufficient memory for Dt Session Hints"))); + return(False); + } + + memset ((char *)pSD->pDtSessionItems, NULL, + numItems * sizeof (DtSessionItem)); + + return(True); + + +} /* END OF FUNCTION GetSessionHintsInfo */ + + + + +/*************************************<->************************************* + * + * PeekAhead (currentChar, currentLev) + * + * + * Description: + * ----------- + * Returns a new level value if this is a new nesting level of quoted string + * Otherwise it returns a zero + * + * + * Inputs: + * ------ + * currentChar = current position in the string + * currentLev = current level of nesting + * + * + * Outputs: + * ------- + * Returns either a new level of nesting or zero if the character is copied in + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ +unsigned int PeekAhead(unsigned char *currentChar, + unsigned int currentLev) + + +{ + Boolean done = False; + unsigned int tmpLev = 1; +#ifndef NO_MULTIBYTE + unsigned int chlen; + + while (((chlen = mblen ((char *)currentChar, MB_CUR_MAX)) > 0) && + (chlen == 1) && ((*currentChar == '"') || (*currentChar == '\\')) + && (done == False)) + { + currentChar++; + + if(((chlen = mblen ((char *)currentChar, MB_CUR_MAX)) > 0) && (chlen == 1) && + ((*currentChar == '"') || (*currentChar == '\\'))) + { + tmpLev++; + if(*currentChar == '"') + { + done = True; + } + else + { + currentChar++; + } + } + } +#else + while((*currentChar != NULL) && (done == False) && + ((*currentChar == '"') || (*currentChar == '\\'))) + { + currentChar++; + if((*currentChar != NULL) && + ((*currentChar == '"') || (*currentChar == '\\'))) + { + tmpLev++; + if(*currentChar == '"') + { + done = True; + } + else + { + currentChar++; + } + } + } +#endif /*NO_MULTIBYTE*/ + + /* + * Figure out if this is truly a new level of nesting - else ignore it + * This section probably could do some error checking and return -1 + * If so, change type of routine from unsigned int to int + */ + if(done == True) + { + return(tmpLev); + } + else + { + return(0); + } +} /* END OF FUNCTION PeekAhead */ + + +#endif /* WSM */ + + + +#ifdef MOTIF_ONE_DOT_ONE +/*************************************<->************************************* + * + * GetHomeDirName (fileName) + * + * Description: + * ----------- + * This function finds the "HOME" directory + * + * + * Inputs: + * ------ + * fileName + * + * Outputs: + * ------- + * fileName + * + * Comments: + * -------- + * + *************************************<->***********************************/ +void GetHomeDirName(String fileName) +{ + int uid; + struct passwd *pw; + char *ptr = NULL; + + if((ptr = getenv("HOME")) == NULL) + { + if((ptr = getenv("USER")) != NULL) + { + pw = getpwnam(ptr); + } + else + { + uid = getuid(); + pw = getpwuid(uid); + } + + if (pw) + { + ptr = pw->pw_dir; + } + else + { + ptr = ""; + } + } + strcpy(fileName, ptr); +} +#endif + + +/*************************************<->************************************* + * + * SyncModifierStrings (fileName) + * + * Description: + * ----------- + * This function updates modifierStrings table so that Mwm uses the correct + * modifier to keysym mapping. Specifically, fix up the Alt and Meta bindings. + * + * Inputs: + * ------ + * fileName + * + * Outputs: + * ------- + * fileName + * + * Comments: + * -------- + * + *************************************<->***********************************/ +void SyncModifierStrings(void) +{ + XModifierKeymap *map; + int i, j, k = 0; + + map = XGetModifierMapping (DISPLAY); + + for (i = 0; i < 8; i++) + { + for (j = 0; j < map->max_keypermod; j++) + { + if (map->modifiermap[k]) + { + KeySym ks = XKeycodeToKeysym(DISPLAY, map->modifiermap[k], 0); + char *nm = XKeysymToString(ks); + + /* Compare, ignoring the trailing '_L' or '_R' in keysym */ + if (nm && !strncmp("Alt", nm, 3)) + { + modifierStrings[ALT_INDEX].mask = (1<************************************* + * + * ProcessWmFile () + * + * + * Description: + * ----------- + * This function reads the mwm resource description file and processes the + * resources that are described. + * + * + * Inputs: + * ------ + * wmGD.bitmapDirectory = bitmapDirectory resource value + * pSD->buttonBindings = buttonBindings resource value + * wmGD.configFile = configuration file resource value + * pSD->keyBindings = keyBindings resource value + * wmGD.rootWindow = default root window of display + * HOME = environment variable for home directory + * functionTable = window manager function parse table + * + * + * Outputs: + * ------- + * wmGD.buttonSpecs = list of button binding specifications + * wmGD.keySpecs = list of key binding specification + * wmGD.menuSpecs = list of menu specifications + * *wmGD.acceleratorMenuSpecs = initialized array of (MenuSpec *) + * wmGD.acceleratorMenuCount = 0 + * + * + * Comments: + * -------- + * If there are more than MAXLINE characters on a line the excess characters + * are truncated. + * + *************************************<->***********************************/ +#define MENU_SPEC "menu" +#define BUTTON_SPEC "buttons" +#define KEY_SPEC "keys" +#ifdef PANELIST +#define FRONT_PANEL_SPEC DTWM_FP_PANEL_OLD +#define DROP_EFFECTS_SPEC DTWM_FP_DROP_EFFECTS +#define PANEL_SPEC DTWM_FP_PANEL +#define BOX_SPEC DTWM_FP_BOX +#define CONTROL_SPEC DTWM_FP_CONTROL +#define INCLUDE_SPEC DTWM_FP_INCLUDE +#define ANIMATION_SPEC DTWM_FP_ANIMATION +#define SWITCH_SPEC DTWM_FP_SWITCH + +void ProcessWmFile (WmScreenData *pSD, Boolean bNested) + +#else /* PANELIST */ +void ProcessWmFile (WmScreenData *pSD) +#endif /* PANELIST */ +{ + unsigned char *lineP; + unsigned char *string; + unsigned int n; + MenuSpec *menuSpec; +#ifdef PANELIST + static Boolean conversionInProgress = False; + Arg args[10]; + int argnum; + + if (!bNested) + { +#endif /* PANELIST */ + + /* + * Initialize global data values that are set based on data in + * the mwm resource description file. + */ + + pSD->buttonSpecs = NULL; + pSD->keySpecs = NULL; + pSD->menuSpecs = NULL; + +#ifdef WSM + /**** hhhhhhhhhhhh ******/ + GetFunctionTableValues (&F_EXEC_INDEX, &F_NOP_INDEX, &F_ACTION_INDEX); +#endif /* WSM */ + /* + * Find and parse the default system menu string, if it exists. + */ + + cfileP = NULL; + linec = 0; + if (((parseP = (unsigned char *) builtinSystemMenu) != NULL) && + (GetNextLine () != NULL)) + { + lineP = line; + ParseMenuSet (pSD, lineP); + } + + linec = 0; + if (((parseP = (unsigned char *) builtinRootMenu) != NULL) && + (GetNextLine () != NULL)) + { + lineP = line; + ParseMenuSet (pSD, lineP); + } +#ifdef PANELIST + if (wmGD.useFrontPanel && !wmGD.dtSD && + (XDefaultScreen (wmGD.display) == pSD->screen)) + { + wmGD.dtSD = pSD; /* only one per display */ + } +#endif /* PANELIST */ + + /* + * Find and associate a stream with the window manager resource + * description file. + */ + + if ((cfileP = FopenConfigFile ()) == NULL) + { + if (!wmGD.useStandardBehavior) + Warning (((char *)GETMESSAGE(60, 6, "Cannot open configuration file"))); + return; + } + +#ifdef PANELIST + } /* end if (!bNested) */ +#endif /* PANELIST */ + /* + * Parse the information in the configuration file. + * If there are more than MAXLINE characters on a line the excess are + * truncated. + */ + + linec = 0; + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + if ((*line == '!') || (string = GetString (&lineP)) == NULL) + /* empty or comment line */ + { + continue; + } + + ToLower (string); + if (!strcmp ((char *)string, MENU_SPEC)) + { + ParseMenuSet (pSD, lineP); + } + else if (!strcmp ((char *) string, BUTTON_SPEC)) + { + ParseButtonSet (pSD, lineP); + } + else if (!strcmp ((char *) string, KEY_SPEC)) + { + ParseKeySet (pSD, lineP); + } +#ifdef PANELIST + else if (!strcmp ((char *)string, INCLUDE_SPEC)) + { + ParseIncludeSet (pSD, lineP); + } +#endif /* PANELIST */ + } + + fclose (cfileP); + + /* + * Create and initialize the pSD->acceleratorMenuSpecs array. + * This assumes we create pointers to MenuSpecs within ProcessWmFile(). + * Set pSD->acceleratorMenuCount to 0. + */ + + /* count the number of menu specifications */ + n = 0; + menuSpec = pSD->menuSpecs; + while (menuSpec) + { + n++; + menuSpec = menuSpec->nextMenuSpec; + } + + /* allocate the array and initialize to zeros */ + pSD->acceleratorMenuSpecs = NULL; + if (n) + { + pSD->acceleratorMenuSpecs = + (MenuSpec **) XtCalloc (n, sizeof (MenuSpec *)); + if (pSD->acceleratorMenuSpecs == NULL) + { + Warning (((char *)GETMESSAGE(60, 7, "Insufficient memory for menu accelerators"))); + } + } + pSD->acceleratorMenuCount = 0; +} /* END OF FUNCTION ProcessWmFile */ + +/**** This function stolen from Xt/Intrinsic.c ****/ +/* The implementation of this routine is operating system dependent */ + +static char *ExtractLocaleName(lang) + String lang; +{ + +#ifdef hpux /* hpux-specific parsing of the locale string */ +#define MAXLOCALE 64 /* buffer size of locale name */ + + char *start; + char *end; + int len; + static char buf[MAXLOCALE]; + + /* If lang has a substring ":;", extract + * from the first such occurrence as the locale name. + */ + + start = lang; + if (start = strchr (lang, ':')) { + start++; + if (end = strchr (start, ';')) { + len = end - start; + strncpy(buf, start, len); + *(buf + len) = '\0'; + lang = buf; + } + } +#endif /* hpux */ + + return lang; +} + +#ifdef WSM +#define RC_CONFIG_SUBDIR "/config/" +#define RC_DEFAULT_CONFIG_SUBDIR "/config/C" +#endif /* WSM */ + +/*************************************<->************************************* + * + * FopenConfigFile () + * + * + * Description: + * ----------- + * This function searches for, opens, and associates a stream with the mwm + * resource description file, + * + * + * Inputs: + * ------ + * wmGD.configFile = configuration file resource value. + * HOME = environment variable for home directory + * + * + * Outputs: + * ------- + * Return = If successful, a pointer to the FILE structure associated with + * the configuration file. Otherwise, NULL. + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ +FILE *FopenConfigFile (void) +{ + + char *LANG, *LANGp; + FILE *fileP; + +#ifndef MOTIF_ONE_DOT_ONE + char *homeDir = XmeGetHomeDirName(); +#endif +#ifdef PANELIST + Boolean stackPushed; +#endif /* PANELIST */ + + /* + * Get the LANG environment variable + * make copy since another call to getenv will blast the value. + */ + LANGp = setlocale(LC_CTYPE, NULL); + + /* + * setlocale not guaranteed to return $LANG -- extract + * something usable. + */ + LANGp = ExtractLocaleName (LANGp); + + if ((LANGp == NULL) || (strlen(LANGp) == 0)) + { + LANG = NULL; + } + else + { + if ((LANG = (char *) XtMalloc(strlen(LANGp) +1)) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 41, "Insufficient memory to get LANG environment variable."))); + return(NULL); + } + + strcpy(LANG, LANGp); + } + + + /* + * To get a name for the file first look at the value of the configFile + * resource. Interpret "~/.." as relative to the user's home directory. + * Use the LANG variable if set and .mwmrc is in $HOME/$LANG/.mwmrc + */ + +#ifdef PANELIST + if (pConfigStackTop && pConfigStackTop->tempName) + { + fileP = fopen (pConfigStackTop->tempName, "r"); + return (fileP); + } + stackPushed = (pConfigStackTop && (pConfigStackTop != pConfigStack)); + fileP = NULL; + cfileName[0] = '\0'; +#endif /* PANELIST */ + if ((wmGD.configFile != NULL) && (wmGD.configFile[0] != '\0')) + /* pointer to nonNULL string */ + { + if ((wmGD.configFile[0] == '~') && (wmGD.configFile[1] == '/')) + /* handle "~/..." */ + { +#ifdef MOTIF_ONE_DOT_ONE + GetHomeDirName(cfileName); +#else + strcpy (cfileName, homeDir); +#endif + if (LANG != NULL) + { + strncat(cfileName, "/", MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + } + strncat(cfileName, &(wmGD.configFile[1]), MAXWMPATH-strlen(cfileName)); + if ((fileP = fopen (cfileName, "r")) != NULL) + { + if (LANG != NULL) { + XtFree(LANG); + LANG = NULL; + } +#ifndef PANELIST + return (fileP); +#endif /* PANELIST */ + } + else + { + /* + * Just try $HOME/.mwmrc + */ +#ifdef MOTIF_ONE_DOT_ONE + GetHomeDirName(cfileName); +#else + strcpy (cfileName, homeDir); +#endif + strncat(cfileName, &(wmGD.configFile[1]), + MAXWMPATH-strlen(cfileName)); + if ((fileP = fopen (cfileName, "r")) != NULL) + { + if (LANG != NULL) { + XtFree(LANG); + LANG = NULL; + } +#ifndef PANELIST + return (fileP); +#endif /* PANELIST */ + } + } + + + } + else + /* relative to current directory or absolute */ + { +#ifdef PANELIST + char *pch; + + pch = (char *) GetNetworkFileName (wmGD.configFile); + + if ((fileP = fopen (pch, "r")) != NULL) + { + strncpy (cfileName, pch, MAXWMPATH); + } + XtFree (pch); + + if ((fileP == NULL) && !stackPushed) + { +#endif /* PANELIST */ + if ((fileP = fopen (wmGD.configFile, "r")) != NULL) + { + if (LANG != NULL) { + XtFree(LANG); + LANG = NULL; + } + return(fileP); + } +#ifdef PANELIST + } + else if ((fileP == NULL) && stackPushed) + { + strcpy (cfileName, wmGD.configFile); + } +#endif /* PANELIST */ + } + } +#ifdef PANELIST + if ((fileP == NULL) && !stackPushed) + { +#endif /* PANELIST */ + + /* + * The configFile resource didn't do it for us. + * First try HOME_MWMRC, then try SYS_MWMRC . + */ + +#define HOME_MWMRC "/.mwmrc" +#define SLASH_MWMRC "/system.mwmrc" + +#ifdef MOTIF_ONE_DOT_ONE + GetHomeDirName(cfileName); +#else + strcpy (cfileName, homeDir); +#endif + +#ifdef WSM + if (MwmBehavior) + { + /* + * + * Looking for $HOME/$LANG/.mwmrc + * --or--if $LANG is NULL + * Looking for $HOME/.mwmrc + * + */ + if (LANG != NULL) + { + strncat(cfileName, "/", MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + } + strncat(cfileName, HOME_MWMRC, MAXWMPATH - strlen(cfileName)); + } + else + { + /* + * + * Looking for $HOME/.dt/$LANG/dtwmrc + * + * --or--if $LANG is NULL-- + * + * Looking for $HOME/.dt/dtwmrc + * + */ + strncat(cfileName, "/.dt/", MAXWMPATH-strlen(cfileName)); + + if (LANG != NULL) + { + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + } + strncat(cfileName, LANG_DT_WMRC, MAXWMPATH - strlen(cfileName)); + } +#else /* WSM */ + if (LANG != NULL) + { + strncat(cfileName, "/", MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + } + strncat(cfileName, HOME_MWMRC, MAXWMPATH - strlen(cfileName)); +#endif /* WSM */ + if ((fileP = fopen (cfileName, "r")) != NULL) + { + if (LANG != NULL) { + XtFree(LANG); + LANG = NULL; + } +#ifndef PANELIST + return (fileP); +#endif /* PANELIST */ + } + else + { + /* + * Just try $HOME/.mwmrc + */ +#ifdef MOTIF_ONE_DOT_ONE + GetHomeDirName(cfileName); +#else + strcpy (cfileName, homeDir); +#endif +#ifdef WSM + if (MwmBehavior) + { + /* + * Just try $HOME/.mwmrc + */ + strncat(cfileName, HOME_MWMRC, MAXWMPATH - strlen(cfileName)); + } + else + { + /* + * Just try $HOME/.dt/dtwmrc + */ + strncat(cfileName, HOME_DT_WMRC, MAXWMPATH - strlen(cfileName)); + } +#else /* WSM */ + strncat(cfileName, HOME_MWMRC, MAXWMPATH - strlen(cfileName)); +#endif /* WSM */ + if ((fileP = fopen (cfileName, "r")) != NULL) + { + if (LANG != NULL) { + XtFree(LANG); + LANG = NULL; + } +#ifndef PANELIST + return (fileP); +#endif /* PANELIST */ + } + } +#ifdef PANELIST + } + +#define DTLIBDIR CDE_INSTALLATION_TOP +#define DTADMINDIR CDE_CONFIGURATION_TOP +#define SLASH_DT_WMRC "/sys.dtwmrc" + + if ((fileP == NULL) && !stackPushed) + { + /* + * No home-based config file. Try the admin directory. + */ + strcpy(cfileName, DTADMINDIR); + strncat(cfileName, RC_CONFIG_SUBDIR, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, SLASH_DT_WMRC, MAXWMPATH - strlen(cfileName)); + + if (((fileP = fopen (cfileName, "r")) == NULL) && LANG && *LANG) + { + /* Try it with no LANG */ + strcpy(cfileName, DTADMINDIR); + strncat(cfileName, RC_CONFIG_SUBDIR, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, SLASH_DT_WMRC, MAXWMPATH - strlen(cfileName)); + } + + if ((fileP = fopen (cfileName, "r")) != NULL) + { + XtFree(LANG); + LANG = NULL; + } + } + + if ((fileP == NULL) && !stackPushed) + { +#endif /* PANELIST */ + +#ifndef MWMRCDIR +#define MWMRCDIR "/usr/lib/X11" +#endif + if (LANG != NULL) + { +#ifdef WSM + if (MwmBehavior) + { + strcpy(cfileName, MWMRCDIR); + strncat(cfileName, "/", MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, SLASH_MWMRC, MAXWMPATH - strlen(cfileName)); + } + else + { + strcpy(cfileName, DTLIBDIR); + strncat(cfileName, RC_CONFIG_SUBDIR, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, SLASH_DT_WMRC, MAXWMPATH - strlen(cfileName)); + } +#else /* WSM */ + /* + * Try /$LANG/system.mwmrc within the install tree + */ + strcpy(cfileName, MWMRCDIR); + strncat(cfileName, "/", MAXWMPATH-strlen(cfileName)); + strncat(cfileName, LANG, MAXWMPATH-strlen(cfileName)); + strncat(cfileName, SLASH_MWMRC, MAXWMPATH - strlen(cfileName)); +#endif /* WSM */ + if ((fileP = fopen (cfileName, "r")) != NULL) + { + XtFree(LANG); + LANG = NULL; +#ifndef PANELIST + return (fileP); +#endif /* PANELIST */ + } + } + +#ifdef PANELIST + if ((fileP == NULL) && !stackPushed) + { +#endif /* PANELIST */ +#ifdef WSM + if (MwmBehavior) + { + strcpy(cfileName, MWMRCDIR); + strncat(cfileName, SLASH_MWMRC, MAXWMPATH - strlen(cfileName)); +#ifdef PANELIST + fileP = fopen (cfileName, "r"); +#else /* PANELIST */ + return (fopen (cfileName, "r")); +#endif /* PANELIST */ + } + else + { + strcpy(cfileName, DTLIBDIR); + strncat(cfileName, RC_DEFAULT_CONFIG_SUBDIR, + MAXWMPATH - strlen(cfileName)); + strncat(cfileName, SLASH_DT_WMRC, MAXWMPATH - strlen(cfileName)); +#ifdef PANELIST + fileP = fopen (cfileName, "r"); +#else /* PANELIST */ + return (fopen (cfileName, "r")); +#endif /* PANELIST */ + } +#else /* WSM */ + /* + * Try /system.mwmrc within the install tree + */ + strcpy(cfileName, MWMRCDIR); + strncat(cfileName, SLASH_MWMRC, MAXWMPATH - strlen(cfileName)); + + if (LANG != NULL) + { + XtFree(LANG); + LANG = NULL; + } +#ifdef PANELIST + strcpy(cfileName, cfileName); + fileP = fopen (cfileName, "r"); +#else /* PANELIST */ + return (fopen (cfileName, "r")); +#endif /* PANELIST */ +#endif /* WSM */ +#ifdef PANELIST + } + } + + if (!fileP) + { + char *pch; + + /* + * handle ":" form of file name + */ + pch = (char *) GetNetworkFileName (cfileName); + if ((fileP = fopen (cfileName, "r")) != NULL) + { + strncpy (cfileName, pch, MAXWMPATH); + XtFree (pch); + } + + /* + * Either not ":" form or there was a + * problem up above. This is the last attempt to + * open something. + */ + if (!fileP) + { + fileP = fopen (cfileName, "r"); + } + } + + if (!pConfigStack) + { + ConfigStackInit (cfileName); + } + + if (wmGD.cppCommand && *wmGD.cppCommand) + { + /* + * Run the file through the C-preprocessor + */ + PreprocessConfigFile (); + if (pConfigStackTop->cppName) + { + /* open the result */ + fileP = fopen (pConfigStackTop->cppName, "r"); + } + } + + if (LANG != NULL) + { + XtFree(LANG); + LANG = NULL; + } + return (fileP); +#endif /* PANELIST */ + +} /* END OF FUNCTION FopenConfigFile */ + + +/*************************************<->************************************* + * + * SaveMenuAccelerators (pSD, newMenuSpec) + * + * + * Description: + * ----------- + * This function saves the MenuSpec pointer in pSD->acceleratorMenuSpecs. + * + * + * Inputs: + * ------ + * newMenuSpec = pointer to MenuSpec to be saved. + * pSD->acceleratorMenuSpecs = + * pSD->acceleratorMenuCount = + * + * + * Outputs: + * ------- + * pSD->acceleratorMenuSpecs = possibly updated + * pSD->acceleratorMenuCount = possibly updated + * + * + * Comments: + * -------- + * We assume only MenuSpecs created within ProcessWmFile() are to be saved. + * Otherwise, we may cause override the limits of pSD->acceleratorMenuSpecs. + * + *************************************<->***********************************/ + +void SaveMenuAccelerators (WmScreenData *pSD, MenuSpec *newMenuSpec) +{ + MenuSpec **pMenuSpec; + + pMenuSpec = pSD->acceleratorMenuSpecs; + + if (pMenuSpec == NULL) + return; + + while ((*pMenuSpec != NULL) && (*pMenuSpec != newMenuSpec)) + { + pMenuSpec++; + } + + if (*pMenuSpec == NULL) + { + *pMenuSpec = newMenuSpec; + pSD->acceleratorMenuCount++; + } + +} /* END OF FUNCTION SaveMenuAccelerators */ + + +/*************************************<->************************************* + * + * ParseMenuSet (pSD, lineP) + * + * + * Description: + * ----------- + * Menu pane specification found. Parse the following syntax: + * + * v + * Menu menu_pane_name + * { + * label [mnemonic] [accelerator] function + * label [mnemonic] [accelerator] function + * ... + * label [mnemonic] [accelerator] function + * } + * + * + * Inputs: + * ------ + * cfileP = (global) file pointer to fopened configuration file or NULL + * lineP = pointer to menu name in line buffer + * line = (global) line buffer + * linec = (global) line count + * parseP = (global) parse string pointer if cfileP == NULL + * pSD->rootWindow = default root window of display + * wmGD.bitmapDirectory = bitmapDirectory resource value + * HOME = environment variable for home directory + * + * + * Outputs: + * ------- + * linec = (global) line count incremented + * parseP = (global) parse string pointer if cfileP == NULL + * pSD->menuSpecs = list of menu specifications + * + * + * Comments: + * -------- + * Skips unnamed menu specifications. + * This means custom menu specifications can be distinguished by NULL name. + * + *************************************<->***********************************/ + +static void ParseMenuSet (WmScreenData *pSD, unsigned char *lineP) +{ + unsigned char *string; + MenuSpec *menuSpec; + + /* + * If menu name is NULL then skip this pane specification. + */ + + if ((string = GetString (&lineP)) == NULL) + { + return; + } + + /* + * Allocate space for the menu specification structure. + */ + + if ((menuSpec = (MenuSpec *)XtMalloc (sizeof (MenuSpec))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 9, "Insufficient memory for menu"))); + return; + } + menuSpec->currentContext = 0; + menuSpec->menuWidget = NULL; + menuSpec->whichButton = SELECT_BUTTON; /* Button1 selection default */ + menuSpec->menuItems = NULL; + menuSpec->accelContext = 0; + menuSpec->accelKeySpecs = NULL; +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + menuSpec->exclusions = NULL; + menuSpec->clientLocal = FALSE; + menuSpec->commandID = 0; +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + menuSpec->nextMenuSpec = NULL; + + /* + * Allocate and fill space for the menu name. + */ + + if ((menuSpec->name = + (String)XtMalloc ((unsigned int) (strlen ((char *)string) + 1))) + == NULL) + { + PWarning (((char *)GETMESSAGE(60, 10, "Insufficient memory for menu"))); + XtFree ((char *)menuSpec); + return; + } + strcpy (menuSpec->name, (char *)string); + + /* + * Add the empty structure to the head of the menu specification list. + */ + + menuSpec->nextMenuSpec = pSD->menuSpecs; + pSD->menuSpecs = menuSpec; + + /* + * Require leading '{' on the next line. + */ + + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace(&lineP); + + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment line */ + { + continue; + } + + if (*lineP == '{') + /* found '{' */ + { + break; + } + + /* not a '{' */ + PWarning (((char *)GETMESSAGE(60, 11, "Expected '{' after menu name"))); + return; + } + + /* + * Found leading "{" or EOF. + * Parse menu item specifications until "}" or EOF found. + */ + + menuSpec->menuItems = PARSE_MENU_ITEMS (pSD, menuSpec); + +} /* END OF FUNCTION ParseMenuSet */ + + +/*************************************<->************************************* + * + * MenuItem * + * ParseMwmMenuStr (pSD, menuStr) + * + * + * Description: + * ----------- + * This function parses a WMW_MENU string and returns a list of + * MenuItems structures. The string should have the syntax: + * + * label [mnemonic] [accelerator] function + * label [mnemonic] [accelerator] function + * ... + * label [mnemonic] [accelerator] function + * + * + * Inputs: + * ------ + * line = (global) line buffer + * pSD->rootWindow = default root window of display + * wmGD.bitmapDirectory = bitmapDirectory resource value + * HOME = environment variable for home directory + * functionTable = window manager function parse table + * + * + * Outputs: + * ------- + * Return = list of MenuItem structures or NULL + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +MenuItem *ParseMwmMenuStr (WmScreenData *pSD, unsigned char *menuStr) +{ + + cfileP = NULL; + linec = 0; + parseP = menuStr; + + return (PARSE_MENU_ITEMS (pSD, NULL)); + +} /* END OF FUNCTION ParseMwmMenuStr */ + + +/*************************************<->************************************* + * + * static MenuItem * + * ParseMenuItems (pSD, menuSpec) + * + * + * Description: + * ----------- + * Parse menu item specifications: + * + * label [mnemonic] [accelerator] function + * label [mnemonic] [accelerator] function + * ... + * label [mnemonic] [accelerator] function + * [}] + * + * + * Inputs: + * ------ + * pSD = pointer to screen data + * cfileP = (global) file pointer to fopened configuration file or NULL + * line = (global) line buffer + * linec = (global) line count + * parseP = (global) parse string pointer if cfileP == NULL + * pSD->rootWindow = default root window of display + * wmGD.bitmapDirectory = bitmapDirectory resource value + * HOME = environment variable for home directory + * + * + * Outputs: + * ------- + * linec = (global) line count incremented + * parseP = (global) parse string pointer if cfileP == NULL + * Return = list of MenuItem structures or NULL + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static MenuItem *ParseMenuItems (WmScreenData *pSD +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + , MenuSpec *menuSpec +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + ) +{ + unsigned char *string; + unsigned char *lineP; + MenuItem *firstMenuItem; + MenuItem *lastMenuItem; + MenuItem *menuItem; + register int ix; +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + Boolean use_separators = False; +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + + /* + * Parse "label [mnemonic] [accelerator] function" or + * "[.]*" + * lines until "}" or EOF found. + */ + + firstMenuItem = lastMenuItem = NULL; + while ((GetNextLine () != NULL)) + { + lineP = line; + if ((*line == '!') || (*line == '#') || (string = GetString (&lineP)) == NULL) + /* ignore empty or comment lines */ + { + continue; + } + if (*string == '}') /* finished with menu set. */ + { + break; + } + + /* + * Allocate space for the menu item structure. + */ + + if ((menuItem = (MenuItem *)XtMalloc (sizeof (MenuItem))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 12, "Insufficient memory for menu item"))); + continue; + } + menuItem->nextMenuItem = NULL; + menuItem->wmFunction = (WmFunction)NULL; + menuItem->wmFuncArgs = NULL; +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + menuItem->clientCommandName = NULL; + menuItem->clientCommandID = 0; +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + +#if ((!defined(WSM)) || 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + { + /* + * Parse the menu item label. + */ + if (!ParseWmLabel (pSD, menuItem, string)) + { + XtFree ((char *)menuItem); + continue; + } + } + + /* + * Parse any menu function mnemonic. + */ + + ParseWmMnemonic (&lineP, menuItem); + + /* + * Parse any menu function accelerator. + */ + + if (!ParseWmAccelerator (&lineP, menuItem)) + { + FreeMenuItem (menuItem); + continue; + } + /* + * Parse the menu function name if this is not a client + * command. If it is a client command, then the wmFunction + * field should already be set, as well as the ix variable, + * 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(WSM)) || defined(MWM_QATS_PROTOCOL)) + if (menuItem->wmFunction != NULL) + ParseMenuItemName(&lineP, menuItem); + else +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + ix = ParseWmFunction (&lineP, CRS_MENU, &menuItem->wmFunction); + + /* + * Determine context sensitivity and applicability mask. + */ + + menuItem->greyedContext = functionTable[ix].greyedContext; + menuItem->mgtMask = functionTable[ix].mgtMask; +#ifdef PANELIST + if ((menuItem->wmFunction == F_Toggle_Front_Panel) && + ((wmGD.useFrontPanel == False) || + (wmGD.dtSD != pSD))) + { + /* + * disallow this function if there's no front + * panel on this screen. + */ + menuItem->greyedContext |= (F_CONTEXT_ALL | + F_SUBCONTEXT_IB_WICON | + F_SUBCONTEXT_IB_IICON); + } +#endif /* PANELIST */ + + /* + * Apply the function argument parser. + */ + if (!(*(functionTable [ix].parseProc)) + (&lineP, menuItem->wmFunction, &menuItem->wmFuncArgs)) + { + FreeMenuItem (menuItem); + continue; /* skip this menu item */ + } + +#if ((!defined(WSM)) || 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + + /* + * Add this item to the menu specification. + */ + + if (lastMenuItem != NULL) /* not first */ + { + lastMenuItem->nextMenuItem = menuItem; + } + else + { + firstMenuItem = menuItem; + } + lastMenuItem = menuItem; + +#if ((!defined(WSM)) || 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + } + + return (firstMenuItem); + +} /* END OF FUNCTION ParseMenuItems */ + + + +#if ((!defined(WSM)) || 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; +} + + +/*************************************<->************************************* + * + * 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 (( +#ifndef NO_MULTIBYTE + mblen ((char *)string, MB_CUR_MAX) == 1 && +#endif + *string == '<') || + (strncmp(string, "-><", 3) == 0) || + (strncmp(string, "=<", 2) == 0) || + (strncmp(string, "=><", 3) == 0) || + (strncmp(string, "~<", 2) == 0)) + return(TRUE); + + return(FALSE); +} + + +/*************************************<->************************************* + * + * 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) + { +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + + 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; +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + 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; +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + 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. */ +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + while ( +#ifndef NO_MULTIBYTE + mblen ((char *)stream, MB_CUR_MAX) == 1 && +#endif + (*stream == ' ' || *stream == '\t')) + ++stream; + +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + /* Now check for a reference name wild card or a + full reference name */ + if (*stream == '*') + ++stream; + else + { + while ( +#ifndef NO_MULTIBYTE + mblen ((char *)stream, MB_CUR_MAX) == 1 && +#endif + (isalnum(*stream) || *stream == ' ' || + *stream == '\t' || *stream == '_' )) + ++stream; + } + +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + + /* Now skip past any trailing white space */ + while ( +#ifndef NO_MULTIBYTE + mblen ((char *)stream, MB_CUR_MAX) == 1 && +#endif + (*stream == ' ' || *stream == '\t')) + ++stream; + +#ifndef NO_MULTIBYTE + if (mblen ((char *)stream, MB_CUR_MAX) > 1) { + token = PRS_ERROR; + continue; + } +#endif + /* 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + + +/*************************************<->************************************* + * + * ParseWmLabel (pSD, menuItem, string) + * + * + * Description: + * ----------- + * Parse a menu label string. + * + * + * Inputs: + * ------ + * pSD = pointer to screen data + * menuItem = pointer to MenuItem structure + * string = label string + * + * + * Outputs: + * ------- + * menuItem->label + * menuItem->labelType + * menuItem->labelBitmapCache + * Return = boolean, FALSE iff insufficient memory + * + * + * Comments: + * -------- + * We have two label types: XmSTRING and XmPIXMAP + * We allocate and fill the label field with string and set the type to + * XmSTRING. If string = "@", and contains a + * with which to build a label image we save the bitmap in the MenuItem + * structure and set the type to XmPIXMAP. + * + *************************************<->***********************************/ + +static Boolean ParseWmLabel (WmScreenData *pSD, MenuItem *menuItem, + unsigned char *string) +{ + + /* + * Allocate the label field and copy string. + */ + + if ((menuItem->label = (String) + XtMalloc ((unsigned int)(strlen ((char *)string) + 1))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 13, "Insufficient memory for menu item"))); + return (FALSE); + } + + strcpy (menuItem->label, (char *)string); + menuItem->labelType = XmSTRING; + + if (*string == '@') + /* + * Here: string = "@" + * Try to find the label bitmap in the bitmap cache or read the label + * bitmap file. + */ + { + string++; /* skip "@" */ +#ifdef WSM + if ((menuItem->labelBitmapIndex = GetBitmapIndex (pSD, + (char *)string, True)) >= 0) +#else /* WSM */ + if ((menuItem->labelBitmapIndex = GetBitmapIndex (pSD, + (char *)string)) >= 0) +#endif /* WSM */ + { + menuItem->labelType = XmPIXMAP; + } + } + return (TRUE); + +} /* END OF FUNCTION ParseWmLabel */ + + + +/*************************************<->************************************* + * + * ParseWmMnemonic (linePP, menuItem) + * + * + * Description: + * ----------- + * Parse an optional menu function mnemonic. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * menuItem = pointer to MenuItem structure + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * menuItem->mnemonic = valid mnemonic character or NULL. + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static void ParseWmMnemonic (unsigned char **linePP, MenuItem *menuItem) +{ + unsigned char *lineP = *linePP; + unsigned char *mnemonic; + + /* + * Skip leading white space. + */ + ScanWhitespace (&lineP); + menuItem->mnemonic = (KeySym)NULL; + + if (*lineP == '_') + /* + * We have a mnemonic specification. + * Get the next string (we only use the first character). + * If no string exists, the labelType is not XmSTRING, or does not contain + * the first character, then skip the string and return. + * Otherwise, accept the first character as a mnemonic. + */ + { + KeySym ks; + lineP++; + mnemonic = GetString(&lineP); + +#ifndef NO_MULTIBYTE + if (menuItem->labelType == XmSTRING && + mnemonic != NULL && + (ks = XStringToKeysym((char *)mnemonic)) != NoSymbol && + strchr(menuItem->label, (char)(ks & 0xff)) != NULL) + { + menuItem->mnemonic = ks; + } +#else + if ((mnemonic != NULL) && + (*mnemonic != '\0') && + (menuItem->labelType == XmSTRING) && + (strchr (menuItem->label, *mnemonic) != NULL)) + /* valid mnemonic */ + { + menuItem->mnemonic = *mnemonic; + } +#endif + else + { + PWarning (((char *)GETMESSAGE(60, 14, "Invalid mnemonic specification"))); + } + } + + *linePP = lineP; /* consume any string */ + +} /* END OF FUNCTION ParseWmMnemonic */ + + +/*************************************<->************************************* + * + * ParseWmAccelerator (linePP, menuItem) + * + * + * Description: + * ----------- + * Parse an optional menu function accelerator. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * menuItem = pointer to MenuItem structure + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * menuItem->accelText = pointer to an accelerator string or NULL. + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseWmAccelerator (unsigned char **linePP, MenuItem *menuItem) +{ + unsigned char *lineP; + String string; + unsigned int eventType; + unsigned int state; + KeyCode keycode; + Boolean status; + + menuItem->accelState = 0; + menuItem->accelKeyCode = 0; + menuItem->accelText = NULL; + status = TRUE; + + /* + * If linePP contains NULL, then abort. + */ + if (*linePP == (unsigned char *) NULL) return(FALSE); + + /* + * Skip leading white space. + */ + ScanWhitespace (linePP); + lineP = *linePP; + + /* + * If the second character is not ".", and an accelerator specification + * exists, then process and save the specification string. + */ + + if ((*lineP != '\0') && /* something follows */ + (*lineP != '!') && /* skip if we have the ! WmFunction */ +#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) + /* skip label name for client command */ + ((*lineP != '"') || (menuItem->wmFunction != F_InvokeCommand)) && +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + (*lineP != 'f') && + (*(lineP+1) != '.')) /* skip if we have f.xxx WmFunction */ + { + if (ParseKeyEvent(&lineP, &eventType, &keycode, &state)) + { + if ((string = (String) XtMalloc + ((unsigned int) (lineP - *linePP + 1))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 15, "Insufficient memory for accelerator specification"))); + status = FALSE; + } + else + /* + * Save the accelerator state and keycode. + * Process and save the accelerator text. + */ + { + ProcessAccelText (*linePP, lineP, (unsigned char *) string); + menuItem->accelState = state; + menuItem->accelKeyCode = keycode; + menuItem->accelText = string; + } + } + else + { + PWarning (((char *)GETMESSAGE(60, 16, "Invalid accelerator specification"))); + status = FALSE; + } + + *linePP = lineP; /* consume the specification */ + } + + return (status); + +} /* END OF FUNCTION ParseWmAccelerator */ + + +#if ((!defined(WSM)) || 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; +#ifndef NO_MULTIBYTE + int chlen; +#endif + + /* Skip past any whitespace */ + ScanWhitespace (linePP); + lineP = *linePP; + + /* Look for a double quote */ + if ( +#ifndef NO_MULTIBYTE + mblen ((char *)lineP, MB_CUR_MAX) == 1 && +#endif + *lineP == '"') + { + /* Move past the first quote. */ + ++lineP; + + endquote = lineP; + + /* Search for closing quote */ +#ifndef NO_MULTIBYTE + 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 */ +#else + while (*endquote != '\0' && *endquote != '"') { + if (*endquote == '\n' || *endquote == '\0') return; + endquote++; + } +#endif + + /* 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. */ +#ifndef NO_MULTIBYTE + while (*lineP != '\0' && + ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) > 1 || + *lineP != '\n')) + lineP += chlen > 0 ? chlen : 1; +#else + while (*lineP != '\0' && *lineP != '\n') + lineP++; +#endif + *linePP = lineP; + } +} +#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ + + +/*************************************<->************************************* + * + * int + * ParseWmFunction (linePP, res_spec, pWmFunction) + * + * + * Description: + * ----------- + * Parse a button, key, or menu function name and return its function table + * index. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * res_spec = resource specification type (key, button, or menu). + * pWmFunction = pointer to window manager function destination. + * functionTable = window manager function parse table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * pWmFunction = pointer to parsed window manager function. + * Return = function table index of parsed function. + * + * + * Comments: + * -------- + * Uses F_Nop if the function name or resource type is invalid. + * + *************************************<->***********************************/ + +int ParseWmFunction (unsigned char **linePP, unsigned int res_spec, + WmFunction *pWmFunction) +{ + unsigned char *lineP = *linePP; + unsigned char *string; + register int low, mid, high, cmp; + + /* + * Skip leading white space. + */ + ScanWhitespace (&lineP); + + /* + * Have function string (may be NULL or a comment). + * Handle the special case of '!' + */ + + if (*lineP == '!') + { + *linePP = ++lineP; + *pWmFunction = F_Exec; + return (F_EXEC_INDEX); + } + + /* + * Identify the function corresponding to the specified name. + * Try binary search of the window manager function parse table. + * Assume f.nop if the function and resource type cannot be matched. + * This handles NULL and comment strings, bad function names, and functions + * in inappropriate resource sets. + */ + string = GetString (&lineP); + *linePP = lineP; + + if (string != NULL) + { + ToLower (string); + low = 0; + high = WMFUNCTIONTABLESIZE - 1; + + while (low <= high) + { + mid = (low + high)/2; + cmp = strcmp (functionTable[mid].funcName, (char *)string); + + if (!cmp) + /* + * Function name match + * Require proper resource type for the function. + */ + { + if (res_spec & functionTable[mid].resource) + { + *pWmFunction = functionTable[mid].wmFunction; + return (mid); + } + + /* invalid resource: use F_Nop */ + break; + } + + /* + * Function name mismatch + */ + if (cmp > 0) + { + high = mid - 1; + } + else + { + low = mid + 1; + } + } + } + + /* + * Not found: assume f.nop + */ + *pWmFunction = F_Nop; + return (F_NOP_INDEX); + +} /* END OF FUNCTION ParseWmFunction */ + + +/*************************************<->************************************* + * + * ParseWmFuncMaybeStrArg (linePP, wmFunction, pArgs) + * + * + * Description: + * ----------- + * Parses a window manager function with a null or string argument. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * wmFunction = function (not used). + * pArgs = pointer to argument destination. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * pArgs = pointer to parsed argument string. + * Return = FALSE iff insufficient memory + * + * + * Comments: + * -------- + * Only used to parse arguments for F_Lower, F_Raise, and F_Raise_Lower. + * If it is used for any other function, be sure to change FreeMenuItem () + * accordingly. + * + *************************************<->***********************************/ + +#ifndef PANELIST +static +#endif +Boolean ParseWmFuncMaybeStrArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs) +{ + unsigned char *string = *linePP; + unsigned int len; + + ScanWhitespace (&string); +/* + if (*lineP == '-') + { + *linePP = ++lineP; + return (ParseWmFuncStrArg (linePP, wmFunction, pArgs)); + } +*/ +#ifdef PANELIST +#if 0 + else if (*lineP == '"' && *(lineP+1) == '-') + { + /* kill off '-' */ + strcpy ((char *) (lineP+1), (char *) (lineP+2)); + return (ParseWmFuncStrArg (linePP, wmFunction, pArgs)); + } +#endif +#endif /* PANELIST */ + if ((len = strlen ((char *)string)) != 0) + { + if ((*pArgs = (String)XtMalloc (len + 1)) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 17, "Insufficient memory"))); + return (FALSE); + } + strcpy (*pArgs, (char *)string); + return (TRUE); + } + else + /* Do ParseWmFuncNoArg () */ + { + *pArgs = NULL; + return (TRUE); + } + +} /* END OF FUNCTION ParseWmFuncMaybeStrArg */ + + +/*************************************<->************************************* + * + * ParseWmFuncNoArg (linePP, wmFunction, pArgs) + * + * + * Description: + * ----------- + * Parses a window manager function null argument. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * wmFunction = function (not used). + * pArgs = pointer to argument destination. + * + * + * Outputs: + * ------- + * linePP = unchanged + * pArgs = NULL + * Return = TRUE + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseWmFuncNoArg (unsigned char **linePP, WmFunction wmFunction, + String *pArgs) +{ + + *pArgs = NULL; + return (TRUE); + +} /* END OF FUNCTION ParseWmFuncNoArg */ + + +/*************************************<->************************************* + * + * ParseWmFuncStrArg (linePP, wmFunction, pArgs) + * + * + * Description: + * ----------- + * Parses a window manager function string argument. + * + * + * 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: + * -------- + * Insures that an argument for F_Exec() ends in '&' . + * Only used to parse arguments for F_Exec, F_Menu, F_Lower, F_Raise, + * F_Raise_Lower, and F_Screen. If it is used for any other function, be + * sure to change FreeMenuItem () accordingly. + * + *************************************<->***********************************/ + +#ifndef PANELIST +static +#endif +Boolean ParseWmFuncStrArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs) +{ + unsigned char *string; + unsigned int len; +#ifndef NO_MULTIBYTE + char *p; + wchar_t last; + char delim; + wchar_t wdelim; + int lastlen; +#endif + + if ((string = GetString (linePP)) != NULL) + /* nonNULL string argument */ + { + len = strlen ((char *)string); + if ((*pArgs = (String)XtMalloc (len + 2)) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 17, "Insufficient memory"))); + return (FALSE); + } + strcpy (*pArgs, (char *)string); + + /* + * Insure that an argument for F_Exec ends in '&' . + */ + +#ifndef NO_MULTIBYTE + if ((wmFunction == F_Exec)) + { + lastlen = 0; + p = *pArgs; + while (*p && + ((len = mblen(p, MB_CUR_MAX)) > 0)) + { + mbtowc(&last, p, MB_CUR_MAX); + lastlen = len; + p += len; + } + delim = '&'; + mbtowc(&wdelim, &delim, MB_CUR_MAX); + if (lastlen == 1 && last != wdelim) + { + *p++ = '&'; + *p = '\0'; + } + } +#else + if ((wmFunction == F_Exec) && ((*pArgs)[len - 1] != '&')) + { + (*pArgs)[len] = '&'; + (*pArgs)[len + 1] = '\0'; + } +#endif + } + else + /* NULL string argument */ + { + *pArgs = NULL; + } + + return (TRUE); + +} /* END OF FUNCTION ParseWmFuncStrArg */ + + +/*************************************<->************************************* + * + * FreeMenuItem (menuItem) + * + * + * Description: + * ----------- + * This procedure destroys a MenuItem structure. + * + * + * Inputs: + * ------ + * menuItem = to be destroyed. + * + * + * Outputs: + * ------- + * None. + * + * + * Comments: + * -------- + * Assumes that ParseWmFuncStrArg () has parsed a menu item's function + * argument only for F_Exec, F_Menu, F_Lower, F_Raise, F_Raise_Lower, and + * F_Screen. If it is used for other functions, be sure to include them here! + * + *************************************<->***********************************/ + +void FreeMenuItem (MenuItem *menuItem) +{ + if (menuItem->label != NULL) + { + XtFree ((char *)menuItem->label); + } + + if (menuItem->accelText != NULL) + { + XtFree ((char *)menuItem->accelText); + } + + /* + * If menuItem->wmFuncArgs is nonNULL, we assume that it is a string that + * was malloc'ed in ParseWmFuncStrArg () and we free it now. + */ + if ((menuItem->wmFuncArgs != NULL) && + ((menuItem->wmFunction == F_Exec) || + (menuItem->wmFunction == F_Menu) || + (menuItem->wmFunction == F_Lower) || + (menuItem->wmFunction == F_Raise) || + (menuItem->wmFunction == F_Raise_Lower) || + (menuItem->wmFunction == F_Screen))) + { + XtFree ((char *)menuItem->wmFuncArgs); + } + + if (menuItem->clientCommandName != NULL) + { + XtFree ((char *) menuItem->clientCommandName); + } + + XtFree ((char *)menuItem); + +} /* END OF FUNCTION FreeMenuItem */ + + + +/*************************************<->************************************* + * + * ParseWmFuncGrpArg (linePP, wmFunction, pGroup) + * + * + * Description: + * ----------- + * Parses a window manager function group argument. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * wmFunction = function for which the group argument is intended. + * pGroup = pointer to group argument destination. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * pGroup = pointer to parsed group argument. + * Return = FALSE iff invalid group argument. + * + * + * Comments: + * -------- + * The only valid nonNULL arguments are "icon", "window", and "transient". + * + *************************************<->***********************************/ + +static Boolean ParseWmFuncGrpArg (unsigned char **linePP, + WmFunction wmFunction, GroupArg *pGroup) +{ + unsigned char *lineP = *linePP; + unsigned char *startP; + unsigned char grpStr[MAX_GROUP_STRLEN+1]; + int len; + + + /* + * Parse groups while each is followed by "|". + */ + + *pGroup = 0; + while (1) + { + /* + * Skip whitespace and find next group string. + */ + + ScanWhitespace (&lineP); + startP = lineP; + ScanAlphanumeric (&lineP); + if (startP == lineP) + /* Group missing => use default or complain */ + { + if (*pGroup) + { + PWarning (((char *)GETMESSAGE(60, 18, "Missing group specification"))); + return (FALSE); + } + else + { + *pGroup = F_GROUP_DEFAULT; + break; + } + } + + /* + * Found a group string; compare it with valid groups. + */ + + len = min (lineP - startP, MAX_GROUP_STRLEN); + (void) strncpy ((char *)grpStr, (char *)startP, len); + grpStr[len] = '\0'; + ToLower (grpStr); + + if (!strcmp ("icon", (char *)grpStr)) + { + *pGroup |= F_GROUP_ICON; + } + else if (!strcmp ("window", (char *)grpStr)) + { + *pGroup |= F_GROUP_WINDOW; + } + else if (!strcmp ("transient", (char *)grpStr)) + { + *pGroup |= F_GROUP_TRANSIENT; + } + else + /* Unknown group name */ + { + PWarning (((char *)GETMESSAGE(60, 19, "Invalid group specification"))); + return (FALSE); + } + + /* + * Continue processing until the line is exhausted. + * Skip any '|' . + */ + + ScanWhitespace (&lineP); + + if (lineP == NULL || *lineP == '\0') + { + break; + } + else if (*lineP == '|') + { + lineP++; + } + } + + *linePP = lineP; + return (TRUE); + +} /* END OF FUNCTION ParseWmFuncGrpArg */ + + + +/*************************************<->************************************* + * + * ParseWmFuncNbrArg (linePP, wmFunction, pNumber) + * + * + * Description: + * ----------- + * Parses a window manager function number argument. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * wmFunction = function + * pNumber = pointer to number argument destination. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * pNumber = pointer to parsed number argument. + * Return = FALSE iff invalid number argument. + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseWmFuncNbrArg (unsigned char **linePP, + WmFunction wmFunction, + unsigned long *pNumber) +{ + int val; + + val = StrToNum (GetString (linePP)); + if (val == -1) + { + PWarning (((char *)GETMESSAGE(60, 20, "Invalid number specification"))); + *pNumber = 0; + return (FALSE); + } + + *pNumber = val; + return (TRUE); + +} /* END OF FUNCTION ParseWmFuncNbrArg */ + + +#if ((!defined(WSM)) || 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + + +/*************************************<->************************************* + * + * ParseButtonStr () + * + * + * Description: + * ----------- + * This function parses a button set specification string: + * + * bindings_name + * { + * button context function + * button context function + * ... + * button context function + * } + * + * + * + * Inputs: + * ------ + * pSD->buttonBindings = buttonBindings resource value + * functionTable = window manager function parse table + * + * + * Outputs: + * ------- + * pSD->buttonSpecs = list of button binding specifications. + * + * + * Comments: + * -------- + * The button set specification name must match pSD->buttonBindings. + * + *************************************<->***********************************/ + +void ParseButtonStr (WmScreenData *pSD, unsigned char *buttonStr) +{ + unsigned char *lineP; + + cfileP = NULL; + linec = 0; + if (((parseP = buttonStr) != NULL) && (GetNextLine () != NULL)) + { + lineP = line; + ParseButtonSet (pSD, lineP); + } + +} /* END OF FUNCTION ParseButtonStr */ + + +/*************************************<->************************************* + * + * ParseButtonSet (pSD, lineP) + * + * + * Description: + * ----------- + * Button set specification found. Parse the following syntax: + * + * v + * Buttons bindings_name + * { + * button context function + * button context function + * ... + * button context function + * } + * + * + * Inputs: + * ------ + * cfileP = (global) file pointer to fopened configuration file or NULL + * line = (global) line buffer + * lineP = pointer to current character in line buffer + * pSD->buttonBindings = buttonBindings resource value + * + * + * Outputs: + * ------- + * lineP = pointer to current character in line buffer + * pSD->buttonSpecs = list of button binding specifications. + * + * + * Comments: + * -------- + * Skips unnamed button binding set and sets with names that don't match + * the buttonBindings resource. + * Skips bad button binding specifications. + * + *************************************<->***********************************/ + +static void ParseButtonSet (WmScreenData *pSD, unsigned char *lineP) +{ + unsigned char *string; + ButtonSpec *buttonSpec; + ButtonSpec *lastButtonSpec; + int ix; + + /* + * Parse the button set bindings from the configuration file. + * If either the button set name or buttonBindings resource is NULL or + * they don't match, then skip this button specification. + */ + + if (((string = GetString (&lineP)) == NULL) || + (pSD->buttonBindings == NULL) || + strcmp ((char *)string, pSD->buttonBindings)) + { + return; + } + + /* + * Require leading '{' on the next line. + */ + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace(&lineP); + + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment line */ + { + continue; + } + + if (*lineP == '{') + /* found '{' */ + { + break; + } + + /* not a '{' */ + PWarning (((char *)GETMESSAGE(60, 21, "Expected '{' after button set name"))); + return; + } + + /* + * Found leading "{" or EOF. + * Prepare to accumulate button bindings by finding the end of + * the button specification list. + * lastButtonSpec will be NULL only if no prior bindings exist. + */ + + lastButtonSpec = pSD->buttonSpecs; + if (lastButtonSpec != NULL) + { + while (lastButtonSpec->nextButtonSpec != NULL) + { + lastButtonSpec = (lastButtonSpec->nextButtonSpec); + } + } + + /* + * Parse "button context function" until "}" or EOF found. + * Skips bad button binding specifications. + */ + + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace(&lineP); + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment lines */ + { + continue; + } + if (*lineP == '}') /* finished with button set */ + { + break; + } + + /* + * Allocate space for the button binding specification. + */ + if ((buttonSpec = (ButtonSpec *)XtMalloc (sizeof (ButtonSpec))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 22, "Insufficient memory for button specification"))); + continue; + } + buttonSpec->wmFunction = (WmFunction)NULL; + buttonSpec->wmFuncArgs = NULL; + buttonSpec->nextButtonSpec = NULL; + + /* + * Parse the button specification "button". + */ + lineP = line; + if (!ParseBtnEvent(&lineP, + &buttonSpec->eventType, + &buttonSpec->button, + &buttonSpec->state, + &buttonSpec->click)) + { + PWarning (((char *)GETMESSAGE(60, 23, "Invalid button specification"))); + XtFree ((char *)buttonSpec); + continue; /* skip this button specification */ + } + + + /* + * Parse the button context. + */ + if (!ParseContext(&lineP, &buttonSpec->context, + &buttonSpec->subContext)) + { + PWarning (((char *)GETMESSAGE(60, 24, "Invalid button context"))); + XtFree ((char *)buttonSpec); + continue; /* skip this button specification */ + } + + /* + * Parse the button function and any arguments. + */ + + ix = ParseWmFunction (&lineP, CRS_BUTTON, &buttonSpec->wmFunction); + + /* + * remove any subContexts that don't apply to this function + */ + + if ((functionTable[ix].greyedContext & F_SUBCONTEXT_IB_IICON) && + (buttonSpec->subContext & F_SUBCONTEXT_IB_IICON)) + { + buttonSpec->subContext &= ~F_SUBCONTEXT_IB_IICON; + } + + if ((functionTable[ix].greyedContext & F_SUBCONTEXT_IB_WICON) && + (buttonSpec->subContext & F_SUBCONTEXT_IB_WICON)) + { + buttonSpec->subContext &= ~F_SUBCONTEXT_IB_WICON; + } + + /* + * Map Button3 menus to BMenu virtual button + */ + if (buttonSpec->button == Button3 && + (buttonSpec->wmFunction == F_Menu || + buttonSpec->wmFunction == F_Post_SMenu)) { + + buttonSpec->button = wmGD.bMenuButton; + } + + /* + * Apply the function argument parser. + */ + if (!(*(functionTable [ix].parseProc)) + (&lineP, buttonSpec->wmFunction, &buttonSpec->wmFuncArgs)) + { + XtFree ((char *)buttonSpec); + continue; /* skip this button specification */ + } + + /* + * Add the button specification to the button specification list. + */ + if (lastButtonSpec != NULL) + /* a prior specification exists */ + { + lastButtonSpec->nextButtonSpec = buttonSpec; + } + else + { + pSD->buttonSpecs = buttonSpec; + } + lastButtonSpec = buttonSpec; + } + +} /* END OF FUNCTION ParseButtonSet */ + + + +/*************************************<->************************************* + * + * ParseContext (linePP, context, subContext) + * + * + * Description: + * ----------- + * Parses a general context string. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * context = context field value + * subContext = subContext field value + * Return = (Boolean) true iff valid context string + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseContext (unsigned char **linePP, Context *context, + Context *subContext) +{ + unsigned char *lineP = *linePP; + unsigned char *startP; + unsigned char ctxStr[MAX_CONTEXT_STRLEN+1]; + int len; + + /* + * Parse contexts while each is followed by "|". + */ + + *context = 0; + *subContext = 0; + while (1) { + + /* + * Skip whitespace and find next context string. + */ + ScanWhitespace (&lineP); + startP = lineP; + ScanAlphanumeric (&lineP); + if (startP == lineP) + /* ERROR: Context missing */ + { + return (FALSE); + } + + /* + * Found nonNULL string; compare it with valid contexts. + */ + + len = min(lineP - startP, MAX_CONTEXT_STRLEN); + (void) strncpy ((char *)ctxStr, (char *)startP, len); + ctxStr[len] = '\0'; + ToLower (ctxStr); + + if (!strcmp ("root", (char *)ctxStr)) + { + *context |= F_CONTEXT_ROOT; + *subContext |= F_SUBCONTEXT_R_ALL; + } + else if (!strcmp ("icon", (char *)ctxStr)) + { + *context |= (F_CONTEXT_ICON | + F_CONTEXT_ICONBOX | + F_SUBCONTEXT_IB_IICON | + F_SUBCONTEXT_IB_WICON ); + *subContext |= (F_SUBCONTEXT_I_ALL | + F_SUBCONTEXT_IB_IICON | + F_SUBCONTEXT_IB_WICON ); + } + else if (!strcmp ("window", (char *)ctxStr)) + { + *context |= F_CONTEXT_WINDOW; + *subContext |= F_SUBCONTEXT_W_ALL; + } + else if (!strcmp ("frame", (char *)ctxStr)) + { + *context |= F_CONTEXT_WINDOW; + *subContext |= F_SUBCONTEXT_W_FRAME; + } + else if (!strcmp ("title", (char *)ctxStr)) + { + *context |= F_CONTEXT_WINDOW; + *subContext |= F_SUBCONTEXT_W_TITLE; + } + else if (!strcmp ("border", (char *)ctxStr)) + { + *context |= F_CONTEXT_WINDOW; + *subContext |= F_SUBCONTEXT_W_BORDER; + } + else if (!strcmp ("app", (char *)ctxStr)) + { + *context |= F_CONTEXT_WINDOW; + *subContext |= F_SUBCONTEXT_W_APP; + } +#ifdef WSM + else if (!strcmp ("ifkey", (char *)ctxStr)) + { + *context |= F_CONTEXT_IFKEY; + } +#endif /* WSM */ + else + /* Unknown context name */ + { + return (FALSE); + } + + /* continue only if followed by '|' */ + ScanWhitespace (&lineP); + if (*lineP != '|') + { + break; + } + lineP++; + } + + *linePP = lineP; + return (TRUE); + +} /* END OF FUNCTION ParseContext */ + + +/*************************************<->************************************* + * + * ParseKeyStr () + * + * + * Description: + * ----------- + * This function parses a key set specification string: + * + * bindings_name + * { + * key context function + * key context function + * ... + * key context function + * } + * + * + * Inputs: + * ------ + * pSD->keyBindings = keyBindings resource value + * functionTable = window manager function parse table + * + * + * Outputs: + * ------- + * pSD->keySpecs = list of key binding specification + * + * + * Comments: + * -------- + * The key set specification name must match pSD->keyBindings. + * + *************************************<->***********************************/ + +void +ParseKeyStr (WmScreenData *pSD, unsigned char *keyStr) +{ + unsigned char *lineP; + + cfileP = NULL; + linec = 0; + if (((parseP = keyStr) != NULL) && (GetNextLine () != NULL)) + { + lineP = line; + ParseKeySet (pSD, lineP); + } + +} /* END OF FUNCTION ParseKeyStr */ + + + +/*************************************<->************************************* + * + * ParseKeySet (pSD, lineP) + * + * + * Description: + * ----------- + * Key set specification found. Parse the following syntax: + * + * v + * Keys bindings_name + * { + * key context function + * key context function + * ... + * key context function + * } + * + * + * Inputs: + * ------ + * cfileP = (global) file pointer to fopened configuration file or NULL + * line = (global) line buffer + * lineP = pointer to current character in line buffer + * pSD->keyBindings = keyBindings resource value + * + * + * Outputs: + * ------- + * lineP = pointer to current character in line buffer + * pSD->keySpecs = list of key binding specifications. + * + * + * Comments: + * -------- + * Skips unnamed key binding set and sets with names that don't match the + * keyBindings resource. + * Skips bad key binding specifications. + * + *************************************<->***********************************/ + +static void ParseKeySet (WmScreenData *pSD, unsigned char *lineP) +{ + unsigned char *string; + KeySpec *keySpec; + KeySpec *lastKeySpec; + unsigned int eventType; + int ix; +#ifdef WSM + Boolean bBadKey; +#endif /* WSM */ + + /* + * Parse the key set bindings from the configuration file. + * If either the key set name or keyBindings resource is NULL or they + * don't match then skip this key specification. + */ + + if (((string = GetString (&lineP)) == NULL) || + (pSD->keyBindings == NULL) || + strcmp ((char *)string, pSD->keyBindings)) + { + return; + } + + /* + * Require leading '{' on next line. + */ + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace(&lineP); + + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment line */ + { + continue; + } + + if (*lineP == '{') + /* found '{' */ + { + break; + } + + /* not a '{' */ + PWarning (((char *)GETMESSAGE(60, 25, "Expected '{' after key set name"))); + return; + } + + /* + * Found leading "{" or EOF. + * Prepare to accumulate key bindings by finding the end of + * the key specification list. + * lastKeySpec will be NULL only if no prior bindings exist. + */ + + lastKeySpec = pSD->keySpecs; + if (lastKeySpec != NULL) + { + while (lastKeySpec->nextKeySpec != NULL) + { + lastKeySpec = (lastKeySpec->nextKeySpec); + } + } + + /* + * Parse "key context function" until "}" or EOF found. + * Skip bad key bindings. + */ + + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace (&lineP); + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment lines */ + { + continue; + } + if (*lineP == '}') /* finished with key set */ + { + break; + } + + /* + * Allocate space for the key specification. + */ + if ((keySpec = (KeySpec *)XtMalloc (sizeof (KeySpec))) == NULL) + { + PWarning (((char *)GETMESSAGE(60, 26, "Insufficient memory for key specification"))); + continue; + } + + keySpec->wmFunction = (WmFunction)NULL; + keySpec->wmFuncArgs = NULL; + keySpec->nextKeySpec = NULL; + + /* + * Parse the key specification. + */ +#ifdef WSM + bBadKey = False; +#endif /* WSM */ + if (!ParseKeyEvent(&lineP, + &eventType, + &keySpec->keycode, + &keySpec->state)) + { +#ifdef WSM + bBadKey = True; +#else /* WSM */ + PWarning (((char *)GETMESSAGE(60, 27, "Invalid key specification"))); + XtFree ((char *)keySpec); + continue; /* skip this key specification */ +#endif /* WSM */ + } + + /* + * Parse the key context. + * Here lineP points to the candidate context string. + */ + + if (!ParseContext(&lineP, &keySpec->context, + &keySpec->subContext)) + { +#ifdef WSM + if (bBadKey) + PWarning (((char *)GETMESSAGE(60, 27, "Invalid key specification"))); +#endif /* WSM */ + PWarning (((char *)GETMESSAGE(60, 28, "Invalid key context"))); + XtFree ((char *)keySpec); + continue; /* skip this key specification */ + } +#ifdef WSM + if (bBadKey) + { + /* + * Don't print an error message if this is a "hardware + * available" binding. + */ + if (!(keySpec->context & F_CONTEXT_IFKEY)) + PWarning (((char *)GETMESSAGE(60, 27, "Invalid key specification"))); + XtFree ((char *)keySpec); + continue; /* skip this key specification */ + } + + /* + * This flag is only used for parsing, clear it so the + * rest of the program doesn't see it. + */ + keySpec->context &= ~F_CONTEXT_IFKEY; +#endif /* WSM */ + + + /* + * Parse the key function and any arguments. + */ + + ix = ParseWmFunction (&lineP, CRS_KEY, &keySpec->wmFunction); + + /* + * remove any subContexts that don't apply to this function + */ + if ((functionTable[ix].greyedContext & F_SUBCONTEXT_IB_IICON) && + (keySpec->subContext & F_SUBCONTEXT_IB_IICON)) + { + keySpec->subContext &= ~F_SUBCONTEXT_IB_IICON; + } + + if ((functionTable[ix].greyedContext & F_SUBCONTEXT_IB_WICON) && + (keySpec->subContext & F_SUBCONTEXT_IB_WICON)) + { + keySpec->subContext &= ~F_SUBCONTEXT_IB_WICON; + } + + /* + * Apply the function argument parser. + */ + if (!(*(functionTable [ix].parseProc)) + (&lineP, keySpec->wmFunction, &keySpec->wmFuncArgs)) + { + XtFree ((char *)keySpec); + continue; /* skip this key specification */ + } + + /* + * Add the key specification to the key specification list. + */ + if (lastKeySpec != NULL) + /* a prior specification exists */ + { + lastKeySpec->nextKeySpec = keySpec; + } + else + { + pSD->keySpecs = keySpec; + } + lastKeySpec = keySpec; + } + +} /* END OF FUNCTION ParseKeySet */ + +#ifndef WSM + +/*************************************<->************************************* + * + * GetNextLine () + * + * + * Description: + * ----------- + * Returns the next line from an fopened configuration file or a newline- + * embedded configuration string. + * + * + * Inputs: + * ------ + * cfileP = (global) file pointer to fopened configuration file or NULL + * line = (global) line buffer + * linec = (global) line count + * parseP = (global) parse string pointer if cfileP == NULL + * + * + * Outputs: + * ------- + * line = (global) next line + * linec = (global) line count incremented + * parseP = (global) parse string pointer incremented + * Return = line or NULL if file or string is exhausted. + * + * + * Comments: + * -------- + * If there are more than MAXLINE characters on a line in the file cfileP the + * excess are truncated. + * Assumes the line buffer is long enough for any parse string line. + * + *************************************<->***********************************/ + +unsigned char * +GetNextLine (void) +{ + register unsigned char *string; + int len; + +#ifndef NO_MULTIBYTE + int chlen; + wchar_t last; + wchar_t wdelim; + char delim; + int lastlen; +#endif + + if (cfileP != NULL) + /* read fopened file */ + { + if ((string = (unsigned char *) + fgets ((char *)line, MAXLINE, cfileP)) != NULL) + { +#ifndef NO_MULTIBYTE + + lastlen = 0; + while (*string && + ((len = mblen((char *)string, MB_CUR_MAX)) > 0)) + { + mbtowc(&last, (char *)string, MB_CUR_MAX); + lastlen = len; + string += len; + } + delim = '\\'; + mbtowc(&wdelim, &delim, MB_CUR_MAX); + if (lastlen == 1 && last == wdelim) + { + do + { + if (!fgets((char *)string, MAXLINE - (string - line), cfileP)) + break; + + lastlen = 0; + while (*string && + ((len = mblen((char *)string, MB_CUR_MAX)) > 0)) + { + mbtowc(&last, (char *)string, MB_CUR_MAX); + lastlen = len; + string += len; + } + linec++; + } + while (lastlen == 1 && last == wdelim); + } + string = line; +#else + len = strlen((char *)string) - 2; + if ((len > 0) && string[len] == '\\') + { + do { + string = &string[len]; + if (fgets((char *)string, + MAXLINE - (string-line), cfileP) == NULL) + break; + len = strlen((char *)string) - 2; + linec++; + } while ((len >= 0) && string[len] == '\\'); + string = line; + } +#endif + } + } + else if ((parseP != NULL) && (*parseP != '\0')) + /* read parse string */ + { + string = line; +#ifndef NO_MULTIBYTE +#ifdef FIX_1127 + chlen = mblen((char *)parseP, MB_CUR_MAX); + if(chlen==-1) string = NULL; +#endif + + while ((*parseP != '\0') && + ((chlen = mblen ((char *)parseP, MB_CUR_MAX)) > 0) && + (*parseP != '\n')) + /* copy all but NULL and newlines to line buffer */ + { + while (chlen--) + { + *(string++) = *(parseP++); + } + } +#else + while ((*parseP != '\0') && (*parseP != '\n')) + /* copy all but end-of-line and newlines to line buffer */ + { + *(string++) = *(parseP++); + } +#endif + if (string) + *string = '\0'; + if (*parseP == '\n') + { + parseP++; + } + } + else + { + string = NULL; + } + + linec++; + return (string); + +} /* END OF FUNCTION GetNextLine */ +#endif /* WSM */ + +#ifndef PANELIST + +#ifdef WSM +/*************************************<->************************************* + * + * GetStringC (linePP, SmBehavior) + * + * + * Description: + * ----------- + * Returns the next quoted or whitespace-terminated nonquoted string in the + * line buffer. + * Additional functionality added to GetString in that anything in a + * quoted string is considered sacred and nothing will be stripped from + * the middle of a quoted string. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * SmBehavior = flag that enables parsing session manager hints + * if True. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * Return = string + * + * + * Comments: + * -------- + * May alter the line buffer contents. + * Handles quoted strings and characters, removing trailing whitespace from + * quoted strings. + * Returns NULL string if the line is empty or is a comment. + * Code stolen from dtmwm. + * + *************************************<->***********************************/ +#else /* WSM */ +/*************************************<->************************************* + * + * GetString (linePP) + * + * + * Description: + * ----------- + * Returns the next quoted or whitespace-terminated nonquoted string in the + * line buffer. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * Return = string + * + * + * Comments: + * -------- + * May alter the line buffer contents. + * Handles quoted strings and characters, removing trailing whitespace from + * quoted strings. + * Returns NULL string if the line is empty or is a comment. + * + *************************************<->***********************************/ +#endif /* WSM */ + +#ifdef WSM +unsigned char *GetStringC (unsigned char **linePP, Boolean SmBehavior) +#else /* WSM */ +unsigned char *GetString (unsigned char **linePP) +#endif /* WSM */ +{ + unsigned char *lineP = *linePP; + unsigned char *endP; + unsigned char *curP; + unsigned char *lnwsP; +#ifdef WSM + unsigned int level = 0, checkLev, i, quoteLevel[10]; +#endif /* WSM */ +#ifndef NO_MULTIBYTE + int chlen; + + /* get rid of leading white space */ + ScanWhitespace (&lineP); + + /* + * Return NULL if line is empty, a comment, or invalid. + */ +#ifdef WSM + if ( + *lineP == '\0' || + ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) < 1) || + ((chlen == 1) && ((*lineP == '!') || + ((!SmBehavior) && (*lineP == '#')))) + ) +#else /* WSM */ + if ( + *lineP == '\0' || + ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) < 1) || + ((chlen > 0) && ((*lineP == '!') || (*lineP == '#'))) + ) +#endif /* WSM */ + { + *linePP = lineP; + return (NULL); + } + + if ((chlen == 1) && (*lineP == '"')) + /* Quoted string */ + { +#ifdef WSM + quoteLevel[level] = 1; +#endif /* WSM */ + /* + * Start beyond double quote and find the end of the quoted string. + * '\' quotes the next character. + * Otherwise, matching double quote or NULL terminates the string. + * + * We use lnwsP to point to the last non-whitespace character in the + * quoted string. When we have found the end of the quoted string, + * increment lnwsP and if lnwsP < endP, write NULL into *lnwsP. + * This removes any trailing whitespace without overwriting the + * matching quote, needed later. If the quoted string was all + * whitespace, then this will write a NULL at the beginning of the + * string that will be returned -- OK. + */ + lnwsP = lineP++; /* lnwsP points to first '"' */ + curP = endP = lineP; /* other pointers point beyond */ + + while ((*endP = *curP) && + ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0) && + ((chlen > 1) || (*curP != '"'))) + /* Haven't found matching quote yet. + * First byte of next character has been copied to endP. + */ + { + curP++; + if ((chlen == 1) && (*endP == '\\') && + ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0)) + /* character quote: + * copy first byte of quoted nonNULL character down. + * point curP to next byte + */ + { +#ifdef WSM + if (SmBehavior) + { + /* + * Check to see if this is a quoted quote - if it is + * strip off a level - if not - it's sacred leave it alone + */ + checkLev = PeekAhead((curP - 1), quoteLevel[level]); + if(checkLev > 0) + { + if(quoteLevel[level] <= checkLev) + { + level--; + } + else + { + level++; + quoteLevel[level] = checkLev; + } + + for(i = 0;i < (checkLev - 2);i++) + { + *endP++ = *curP++;curP++; + } + *endP = *curP++; + } + } + else + { +#endif /* WSM */ + *endP = *curP++; +#ifdef WSM + } +#endif /* WSM */ + } + + if (chlen == 1) + /* Singlebyte character: character copy finished. */ + { + if (isspace (*endP)) + /* whitespace character: leave lnwsP unchanged. */ + { + endP++; + } + else + /* non-whitespace character: point lnwsP to it. */ + { + lnwsP = endP++; + } + } + else if (chlen > 1) + /* Multibyte (nonwhitespace) character: point lnwsP to it. + * Finish character byte copy. + */ + { + lnwsP = endP++; + while (--chlen) + { + *endP++ = *curP++; + lnwsP++; + } + } + } +#else + + /* get rid of leading white space */ + ScanWhitespace (&lineP); + +#ifdef WSM + /* Return NULL if line is empty, whitespace, or begins with a comment. */ + if ((lineP == NULL || *lineP == '\0') || + (!SmBehavior && (*lineP == '#'))) +#else /* WSM */ + /* Return NULL if line is empty, whitespace, or begins with a comment. */ + if ((lineP == NULL) || (*lineP == '\0') || (*lineP == '#')) +#endif /* WSM */ + { + *linePP = lineP; + return (NULL); + } + + if (*lineP == '"') + /* Quoted string */ + { +#ifdef WSM + quoteLevel[level] = 1; +#endif /* WSM */ + /* + * Start beyond double quote and find the end of the quoted string. + * '\' quotes the next character. + * Otherwise, matching double quote or NULL terminates the string. + * + * We use lnwsP to point to the last non-whitespace character in the + * quoted string. When we have found the end of the quoted string, + * increment lnwsP and if lnwsP < endP, write NULL into *lnwsP. + * This removes any trailing whitespace without overwriting the + * matching quote, needed later. If the quoted string was all + * whitespace, then this will write a NULL at the beginning of the + * string that will be returned -- OK. + */ + lnwsP = lineP++; /* lnwsP points to first '"' */ + curP = endP = lineP; /* other pointers point beyond */ + + while ((*endP = *curP) && (*endP != '"')) + /* haven't found matching quote yet */ + { + /* point curP to next character */ + curP++; + if ((*endP == '\\') && (*curP != '\0')) + /* shift quoted nonNULL character down and curP ahead */ + { +#ifdef WSM + if (SmBehavior) + { + /* + * Check to see if this is a quoted quote - if it is + * strip off a level - if not - it's sacred leave it alone + */ + checkLev = PeekAhead((curP - 1), quoteLevel[level]); + if(checkLev > 0) + { + if(quoteLevel[level] <= checkLev) + { + level--; + } + else + { + level++; + quoteLevel[level] = checkLev; + } + + for(i = 0;i < (checkLev - 2);i++) + { + *endP++ = *curP++;curP++; + } + *endP = *curP++; + } + } + else + { +#endif /* WSM */ + *endP = *curP++; +#ifdef WSM + } +#endif /* WSM */ + } + if (isspace (*endP)) + /* whitespace character: leave lnwsP unchanged. */ + { + endP++; + } + else + /* non-whitespace character: point lnwsP to it. */ + { + lnwsP = endP++; + } + } +#endif + + /* + * Found matching quote or NULL. + * NULL out any trailing whitespace. + */ + + lnwsP++; + if (lnwsP < endP) + { + *lnwsP = '\0'; + } + } + + else + /* Unquoted string */ + { + /* + * Find the end of the nonquoted string. + * '\' quotes the next character. + * Otherwise, whitespace, end-of-line, or '#' terminates the string. + */ + curP = endP = lineP; + +#ifndef NO_MULTIBYTE +#ifdef WSM + while ((*endP = *curP) && + ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0) && + ((chlen > 1) || (!isspace (*curP) && + (SmBehavior || (*curP != '#'))))) +#else /* WSM */ + while ((*endP = *curP) && + ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0) && + ((chlen > 1) || (!isspace (*curP) && (*curP != '#')))) +#endif /* WSM */ + /* Haven't found whitespace or '#' yet. + * First byte of next character has been copied to endP. + */ + { + curP++; + if ((chlen == 1) && (*endP == '\\') && + ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0)) + /* character quote: + * copy first byte of quoted nonNULL character down. + * point curP to next byte + */ + { + *endP = *curP++; + } + endP++; + if (chlen > 1) + /* Multibyte character: finish character copy. */ + { + while (--chlen) + { + *endP++ = *curP++; + } + } + } +#else +#ifdef WSM + while ((*endP = *curP) && !isspace (*endP) && + (SmBehavior || (*endP != '#'))) +#else /* WSM */ + while ((*endP = *curP) && !isspace (*endP) && (*endP != '#')) +#endif /* WSM */ + { + /* point curP to next character */ + curP++; + if ((*endP == '\\') && (*curP != '\0')) + /* shift quoted nonNULL character down and curP ahead */ + { + *endP = *curP++; + } + endP++; + } +#endif + } + + /* + * Three cases for *endP: + * '#' --> write NULL over # and point to NULL + * whitespace or + * matching quote -> write end-of-line over char and point beyond + * NULL -> point to NULL + */ + +#ifdef WSM + if (!SmBehavior && (*endP == '#')) +#else /* WSM */ + if (*endP == '#') +#endif /* WSM */ + { + *endP = '\0'; /* write '\0' over '#' */ + *linePP = endP; /* point to '\0' */ + } + else if (*endP != '\0') + { + *endP = '\0'; /* write NULL over terminator */ + *linePP = ++curP; /* point beyond terminator */ + } + else + { + *linePP = endP; + } + return ((unsigned char *)lineP); + +} /* END OF FUNCTION GetString */ +#endif /* PANELIST */ + + + +/*************************************<->************************************* + * + * ParseBtnEvent (linePP, eventType, button, state, fClick) + * + * + * Description: + * ----------- + * Parse a button event specification. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer + * buttonEvents = (global) button event parse table + * modifierStrings = (global) modifier string/mask table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * eventType = type of event + * button = parsed button number + * state = composite modifier mask + * fClick = is click? + * + * Return = (Boolean) true iff valid button event specification + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +Boolean ParseBtnEvent (unsigned char **linePP, + unsigned int *eventType, + unsigned int *button, + unsigned int *state, + Boolean *fClick) +{ + if (!ParseEvent (linePP, buttonEvents, eventType, button, state, fClick)) + { + return (FALSE); + } + + /* + * The following is a fix for an X11 deficiency in regards to + * modifiers in grabs. + */ + if (*eventType == ButtonRelease) + { + /* the button that is going up will always be in the modifiers... */ + *state |= buttonModifierMasks[*button]; + } + + return (TRUE); + +} /* END OF FUNCTION ParseBtnEvent */ + + + +/*************************************<->************************************* + * + * ParseKeyEvent (linePP, eventType, keyCode, state) + * + * + * Description: + * ----------- + * Parse a key event specification. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer + * keyEvents = (global) key event parse table + * modifierStrings = (global) modifier string/mask table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * eventType = type of event + * keyCode = parsed KeyCode + * state = composite modifier mask + * + * Return = (Boolean) true iff valid key event specification + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +Boolean ParseKeyEvent (unsigned char **linePP, unsigned int *eventType, + KeyCode *keyCode, unsigned int *state) + + +{ + Boolean fClick; + unsigned int keySym = 0; + + if (!ParseEvent (linePP, keyEvents, eventType, &keySym, state, &fClick)) + { + return (FALSE); + } + + /* + * Here keySym is a KeySym. Convert it to a KeyCode. + * KeyCode will be set to 0 if keySym is not defined for any KeyCode + * (e.g. 0x001). + */ + + *keyCode = XKeysymToKeycode(DISPLAY, (KeySym) keySym); + + if (*keyCode == 0) + { + if (keySym == XK_F9) + { + keySym = XK_KP_F1; + } + else if (keySym == XK_F10) + { + keySym = XK_KP_F2; + } + else if (keySym == XK_F11) + { + keySym = XK_KP_F3; + } + else if (keySym == XK_F12) + { + keySym = XK_KP_F4; + } + *keyCode = XKeysymToKeycode(DISPLAY, (KeySym) keySym); + } + + return (*keyCode != 0); + +} /* END OF FUNCTION ParseKeyEvent */ + + +/*************************************<->************************************* + * + * ParseEvent (linePP, table, eventType, detail, state, fClick) + * + * + * Description: + * ----------- + * Parse an event specification. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * table = event parse table + * modifierStrings = (global) modifier string/mask table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * eventType = type of event + * detail = dependent upon parse table detail procedure and closure + * state = composite modifier mask + * fClick = click flag + * + * Return = (Boolean) true iff valid event specification + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseEvent (unsigned char **linePP, EventTableEntry *table, + unsigned int *eventType, unsigned int *detail, + unsigned int *state, Boolean *fClick) +{ + unsigned char *lineP = *linePP; + Cardinal ix; + Boolean status; + + /* Parse the modifiers */ + if (!ParseModifiers (&lineP, state) || *lineP != '<') + { + return (FALSE); + } + lineP++; /* skip '<' */ + + /* Parse the event type */ + if (!ParseEventType (&lineP, table, eventType, &ix) || *lineP != '>') + { + return (FALSE); + } + lineP++; /* skip '>' */ + + /* + * Compute detail and fClick. + * Status will be False for a invalid KeySym name. + */ + status = (*(table[ix].parseProc))(&lineP, table[ix].closure, detail); + *fClick = table[ix].fClick; + + if (status) + { + *linePP = lineP; + } + return (status); + +} /* END OF FUNCTION ParseEvent */ + + + +/*************************************<->************************************* + * + * ParseModifiers(linePP, state) + * + * + * Description: + * ----------- + * Parses a modifier specification. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * modifierStrings = (global) modifier string/mask table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * state = composite modifier mask + * Return = (Boolean) true iff valid modifier name + * + * + * Comments: + * -------- + * If successful, will be followed by NULL or '<'. + * + *************************************<->***********************************/ + +static Boolean ParseModifiers(unsigned char **linePP, unsigned int *state) +{ + unsigned char *lineP = *linePP; + unsigned char *startP; + unsigned char modStr[MAX_MODIFIER_STRLEN+1]; + Boolean fNot; + unsigned int maskBit; + int len; + + *state = 0; + + /* + * Parse modifiers until the event specifier is encountered. + */ + + ScanWhitespace (&lineP); + while ((*lineP != '\0') && (*lineP != '<')) + { + if (*lineP == '~') + { + fNot = TRUE; + lineP++; + } + else + { + fNot = FALSE; + } + + startP = lineP; + ScanAlphanumeric (&lineP); + if (startP == lineP) + /* ERROR: Modifier or '<' missing */ + { + return (FALSE); + } + len = min(lineP - startP, MAX_MODIFIER_STRLEN); + (void) strncpy ((char *)modStr, (char *)startP, len); + modStr[len] = '\0'; + + if (!LookupModifier (modStr, &maskBit)) + /* Unknown modifier name */ + { + return (FALSE); + } + + if (fNot) + { + *state &= ~maskBit; + } + else + { + *state |= maskBit; + } + ScanWhitespace(&lineP); + } + + *linePP = lineP; + return (TRUE); /* must have '<' or NULL following */ + +} /* END OF FUNCTION ParseModifiers */ + + +/*************************************<->************************************* + * + * LookupModifier (name, valueP) + * + * + * Description: + * ----------- + * Return the modifier mask for the provided modifier name. + * + * + * Inputs: + * ------ + * name = modifier string + * modifierStrings = modifier string/mask table + * + * + * Outputs: + * ------- + * valueP = modifier mask + * Return = (Boolean) true iff valid modifier name + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean LookupModifier (unsigned char *name, unsigned int *valueP) +{ + register int i; + + if (name != NULL) + { + ToLower (name); + for (i=0; modifierStrings[i].name != NULL; i++) + { + if (!strcmp (modifierStrings[i].name, (char *)name)) + { + *valueP = modifierStrings[i].mask; + return (TRUE); + } + } + } + + return (FALSE); + +} /* END OF FUNCTION LookupModifier */ + + +#if ((!defined(WSM)) || 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 ((unsigned char *)modString); + for (i=NONE; i<=EXCLUDE; i++) + { + if (!strcmp (CCIEntryModifierNames[i], modString)) + { + *mod = i; + return (TRUE); + } + } + } + + return (FALSE); + +} /* END OF FUNCTION GetCCIModifier */ + + +/*************************************<->************************************* + * + * 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(WSM) || defined(MWM_QATS_PROTOCOL) */ + + +/*************************************<->************************************* + * + * ParseEventType(linePP, table, eventType, ix) + * + * + * Description: + * ----------- + * Parses the event type string. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * table = event parse table + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * eventType = type of event + * ix = table index for matched event + * + * Return = (Boolean) true iff valid event + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseEventType (unsigned char **linePP, EventTableEntry *table, + unsigned int *eventType, Cardinal *ix) +{ + unsigned char *lineP = *linePP; + unsigned char *startP = *linePP; + unsigned char eventTypeStr[MAX_EVENTTYPE_STRLEN+1]; + register int len; + + /* Parse out the event string */ + ScanAlphanumeric (&lineP); + + /* + * Attempt to match the parsed event against our supported event set. + */ + + if (startP != lineP) + { + len = min (lineP - startP, MAX_EVENTTYPE_STRLEN); + (void) strncpy ((char *)eventTypeStr, (char *)startP, len); + eventTypeStr[len] = '\0'; + ToLower (eventTypeStr); + + for (len = 0; table[len].event != NULL; len++) + if (!strcmp (table[len].event, (char *)eventTypeStr)) + { + *ix = len; + *eventType = table[*ix].eventType; + *linePP = lineP; + return (TRUE); + } + } + + /* Unknown event specified */ + return (FALSE); + +} /* END OF FUNCTION ParseEventType */ + + +/*************************************<->************************************* + * + * ParseImmed (linePP, closure, detail) + * + * + * Description: + * ----------- + * Button event detail procedure. + * + * + * Inputs: + * ------ + * linePP = not used + * closure = table entry + * + * + * Outputs: + * ------- + * detail = pointer to closure + * + * Return = TRUE + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseImmed (unsigned char **linePP, unsigned int closure, + unsigned int *detail) +{ + *detail = closure; + return (TRUE); + +} /* END OF FUNCTION ParseImmed */ + + +/*************************************<->************************************* + * + * ParseKeySym (linePP, closure, detail) + * + * + * Description: + * ----------- + * Key event detail procedure. Parses a KeySym string. + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer + * + * closure = not used. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer + * detail = pointer to parsed KeySym + * + * Return = (Boolean) true iff valid KeySym string + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static Boolean ParseKeySym (unsigned char **linePP, unsigned int closure, + unsigned int *detail) +{ + unsigned char *lineP = *linePP; + unsigned char *startP; + char keySymName[MAX_KEYSYM_STRLEN+1]; + int len; +#ifndef NO_MULTIBYTE + int chlen; +#endif + + ScanWhitespace (&lineP); + startP = lineP; + +#ifndef NO_MULTIBYTE + while (*lineP && + ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) > 0) && + ((chlen > 1) || + (!isspace (*lineP) && *lineP != ',' && *lineP != ':'))) + { + /* Skip next character */ + lineP += chlen; + } +#else + while (*lineP && !isspace (*lineP) && *lineP != ',' && *lineP != ':' ) + { + /* Skip next character */ + lineP++; + } +#endif + + len = min (lineP - startP, MAX_KEYSYM_STRLEN); + (void) strncpy (keySymName, (char *)startP, len); + keySymName[len] = '\0'; + +#ifndef NO_MULTIBYTE + if ((*detail = XStringToKeysym(keySymName)) == NoSymbol && + (mblen (keySymName, MB_CUR_MAX) == 1)) +#else + if ((*detail = XStringToKeysym(keySymName)) == NoSymbol) +#endif + { + if (!isdigit (keySymName[0]) || + ((*detail = StrToNum ((unsigned char *)&keySymName[0])) == -1)) + { + *detail = NoSymbol; + return (FALSE); + } + } + *linePP = lineP; + return (TRUE); + +} /* END OF FUNCTION ParseKeySym */ + + + +/*************************************<->************************************* + * + * StrToNum(str) + * + * + * Description: + * ----------- + * Converts a string to an unsigned hexadecimal, decimal, or octal integer. + * + * + * Inputs: + * ------ + * str = character string + * + * + * Outputs: + * ------- + * Return = unsigned integer + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static unsigned int StrToNum(unsigned char *str) +{ + unsigned char c; + unsigned int val = 0; + + if (*str == '0') + { + str++; + if (*str == 'x' || *str == 'X') + { + return (StrToHex(++str)); + } + return (StrToOct(str)); + } + + while ((c = *str) != '\0') + { + if ('0' <= c && c <= '9') + { + val = val*10+c-'0'; + } + else + { + return (-1); + } + str++; + } + + return (val); + +} /* END OF FUNCTION StrToNum */ + + + +/*************************************<->************************************* + * + + * + * + * Description: + * ----------- + * + * Inputs: + * ------ + * + * + * Outputs: + * ------- + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static unsigned int StrToHex(unsigned char *str) +{ + unsigned char c; + unsigned int val = 0; + + while ((c = *str) != '\0') + { + if ('0' <= c && c <= '9') + { + val = val*16+c-'0'; + } + else if ('a' <= c && c <= 'f') + { + val = val*16+c-'a'+10; + } + else if ('A' <= c && c <= 'F') + { + val = val*16+c-'A'+10; + } + else + { + return (-1); + } + str++; + } + + return (val); + +} /* END OF FUNCTION StrToHex */ + + + +/*************************************<->************************************* + * + + * + * + * Description: + * ----------- + * + * Inputs: + * ------ + * + * + * Outputs: + * ------- + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static unsigned int StrToOct(unsigned char *str) +{ + unsigned char c; + unsigned int val = 0; + + while ((c = *str) != '\0') + { + if ('0' <= c && c <= '7') + { + val = val*8+c-'0'; + } + else + { + return (-1); + } + str++; + } + + return (val); + +} /* END OF FUNCTION StrToOct */ + + + +/*************************************<->************************************* + * + * ScanAlphanumeric (linePP) + * + * + * Description: + * ----------- + * Scan string until a non-alphanumeric character is encountered. + * + * + * Inputs: + * ------ + * linePP = nonNULL pointer to current line buffer pointer + * + * + * Outputs: + * ------- + * linePP = nonNULL pointer to revised line buffer pointer + * + * + * Comments: + * -------- + * Assumes linePP is nonNULL + * + *************************************<->***********************************/ + +void ScanAlphanumeric (unsigned char **linePP) +{ +#ifndef NO_MULTIBYTE + int chlen; + + while (*linePP && + ((chlen = mblen ((char *) *linePP, MB_CUR_MAX)) > 0) && + ((chlen > 1) || isalnum (**linePP))) + { + (*linePP) += chlen; + } +#else + while (*linePP && isalnum (**linePP)) + { + (*linePP)++; + } +#endif + +} /* END OF FUNCTION ScanAlphanumeric */ + + +#ifndef WSM + +/*************************************<->************************************* + * + * ScanWhitespace(linePP) + * + * + * Description: + * ----------- + * Scan the string, skipping over all white space characters. + * + * + * Inputs: + * ------ + * linePP = nonNULL pointer to current line buffer pointer + * + * + * Outputs: + * ------- + * linePP = nonNULL pointer to revised line buffer pointer + * + * + * Comments: + * -------- + * Assumes linePP is nonNULL + * + *************************************<->***********************************/ + +void ScanWhitespace(unsigned char **linePP) +{ +#ifndef NO_MULTIBYTE + while (*linePP && (mblen ((char *)*linePP, MB_CUR_MAX) == 1) && isspace (**linePP)) +#else + while (*linePP && isspace (**linePP)) +#endif + { + (*linePP)++; + } + +} /* END OF FUNCTION ScanWhitespace */ +#endif /* not WSM */ + +#ifndef WSM + +/*************************************<->************************************* + * + * ToLower (string) + * + * + * Description: + * ----------- + * Lower all characters in a string. + * + * + * Inputs: + * ------ + * string = NULL-terminated character string or NULL + * + * + * Outputs: + * ------- + * string = NULL-terminated lower case character string or NULL + * + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +void ToLower (unsigned char *string) +{ + unsigned char *pch = string; +#ifndef NO_MULTIBYTE + int chlen; + + while (*pch && ((chlen = mblen ((char *)pch, MB_CUR_MAX)) > 0)) + { + if ((chlen == 1) && (isupper (*pch))) + { + *pch = tolower(*pch); + } + pch += chlen; + } +#else + while (*pch != '\0') + { + if (isupper (*pch)) + { + *pch = tolower(*pch); + } + pch++; + } +#endif + +} /* END OF FUNCTION ToLower */ +#endif /* WSM */ + + +/*************************************<->************************************* + * + * PWarning (message) + * + * + * Description: + * ----------- + * This function lists a resource description parse message to stderr. + * + * + * Inputs: + * ------ + * message = pointer to a message string + * cfileP = (global) file pointer to fopened configuration file or NULL + * linec = (global) line counter + * + *************************************<->***********************************/ + +void +PWarning (char *message) +{ + +#ifdef WSM + char pch[MAXWMPATH+1]; + String sMessage; + char *pchFile; + + sMessage = XtNewString ((String) message); + if (cfileP != NULL) + { + if (pConfigStackTop->fileName) + { + pchFile = pConfigStackTop->fileName; + } + else + { + pchFile = wmGD.configFile; + } + + sprintf (pch, pWarningStringFile, + GETMESSAGE(20,1,"Workspace Manager"), + sMessage, linec, pchFile); + } + else + { + sprintf (pch, pWarningStringLine, + GETMESSAGE(20,1,"Workspace Manager"), + sMessage, linec); + } + _DtSimpleError (wmGD.mwmName, DtIgnore, NULL, pch, NULL); + XtFree (sMessage); +#else /* WSM */ + if (cfileP != NULL) + { + fprintf (stderr, ((char *)GETMESSAGE(60, 33, "%s: %s on line %d of configuration file %s\n")), + wmGD.mwmName, message, linec, + wmGD.configFile ? wmGD.configFile : cfileName); + } + else + { + fprintf (stderr, ((char *)GETMESSAGE(60, 34, "%s: %s on line %d of specification string\n")), + wmGD.mwmName, message, linec); + } + fflush (stderr); +#endif /* WSM */ + + +} /* END OF FUNCTION PWarning */ + +#ifdef WSM +/* + * Key substitution table entry + */ + +typedef struct _keySubs +{ + unsigned char * pchFrom; + int lenFrom; + unsigned char * pchTo; +} KeySub; + + +/*************************************<->************************************* + * + * InitKeySubs (ppKeySubs, pNumKeySubs) + * + * + * Description: + * ----------- + * Initialize key label substitutions used in acclerator text + * + * + * Inputs: + * ------ + * ppKeySubs = ptr to key substitution table ptr + * pNumKeySubs = ptr to number of key substitutions + * + * + * Outputs: + * ------- + * *ppKeySubs = ptr to key substitution table + * *pNumKeySubs = number of substitutions found + * + * Comments: + * -------- + * *ppKeySubs is allocated with XtMalloc in a complicated way. + * If this ever needs to be freed, a function to free it needs to + * be written. + * + *************************************<->***********************************/ + +static void InitKeySubs ( + KeySub **ppKeySubs, + int *pNumKeySubs) +{ + int numKS; + KeySub *pKS; + KeySub *pKSret; + unsigned char *pch0; + unsigned char *pch1; + int len; +#ifndef NO_MULTIBYTE + int chlen; +#endif + + pch0 = (unsigned char *)GETMESSAGE(60, 40, ""); + + if ((pch0 == NULL) || (*pch0 == '\0')) + { + *ppKeySubs = NULL; + *pNumKeySubs = 0; + return; + } + + pKSret = NULL; + numKS = 0; + + while (*pch0 != '\0') + { + ScanWhitespace (&pch0); + if (*pch0 == '\0') break; + + /* + * allocate space for next key sub + */ + if (pKSret == NULL) + { + pKSret = (KeySub *) XtMalloc (1*sizeof(KeySub)); + } + else + { + pKSret = (KeySub *) XtRealloc ((char *)pKSret, + (numKS+1)*sizeof(KeySub)); + } + pKS = &pKSret[numKS]; + + /* get "from" string */ + pch1 = pch0; +#ifndef NO_MULTIBYTE + while (*pch1 && ((chlen = mblen ((char *)pch1, MB_CUR_MAX)) > 0)) + { + if ((chlen == 1) && (*pch1 == ' ')) + { + break; + } + pch1 += chlen; + } +#else /* NO_MULTIBYTE */ + while (*pch1 && (*pch1 != ' ')) pch1++; +#endif /* NO_MULTIBYTE */ + pKS->lenFrom = pch1 - pch0; + if (pKS->lenFrom < 1) + { + /* + * no "from" string + */ + break; + } + pKS->pchFrom = (unsigned char *) XtMalloc (1+pKS->lenFrom); + memcpy (pKS->pchFrom, pch0, pKS->lenFrom); + pKS->pchFrom[pKS->lenFrom] = '\0'; + + /* get "to" string */ + ScanWhitespace (&pch1); + pch0 = pch1; + +#ifndef NO_MULTIBYTE + while (*pch1 && ((chlen = mblen ((char *)pch1, MB_CUR_MAX)) > 0)) + { + if ((chlen == 1) && (*pch1 == ' ')) + { + break; + } + pch1 += chlen; + } +#else /* NO_MULTIBYTE */ + while (*pch1 && (*pch1 != ' ')) pch1++; +#endif /* NO_MULTIBYTE */ + + len = pch1 - pch0; + if (len < 1) + { + /* + * Invalid format, "from" string with no "to" string. + */ + break; + } + pKS->pchTo = (unsigned char *) XtMalloc (1+len); + memcpy (pKS->pchTo, pch0, len); + pKS->pchTo[len] = '\0'; + + /* advance cursor */ + pch0 = pch1; + + /* got one, bump the counter */ + numKS++; + } + + *ppKeySubs = pKSret; + *pNumKeySubs = numKS; +} + +#endif /* WSM */ + +/*************************************<->************************************* + * + * ProcessAccelText (startP, endP, destP) + * + * + * Description: + * ----------- + * Process accelerator text and copy into string. + * + * + * Inputs: + * ------ + * startP = pointer to start of valid accelerator specification + * endP = pointer past end of accelerator specification + * destP = pointer to destination buffer + * + * + * Outputs: + * ------- + * Destination buffer has processed accelerator text. + * + * Comments: + * -------- + * None. + * + *************************************<->***********************************/ + +static void ProcessAccelText (unsigned char *startP, unsigned char *endP, + unsigned char *destP) +{ +#ifndef NO_MULTIBYTE + int chlen; +#endif +#ifdef WSM + static Boolean bAccelInit = False; + static KeySub *pKeySub; + static int numKeySubs; + unsigned char * pchFirst; + unsigned char * pchSub; + int lenSub; + int i; + + if (!bAccelInit) + { + InitKeySubs (&pKeySub, &numKeySubs); + bAccelInit = True; + } +#endif /* WSM */ + + /* + * Copy modifiers + */ + + ScanWhitespace (&startP); + + while (*startP != '<') + { + if (*startP == '~') + { + *destP++ = *startP++; + } +#ifdef WSM + pchFirst = startP; +#endif /* WSM */ + +#ifndef NO_MULTIBYTE + while (*startP && + (((chlen = mblen ((char *)startP, MB_CUR_MAX)) > 1) + || isalnum (*startP))) + { + while (chlen--) + { +#ifdef WSM + startP++; + +#else /* WSM */ + *destP++ = *startP++; +#endif /* WSM */ + } + } +#else + while (isalnum (*startP)) + { +#ifdef WSM + startP++; +#else /* WSM */ + *destP++ = *startP++; +#endif /* WSM */ + } +#endif +#ifdef WSM + /* find substitution */ + pchSub = NULL; + lenSub = 0; + + for (i=0; i 0)) + { + memcpy (destP, pchSub, lenSub); + destP += lenSub; + } + else + { + memcpy (destP, pchFirst, startP-pchFirst); + destP += startP-pchFirst; + } +#endif /* WSM */ + *destP++ = '+'; + + ScanWhitespace (&startP); + } + + /* + * Skip the key event type. + */ + startP++; /* skip '<' */ + while (*startP != '>') + { +#ifndef NO_MULTIBYTE + startP += mblen ((char *)startP, MB_CUR_MAX); +#else + startP++; +#endif + } + startP++; /* skip '>' */ + + /* + * Copy the KeySym string. + */ + + ScanWhitespace (&startP); + while (startP != endP) + { + *destP++ = *startP++; + } + *destP = '\0'; + +} /* END OF FUNCTION ProcessAccelText */ + + + +/*************************************<->************************************* + * + * ProcessCommandLine (argc, argv) + * + * + * Description: + * ----------- + * This function looks for and processes mwm options in the command line + * + * Inputs: + * ------ + * argc = argument count. + * argv = argument vector. + * + * + * Outputs: + * ------- + * Changes global data to based on command line options recognized + * + * + *************************************<->***********************************/ +#define SCREENS_OPT "-screens" +#define MULTI_SCREEN_OPT "-multiscreen" + +void ProcessCommandLine (int argc, char *argv[]) +{ + unsigned char *string; + int argnum; + unsigned char *lineP; + + for (argnum = 1; argnum < argc; argnum++) + { + lineP = (unsigned char *) argv[argnum]; + if ((string = GetString (&lineP)) == NULL) + /* empty or comment line */ + { + continue; + } + if (!strcmp((char *)string, MULTI_SCREEN_OPT)) + { + wmGD.multiScreen = True; + wmGD.numScreens = ScreenCount (DISPLAY); + } + else if (!strcmp((char *)string, SCREENS_OPT)) + { + argnum++; /* skip to next arg */ + ParseScreensArgument (argc, argv, &argnum, lineP); + } + } + +} /* END OF FUNCTION ProcessCommandLine */ + + +/*************************************<->************************************* + * + * ParseScreensArgument (argc, argv, pArgnum, lineP) + * + * + * Description: + * ----------- + * This function processes the ``-screens'' command line argument + * + * Inputs: + * ------ + * argc = argument count. + * argv = argument vector. + * pArgnum = pointer to argument number where processing left off + * lineP = pointer into argv[*pArgnum] where processing left off + * + * + * Outputs: + * ------- + * Changes global data to based on command line options recognized + * + wmGD.screenNames + * + wmGD.numScreens + * Assumes default screenNames are already in place + * + *************************************<->***********************************/ + +static void ParseScreensArgument (int argc, char *argv[], int *pArgnum, + unsigned char *lineP) +{ + unsigned char *string; + int sNum = 0; + int lastLen; + int nameCount = 0; + + for (; (*pArgnum < argc) && (sNum < ScreenCount(DISPLAY)); + (*pArgnum)++, sNum++) + { + lineP = (unsigned char *)argv[*pArgnum]; + if (*argv[*pArgnum] == '"') + { + /* + * if Quote, use GetString to strip it + */ + if ((string = GetString (&lineP)) == NULL) + /* empty or comment line */ + { + continue; + } + } + else + { + string = (unsigned char *)argv[*pArgnum]; + if (*string == '-') + { + /* another option, end of screens names */ + break; + } + } + + if (!(wmGD.screenNames[sNum] = (unsigned char *) + XtRealloc ((char*)wmGD.screenNames[sNum], + 1 + strlen((char *)string)))) + { + Warning (((char *)GETMESSAGE(60, 31, "Insufficient memory for screen names"))); + ExitWM(WM_ERROR_EXIT_VALUE); + } + else + { + strcpy((char *)wmGD.screenNames[sNum], (char *)string); + nameCount++; + } + } + + (*pArgnum)--; + + /* + * remaining screens (if any) get first name specified + */ + if (nameCount > 0) + { + lastLen = 1 + strlen((char *)wmGD.screenNames[0]); + for (; sNum < ScreenCount(DISPLAY); sNum++) + { + if (!(wmGD.screenNames[sNum] = (unsigned char *) + XtRealloc ((char*)wmGD.screenNames[sNum], lastLen))) + { + Warning (((char *)GETMESSAGE(60, 32, "Insufficient memory for screen names"))); + ExitWM(WM_ERROR_EXIT_VALUE); + } + else + { + strcpy((char *)wmGD.screenNames[sNum], + (char *)wmGD.screenNames[0]); + } + } + } + +} /* END OF FUNCTION ParseScreensArgument */ + + +/*************************************<->************************************* + * + * ProcessMotifBindings () + * + * + * Description: + * ----------- + * This function is used retrieve the motif input bindings + * and put them into a property on the root window. + * + * + *************************************<->***********************************/ +void ProcessMotifBindings (void) +{ + char fileName[MAXWMPATH+1]; + char *bindings = NULL; +#ifndef MOTIF_ONE_DOT_ONE + char *homeDir = XmeGetHomeDirName(); +#else + FILE *fileP; +#endif + + /* + * Look in the user's home directory for .motifbind + */ + +#ifdef MOTIF_ONE_DOT_ONE + GetHomeDirName(fileName); +#else + strcpy (fileName, homeDir); +#endif + strncat(fileName, "/", MAXWMPATH-strlen(fileName)); + strncat(fileName, MOTIF_BINDINGS_FILE, MAXWMPATH-strlen(fileName)); + +#ifdef MOTIF_ONE_DOT_ONE + if ((fileP = fopen (fileName, "r")) != NULL) + { + unsigned char buffer[MBBSIZ]; + int count; + Boolean first = True; + int mode = PropModeReplace; + Window propWindow; + + /* + * Get the atom for the property. + */ + wmGD.xa_MOTIF_BINDINGS = + XInternAtom (DISPLAY, _XA_MOTIF_BINDINGS, False); + + /* + * The property goes on the root window of screen zero + */ + propWindow = RootWindow(DISPLAY, 0); + + /* + * Copy file contents to property on root window of screen 0. + */ + while ( (count=fread((char *) &buffer[0], 1, MBBSIZ, fileP)) > 0) + { + XChangeProperty (DISPLAY, propWindow, wmGD.xa_MOTIF_BINDINGS, + XA_STRING, 8, mode, + &buffer[0], count); + + if (first) + { + first = False; + mode = PropModeAppend; + } + } + } + +#else + XDeleteProperty (DISPLAY, RootWindow (DISPLAY, 0), + XInternAtom (DISPLAY, "_MOTIF_BINDINGS", False)); + XDeleteProperty (DISPLAY, RootWindow (DISPLAY, 0), + XInternAtom (DISPLAY, "_MOTIF_DEFAULT_BINDINGS", False)); + + if (_XmVirtKeysLoadFileBindings (fileName, &bindings) == True) { + XChangeProperty (DISPLAY, RootWindow(DISPLAY, 0), + XInternAtom (DISPLAY, "_MOTIF_BINDINGS", False), + XA_STRING, 8, PropModeReplace, + (unsigned char *)bindings, strlen(bindings)); + } + else { + _XmVirtKeysLoadFallbackBindings (DISPLAY, &bindings); + } + XtFree (bindings); +#endif +} /* END OF FUNCTION ProcessMotifBindings */ + +#ifdef PANELIST + +/*************************************<->************************************* + * + * void + * ParseWmFunctionArg (linePP, ix, wmFunc, ppArg, sClientName) + * + * + * Description: + * ----------- + * Parse the function arguments for a window manager function. + * + * + * Inputs: + * ------ + * linePP = pointer to line buffer pointer (contains string arg). + * ix = window manager function index (returned by ParseWmFunction) + * pWmFunction = pointer to window manager function destination. + * ppArg = ptr to argument pointer. + * sClientName = string name of client + * + * + * Outputs: + * ------- + * *ppArg = arg to pass to window manager function when invoking. + * Return = true on succes, false on some kind of parse error + * + * + * Comments: + * -------- + * functionTable (window manager function table) is indexed with ix + * to get parsing info. + * + * This function may malloc memory for the returned arg. + * + * The sClientName is needed for starting some hpterm-based push_recall + * clients. It needs to be passed into the action so the hpterm gets + * named appropriately. + * + *************************************<->***********************************/ + +Boolean +ParseWmFunctionArg ( + unsigned char **linePP, + int ix, + WmFunction wmFunc, + void **ppArg, + String sClientName, + String sTitle) +{ + unsigned char *lineP = *linePP; + Boolean bValidArg = True; + unsigned char *str = NULL; + + /* + * If this is (possibly) a string argument, put it + * in quotes so that it will be parsed properly. + */ + if ((functionTable[ix].parseProc == ParseWmFuncStrArg) || + (functionTable[ix].parseProc == ParseWmFuncMaybeStrArg)) + { + if (lineP && *lineP != '"') + { + /* + * not in quotes, repackage it, escaping the appropriate + * characters. + */ + str = _DtWmParseMakeQuotedString (lineP); + if (str) + { + lineP = str; + } + } + } + + /* + * Apply the function argument parser. + */ + if ((functionTable[ix].wmFunction != wmFunc) || + !(*(functionTable [ix].parseProc)) (&lineP, wmFunc, ppArg)) + { + bValidArg = False; + } + + /* + * Add the exec parms if this is an f.action + */ + if ((wmFunc == F_Action) && ppArg && *ppArg) + { + WmActionArg *pAP = (WmActionArg *) *ppArg; + int totLen = 0; + + /* + * allocate more than enough string space to copy + * strings and intervening spaces. + */ + if (sClientName && *sClientName) + { + /* length of: "name=" + sClientName + NULL */ + totLen += 5 + strlen(sClientName) + 1; + } + if (sTitle && *sTitle) + { + /* length of: "," + "title=" + sTitle + NULL */ + totLen += 1 + 6 + strlen(sTitle) + 1; + } + + if (totLen > 0) + { + pAP->szExecParms = (String) XtMalloc (totLen); + /* start with empty string */ + pAP->szExecParms[0] = '\0'; + + if (sClientName && *sClientName) + { + strcat (pAP->szExecParms, "name="); + strcat (pAP->szExecParms, sClientName); + } + if (sTitle && *sTitle) + { + if (pAP->szExecParms[0] != '\0') + { + strcat (pAP->szExecParms, ","); + } + strcat (pAP->szExecParms, "title="); + strcat (pAP->szExecParms, sTitle); + } + } + } + + if (str) + { + XtFree ((char *) str); + } + + return (bValidArg); + +} /* END OF FUNCTION ParseWmFunctionArg */ + + +/*************************************<->************************************* + * + * SystemCmd (pchCmd) + * + * + * Description: + * ----------- + * This function fiddles with our signal handling and calls the + * system() function to invoke a unix command. + * + * + * Inputs: + * ------ + * pchCmd = string with the command we want to exec. + * + * Outputs: + * ------- + * + * + * Comments: + * -------- + * The system() command is touchy about the SIGCLD behavior. Restore + * the default SIGCLD handler during the time we run system(). + * + *************************************<->***********************************/ + +void +SystemCmd (char *pchCmd) +{ + struct sigaction sa; + struct sigaction osa; + + (void) sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + + (void) sigaction (SIGCLD, &sa, &osa); + + system (pchCmd); + + (void) sigaction (SIGCLD, &osa, (struct sigaction *) 0); +} + + + +/*************************************<->************************************* + * + * DeleteTempConfigFileIfAny () + * + * + * Description: + * ----------- + * This function deletes the temporary config file used to process + * old dtwmrc syntax. + * + * + * Inputs: + * ------ + * + * + * Outputs: + * ------- + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +void +DeleteTempConfigFileIfAny (void) +{ + char pchCmd[MAXWMPATH+1]; + + if (pConfigStackTop->tempName) + { + strcpy (pchCmd, "/bin/rm "); + strcat (pchCmd, pConfigStackTop->tempName); + SystemCmd (pchCmd); + XtFree ((char *) pConfigStackTop->tempName); + pConfigStackTop->tempName = NULL; + } + if (pConfigStackTop->cppName) + { + strcpy (pchCmd, "/bin/rm "); + strcat (pchCmd, pConfigStackTop->cppName); + SystemCmd (pchCmd); + XtFree ((char *) pConfigStackTop->cppName); + pConfigStackTop->cppName = NULL; + } +} + + +/*************************************<->************************************* + * + * ParseIncludeSet (pSD, lineP) + * + * + * Description: + * ----------- + * + * + * Inputs: + * ------ + * cfileP = (global) file pointer to fopened configuration file or NULL + * lineP = pointer to line buffer + * line = (global) line buffer + * linec = (global) line count + * parseP = (global) parse string pointer if cfileP == NULL + * pSD->rootWindow = default root window of display + * + * Outputs: + * ------- + * linec = (global) line count incremented + * parseP = (global) parse string pointer if cfileP == NULL + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +static void ParseIncludeSet (WmScreenData *pSD, unsigned char *lineP) +{ + unsigned char *string; + unsigned char *pchName; + + /* + * Require leading '{' on the next line. + */ + + while ((GetNextLine () != NULL)) /* not EOF nor read error */ + { + lineP = line; + ScanWhitespace(&lineP); + + if ((lineP == NULL) || (*line == '!') || (*lineP == '\0') || (*lineP == '#')) + /* ignore empty or comment line */ + { + continue; + } + + if (*lineP == '{') + /* found '{' */ + { + break; + } + + /* not a '{' */ + PWarning (((char *)GETMESSAGE(60, 37, "Expected '{'"))); + return; + } + + /* + * Found leading "{" or EOF. + * Parse include files until "}" or EOF found. + */ + while ((GetNextLine () != NULL)) + { + lineP = line; + if ((*line == '!') || (string = GetString (&lineP)) == NULL) + /* ignore empty or comment lines */ + { + continue; + } + if (*string == '}') /* finished with set. */ + { + break; + } + pchName = _DtWmParseFilenameExpand (string); + if (pchName && ConfigStackPush (pchName)) + { + ProcessWmFile (pSD, True /* nested */); + ConfigStackPop (); + XtFree ((char *) pchName); + } + + } + +} + + + +/*************************************<->************************************* + * + * ConfigStackInit (pchFileName) + * + * + * Description: + * ----------- + * Initializes the config file processing stack + * + * Inputs: + * ------ + * pchFileName = name of new file to start parsing + * + * Outputs: + * ------- + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +static void ConfigStackInit (char *pchFileName) +{ + + pConfigStack = XtNew (ConfigFileStackEntry); + + if (pConfigStack) + { + pConfigStackTop = pConfigStack; + pConfigStackTop->fileName = XtNewString (pchFileName); + pConfigStackTop->tempName = NULL; + pConfigStackTop->cppName = NULL; + pConfigStackTop->offset = 0; + pConfigStackTop->pWmPB = wmGD.pWmPB; + pConfigStackTop->wmgdConfigFile = wmGD.configFile; + pConfigStackTop->pIncluder = NULL; + + } + else + { + sprintf ((char *)wmGD.tmpBuffer, + (char *)GETMESSAGE(60,36,"Insufficient memory to process included file: %s"), + pchFileName); + Warning ((char *)wmGD.tmpBuffer); + } +} + + +/*************************************<->************************************* + * + * ConfigStackPush (pchFileName) + * + * + * Description: + * ----------- + * Open an included config file + * + * Inputs: + * ------ + * pchFileName = name of new file to start parsing + * wmGD.pWmPB = global parse buffer (pickle this) + * + * Outputs: + * ------- + * wmGD.pWmPB = global parse buffer (new one for new file) + * return = FILE * to open file or NULL + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +static FILE * +ConfigStackPush (unsigned char *pchFileName) +{ + ConfigFileStackEntry *pEntry; + FILE *pNewFile = NULL; + + pEntry = XtNew (ConfigFileStackEntry); + if (pEntry) + { + /* save off state of current config file */ + pConfigStackTop->offset = ftell (cfileP); + pConfigStackTop->pWmPB = wmGD.pWmPB; + fclose (cfileP); + + /* set up state of new config file */ + pEntry->fileName = XtNewString ((char *)pchFileName); + pEntry->tempName = NULL; + pEntry->cppName = NULL; + pEntry->wmgdConfigFile = (String) pEntry->fileName; + + /* set globals for new config file */ + wmGD.pWmPB = _DtWmParseNewBuf (); + wmGD.configFile = pEntry->wmgdConfigFile; + + /* put new entry onto stack */ + pEntry->pIncluder = pConfigStackTop; + pConfigStackTop = pEntry; + + /* open the file */ + pNewFile = cfileP = FopenConfigFile(); + + if (!pNewFile) + { + /* file open failed! back out */ + ConfigStackPop (); + } + } + else + { + sprintf ((char *)wmGD.tmpBuffer, + (char *)GETMESSAGE(60,36,"Insufficient memory to process included file: %s"), + pchFileName); + Warning ((char *)wmGD.tmpBuffer); + } + + return (pNewFile); +} + + + +/*************************************<->************************************* + * + * ConfigStackPop () + * + * + * Description: + * ----------- + * + * + * Inputs: + * ------ + * pchFileName = name of new file to start parsing + * wmGD.pWmPB = global parse buffer (pickle this) + * + * Outputs: + * ------- + * wmGD.pWmPB = global parse buffer (new one for new file) + * + * + * Comments: + * -------- + * assumes cfileP is closed already + * + *************************************<->***********************************/ + +static void ConfigStackPop (void) +{ + Boolean error = False; + ConfigFileStackEntry *pPrev; + char pchCmd[MAXWMPATH+1]; + + if (pConfigStackTop != pConfigStack) + { + pPrev = pConfigStackTop->pIncluder; + + _DtWmParseDestroyBuf (wmGD.pWmPB); + if (pConfigStackTop->tempName) + { + XtFree (pConfigStackTop->tempName); + } + if (pConfigStackTop->cppName) + { + strcpy (pchCmd, "/bin/rm "); + strcat (pchCmd, pConfigStackTop->cppName); + SystemCmd (pchCmd); + XtFree ((char *) pConfigStackTop->cppName); + pConfigStackTop->cppName = NULL; + } + if (pConfigStackTop->fileName) + { + XtFree (pConfigStackTop->fileName); + } + + wmGD.pWmPB = pPrev->pWmPB; + wmGD.configFile = pPrev->wmgdConfigFile; + if (pPrev->tempName) + { + cfileP = fopen (pPrev->tempName, "r"); + } + else if (pPrev->cppName) + { + cfileP = fopen (pPrev->cppName, "r"); + } + else + { + cfileP = fopen (pPrev->fileName, "r"); + } + if (cfileP) + { + fseek (cfileP, pPrev->offset, 0); + } + else + { + char msg[MAXWMPATH+1]; + + sprintf(msg, ((char *)GETMESSAGE(60, 39, + "Could not reopen configuration file %s")), + pPrev->fileName); + Warning (msg); + } + + XtFree ((char *)pConfigStackTop); + pConfigStackTop = pPrev; + } +} + + +/*************************************<->************************************* + * + * ParseWmFuncActionArg (linePP, wmFunction, pArgs) + * + * + * Description: + * ----------- + * Parses a window manager f.action argument + * + * + * Inputs: + * ------ + * linePP = pointer to current line buffer pointer. + * wmFunction = function for which the argument string is intended. + * pArgs = pointer to argument destination. + * + * + * Outputs: + * ------- + * linePP = pointer to revised line buffer pointer. + * pArgs = pointer to parsed argument. + * Return = FALSE iff insufficient memory + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +Boolean ParseWmFuncActionArg (unsigned char **linePP, + WmFunction wmFunction, String *pArgs) +{ +#define WM_ACTION_ARG_INCREMENT 5 +#define WM_ACTION_ARG_PAD 256 + unsigned char *string; + char *pch; + WmActionArg *pAP; + int iArgSz; + + pAP = XtNew (WmActionArg); + if (pAP && (string = GetString (linePP)) != NULL) + { + /* Got action name */ + pAP->actionName = XtNewString ((char *) string); + + /* Get action arguments, if any */ + if (pAP->aap = (DtActionArg *) + XtMalloc (WM_ACTION_ARG_INCREMENT * sizeof (DtActionArg))) + { + iArgSz = WM_ACTION_ARG_INCREMENT; + pAP->numArgs = 0; + + while ((string = GetString (linePP)) != NULL) + { + if (pAP->aap[pAP->numArgs].u.file.name = (char *) + XtMalloc(1 + strlen((char *)string))) + { + pAP->aap[pAP->numArgs].argClass = DtACTION_FILE; + + /* format the action argument */ + pch = pAP->aap[pAP->numArgs].u.file.name; + + /* + * Expand environment variable + */ + if (string[0] == '$') + { + string = (unsigned char *) getenv ((char *)&string[1]); + if (!string) + { + break; + } + else + { + /* + * Make sure there's room for the new + * string. + */ + pch = (char *) + XtRealloc (pch, (1+strlen((char *)string))); + pAP->aap[pAP->numArgs].u.file.name = pch; + } + } + + /* !!! No host name processing is done!!! */ + + strcpy (pch, (char *)string); + + pAP->numArgs++; + if (pAP->numArgs == iArgSz) + { + /* need to increase our array space */ + iArgSz += WM_ACTION_ARG_INCREMENT; + pAP->aap = (DtActionArg *) + XtRealloc((char *)pAP->aap, + (iArgSz * sizeof (DtActionArg))); + if (!pAP->aap) + { + break; /* out of memory */ + } + } + } + else + { + break; /* out of memory */ + } + } + + } + pAP->szExecParms = NULL; + *pArgs = (String) pAP; + } + else + /* NULL string argument */ + { + *pArgs = NULL; + } + + return (TRUE); + +} /* END OF FUNCTION ParseWmFuncActionArg */ + + +#endif /* PANELIST */ +#ifdef WSM + +/*************************************<->************************************* + * + * PreprocessConfigFile (pSD) + * + * + * Description: + * ----------- + * This function runs the configuration file through the C + * preprocessor + * + * + * Inputs: + * ------ + * pSD = ptr to screen data + * + * Outputs: + * ------- + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +static void +PreprocessConfigFile (void) +{ +#define CPP_NAME_SIZE ((L_tmpnam)+1) + char pchCmd[MAXWMPATH+1]; + + if (wmGD.cppCommand && *wmGD.cppCommand) + { + /* + * Generate a temp file name. + */ + pConfigStackTop->cppName = XtMalloc (CPP_NAME_SIZE * sizeof(char)); + if (pConfigStackTop->cppName) + { + (void) tmpnam (pConfigStackTop->cppName); + + /* + * Build up the command line. + */ + strcpy (pchCmd, wmGD.cppCommand); + strcat (pchCmd, " "); + strcat (pchCmd, pConfigStackTop->fileName); + strcat (pchCmd, " "); + strcat (pchCmd, pConfigStackTop->cppName); + + /* + * Run the config file through the converter program + * and send the output to a temp file. + */ + SystemCmd (pchCmd); + } + } +} + + +/*************************************<->************************************* + * + * GetNetworkFileName (char *pchFile) + * + * + * Description: + * ----------- + * This function returns a local representation for a network + * file. + * + * + * Inputs: + * ------ + * pchFile - pointer to file name of form [:] + * + * Return: + * ------- + * String - ptr to allocated string of local file name. If input + * is not a network file, the a copy of pchFile is returned. + * + * + * Comments: + * -------- + * returned file name should be freed with XtFree(). + * + *************************************<->***********************************/ + +static String +GetNetworkFileName (char *pchFile) +{ + char *pch; + char *host_part; + char *file_part; + char *netfile; + char *sName = NULL; + char *pchName = NULL; + int count; + char **pchTok; + String sReturn = NULL; + char *homeDir; + int len; + + + pch = strchr (pchFile, ':'); + + if (pch) + { + /* + * Expand special chars and find matching file. + */ + pchTok = (char **)shellscan (pchFile, &count, 0); + + if ((count == 1) || (count == 2)) + { + /* one match found */ + host_part = pchTok[0]; + } + else if (count > 2) + { + /* several matches found, pick one */ + host_part = pchTok[1]; + } + else + { + host_part = NULL; + } + + if (host_part != NULL) + { + pch = strchr (host_part, ':'); + if (pch) + { + /* + * copy the string so we don't munge data + * inside shellscan + */ + host_part = sName = XtNewString ((String) host_part); + pch = strchr (sName, ':'); + + /* + * separate the host and file parts of the + * file name + */ + *pch = '\0'; + file_part = pch+1; + } + else + { + /* + * The colon went away. Hmm... + */ + file_part = host_part; + host_part = NULL; + } + + if ( +#ifndef NO_MULTIBYTE + (mblen(file_part, MB_CUR_MAX) == 1) && + (mblen(file_part+1, MB_CUR_MAX) == 1) && +#endif + (*file_part == '~') && + (*(file_part+1) == '/')) + { + /* + * Replace '~' with $HOME + */ + homeDir = XmeGetHomeDirName(); + len = strlen (host_part) + 1 + + strlen (homeDir) + strlen (file_part) + 1; + pch = (char *) XtMalloc (len); + strcpy (pch, sName); + host_part = pch; + pch += strlen (pch) + 1; + strcpy (pch, homeDir); + strcat (pch, file_part+1); + file_part = pch; + XtFree (sName); + sName = host_part; + } + } + else + { + /* + * shellscan had a problem with the file name. + * just operate on the name as-is. + * temporarily replace ':' with a NULL + */ + host_part = sName = XtNewString ((String) pchFile); + pch = strchr (sName, ':'); + *pch = '\0'; + host_part = pchFile; + file_part = pch+1; + } + + /* convert to canonical host/file name */ + netfile = (char *) + tt_host_file_netfile (host_part, file_part); + if (tt_pointer_error (netfile) == TT_OK) + { + /* convert to local file name equivalent */ + pchName = tt_netfile_file (netfile); + + if (tt_pointer_error (pchName) == TT_OK) + { + sReturn = XtNewString ((String) pchName); + tt_free ((char *)pchName); + } + tt_free (netfile); + } + + if (sName) + { + XtFree ((char *)sName); + } + } + + if (sReturn == NULL) + { + if ( +#ifndef NO_MULTIBYTE + (mblen(pchFile, MB_CUR_MAX) == 1) && + (mblen(pchFile+1, MB_CUR_MAX) == 1) && +#endif + (*pchFile == '~') && + (*(pchFile+1) == '/')) + { + /* + * Replace '~' with $HOME + */ + homeDir = XmeGetHomeDirName(); + len = strlen (homeDir) + strlen (pchFile) + 1; + sReturn = (char *) XtMalloc (len); + strcpy (sReturn, homeDir); + strcat (sReturn, pchFile+1); + } + else + { + sReturn = XtNewString ((String) pchFile); + } + } + + return (sReturn); +} +/**************************** eof ***************************/ +#endif /* WSM */ + + +#if ((!defined(WSM)) || 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); +} + + + +/*************************************<->************************************* + * + * 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(""); + item->labelBitmapIndex = -1; + item->mnemonic = (KeySym) 0; + item->accelState = 0; + item->accelKeyCode = (KeyCode) 0; + 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(WSM) || defined(MWM_QATS_PROTOCOL) */ diff --git a/configure.ac b/configure.ac index 6db447c..2b19c41 100644 --- a/configure.ac +++ b/configure.ac @@ -179,7 +179,7 @@ AC_SUBST(CDE_CONFIGURATION_TOP) LIBDIR="${libdir}/X11" AC_SUBST(LIBDIR) -MWMRCDIR="${libdir}/X11" +MWMRCDIR="/etc/X11/mwm" AC_SUBST(MWMRCDIR) INCDIR="${includedir}/X11" diff --git a/configure.ac.mwmrc_dir b/configure.ac.mwmrc_dir new file mode 100644 index 0000000..6db447c --- /dev/null +++ b/configure.ac.mwmrc_dir @@ -0,0 +1,401 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT +AC_CONFIG_SRCDIR([lib/Xm/Form.c]) +AC_PREREQ(2.52) +AC_CONFIG_AUX_DIR(.) +AC_CHECK_FILE(/usr/X/include/X11/X.h, + AC_PREFIX_DEFAULT(/usr/X), + AC_PREFIX_DEFAULT(/usr)) +AC_CHECK_FILE(/usr/X11R6/include/X11/X.h, + AC_PREFIX_DEFAULT(/usr/X11R6), + AC_PREFIX_DEFAULT(/usr)) + +dnl AM_MAINTAINER_MODE +AC_CANONICAL_TARGET + +dnl The version of the Motif libraries +CURRENT=4 +REVISION=4 +AGE=0 +AC_SUBST(CURRENT) +AC_SUBST(REVISION) +AC_SUBST(AGE) + +dnl This is really dumb but it seems to be bug +AM_INIT_AUTOMAKE(motif,2.3.4,no-define) + +LIBTOOL_VERSION=$CURRENT:$REVISION:$AGE + +dnl +dnl Override a default in libtool. +dnl +dnl AC_DISABLE_STATIC + +AM_CONFIG_HEADER(include/config.h lib/Xm/Xm.h) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AM_PROG_CC_STDC +AM_PROG_LIBTOOL + +AC_EXEEXT + +dnl AC_PROG_YACC +dnl Do this the old fashioned way. 'bison -y' doesn't cut it +AC_CHECK_PROGS(YACC, byacc, yacc) + +dnl AC_PROG_SPLINT +AC_CHECK_PROGS(SPLINT, splint) +if test x$SPLINT = x +then + AC_MSG_WARN([No splint is dound]) +fi + +AM_PROG_LEX +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + + +dnl Checks for libraries. + +AC_PATH_X +AC_PATH_XTRA +LT_LIB_XTHREADS + +dnl Checks for Xos_r.h + +AC_CHECK_HEADERS([X11/Xos_r.h]) +AC_CHECK_HEADERS([X11/Xpoll.h]) + +dnl Compile in EditRes support if we can find Xmu + +save_LIBS="$LIBS" +save_CFLAGS="$CFLAGS" +LIBS="$X_LIBS $LIBS" +CFLAGS="$X_CFLAGS $CFLAGS" +AC_CHECK_HEADERS(X11/Xmu/Editres.h, +AC_CHECK_LIB(Xmu, _XEditResCheckMessages, +X_XMU=-lXmu +AC_DEFINE(HAVE_LIBXMU, 1, This System has libXmu) +, X_XMU="", -lXt -lX11) +AC_CHECK_LIB(Xmu,XmuNCopyISOLatin1Lowered , +AC_DEFINE(HAVE_XMU_N_COPY_ISO,1,Have XmuNCopyISOLatin1Lowered) +, , -lXt -lX11) +,,[[#include ]] +) + + +AC_SUBST(X_XMU) +LIBS="$save_LIBS" +CFLAGS="$save_CFLAGS" +AM_CONDITIONAL(OM_XMU, test x$X_XMU != x) + +dnl Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/malloc.h strings.h sys/file.h sys/time.h unistd.h wchar.h) +AC_CHECK_HEADERS(wctype.h, AC_DEFINE(HAS_WIDECHAR_FUNCTIONS,1,System supports wchar)) +AC_CHECK_HEADER(langinfo.h,,AC_DEFINE(CSRG_BASED,1,System Has langinfo.h)) +AC_CHECK_HEADER(X11/Xos_r.h,,AC_DEFINE(NEED_XOS_R_H,1,System Missing Xos_r.h)) +AC_CHECK_HEADER(X11/Xpoll.h,,AC_DEFINE(NEED_XPOLL_H,1,system Missing X11/Xpoll.h)) +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_MODE_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_TYPE_UID_T + +dnl Checks for library functions. +AC_FUNC_ALLOCA +AC_FUNC_MEMCMP +AC_FUNC_SETPGRP +AC_TYPE_SIGNAL +AC_FUNC_STRCOLL +AC_FUNC_STRFTIME +AC_FUNC_FORK([]) +AC_FUNC_VPRINTF +AM_FUNC_VOID_SPRINTF +AC_CHECK_FUNCS(wcslen wcscpy wcsncpy wcschr wcscat wcsncat getcwd gettimeofday mkdir re_comp regcmp select strcspn strerror strstr strtod strtol uname) +AC_CHECK_FUNCS(strdup,,AC_DEFINE(NEED_STRDUP, 1, no strdup)) +AC_CHECK_FUNCS(strcasecmp,,AC_DEFINE(NEED_STRCASECMP, 1, no strcasecmp)) +AC_CHECK_FUNCS(putenv,,AC_DEFINE(NO_PUTENV, 1, No PUTENV)) +AC_CHECK_FUNCS(regcomp,,AC_DEFINE(NO_REGCOMP, 1, no regcmp)) +AC_CHECK_FUNCS(memmove,,AC_DEFINE(NO_MEMMOVE, 1, no memmove)) +AC_CHECK_TYPE(XICProc,,AC_DEFINE(NO_XICPROC, 1, XICProc isn't defined), [#include ]) + +AC_ARG_ENABLE(message-catalog, [ --enable-message-catalog + Enable building of the message catalog (default=no)]) +if test "$enable_message_catalog" != "yes" +then + AC_DEFINE(NO_MESSAGE_CATALOG, 1, No Defined Message Catalog) +fi +AM_CONDITIONAL(MessageCatalog, test x$enable_message_catalog = xyes) + +AC_ARG_ENABLE(themes, [ --enable-themes Enable themes (default=no)]) +if test "$enable_themes" = "yes" +then + if test -f $srcdir/lib/Xm/Theme.h + then + AC_DEFINE(USE_XMTHEMES, 1, "Use XmThemes") + XMTHEME_DIST = "Theme.h ThemeP.h DynLibP.h Theme.c DynLib.c" + else + AC_MSG_WARN([--enable-themes specified, but I don't have the code. Disabled]) + enable_themes="no" + fi +fi +AC_SUBST(XMTHEME_DIST) +AM_CONDITIONAL(OM_XMTHEMES, test "$enable_themes" = "yes") + +AC_ARG_ENABLE(debug-themes, [ --enable-debug-themes Enable themes debugging (default=no)]) +if test "$enable_themes" = "yes" +then + if test "$enable_debug_themes" = "yes" + then + AC_DEFINE(DEBUGTHEMES, 1, "Debug Themes") + fi +fi + +if test x$GCC = xyes +then + CFLAGS="$CFLAGS -Wall -g -fno-strict-aliasing -Wno-unused -Wno-comment" + if test ` $CC -dumpversion | sed -e 's/\(^.\).*/\1/'` = "4" ; then + CFLAGS="$CFLAGS -fno-tree-ter" + fi +fi +AC_DEFINE(NO_OL_COMPAT, 1, "No OL Compatability") + +CDE_INSTALLATION_TOP="\${prefix}/dt" +AC_SUBST(CDE_INSTALLATION_TOP) + +CDE_CONFIGURATION_TOP="\${prefix}/etc/dt" +AC_SUBST(CDE_CONFIGURATION_TOP) + +LIBDIR="${libdir}/X11" +AC_SUBST(LIBDIR) + +MWMRCDIR="${libdir}/X11" +AC_SUBST(MWMRCDIR) + +INCDIR="${includedir}/X11" +AC_SUBST(INCDIR) + +XMBINDDIR_FALLBACK="${libdir}/X11/bindings" +AC_SUBST(XMBINDDIR_FALLBACK) + +RM="rm -f" +AC_SUBST(RM) + +AC_ARG_ENABLE(motif22-compatibility, [ --disable-motif22-compatibility + Disable binary compatibility with OpenMotif 2.2]) +AC_ARG_ENABLE(utf8, [ --disable-utf8 + Disable UTF-8 support]) + +case "$host_os" in + freebsd*) CFLAGS="$CFLAGS -DCSRG_BASED -DXNO_MTSAFE_API -DXNO_MTSAFE_PWDAPI"; + LDFLAGS="$LDFLAGS -L/usr/local/lib";; + cygwin*) CFLAGS="$CFLAGS -DXNO_MTSAFE_DIRENTDAPI";; + solaris* | sunos*) X_LIBS="$X_LIBS -L/usr/X/lib" && + if test x$enable_motif22_compatibility = x + then + enable_motif22_compatibility="no" + fi; + if test x$enable_utf8 = x + then + enable_utf8="no" + fi; + if test x$enable_xft = x + then + enable_xft="no" + fi;; +esac + +if test x$enable_motif22_compatibility = x +then + enable_motif22_compatibility="yes" +fi + +if test "$enable_motif22_compatibility" = "yes" +then + AC_DEFINE([OM22_COMPATIBILITY], [1], [Compatibility with OpenMotif 2.2]) + OM22_COMPATIBILITY_FALSE=! + OM22_COMPATIBILITY_TRUE= +else + OM22_COMPATIBILITY_FALSE= + OM22_COMPATIBILITY_TRUE=! +fi +AC_SUBST(OM22_COMPATIBILITY_FALSE) +AC_SUBST(OM22_COMPATIBILITY_TRUE) + +if test x$enable_utf8 = x +then + enable_utf8="yes" +fi + +if test "$enable_utf8" = "yes" +then + AC_DEFINE([UTF8_SUPPORTED], [1], [UTF8 is supported]) + AC_SEARCH_LIBS([iconv_open], [iconv], , + AC_SEARCH_LIBS([libiconv_open], [iconv])) +fi + +AC_ARG_ENABLE(printing, [ --disable-printing + Disable printing support]) + +if test x$enable_printing = x +then + enable_printing="yes" +fi + +if test "$enable_printing" = "yes" +then + AC_MSG_CHECKING([for libXp]) + AC_CHECK_HEADERS(X11/extensions/Print.h, + AC_CHECK_LIB(Xp, XpCreateContext, ,enable_printing="no"), + enable_printing="no") +fi + +if test "$enable_printing" = "yes" +then + LIB_XP=-lXp + AC_DEFINE([PRINTING_SUPPORTED], [1], [Printing is supported]) + PRINTING_SUPPORTED_FALSE=! + PRINTING_SUPPORTED_TRUE= +else + LIB_XP= + PRINTING_SUPPORTED_FALSE= + PRINTING_SUPPORTED_TRUE=! +fi +AC_SUBST(PRINTING_SUPPORTED_FALSE) +AC_SUBST(PRINTING_SUPPORTED_TRUE) + +AM_CONDITIONAL(PRINTING, test "$enable_printing" = "yes") +AC_SUBST(LIB_XP) + +AC_FIND_XFT +AC_IMAGE_SUPPORT + + + +# AM_CONDITIONAL(Motif22Compatibility, test x$enable_motif22_compatibility = xyes) + +AC_CONFIG_FILES([Makefile \ +bindings/Makefile \ +bitmaps/Makefile \ +clients/Makefile \ +clients/mwm/Makefile \ +clients/mwm/WmWsmLib/Makefile \ +clients/uil/Makefile \ +clients/xmbind/Makefile \ +config/Makefile \ +config/cf/Makefile \ +config/imake/Makefile \ +config/util/Makefile \ +config/makedepend/Makefile \ +include/Makefile \ +include/Dt/Makefile \ +lib/Makefile \ +lib/Xm/Makefile \ +lib/Mrm/Makefile \ +localized/Makefile \ +localized/util/Makefile \ +doc/Makefile \ +doc/man/Makefile \ +doc/man/man1/Makefile \ +doc/man/man3/Makefile \ +doc/man/man4/Makefile \ +doc/man/man5/Makefile \ +tools/Makefile \ +tools/wml/Makefile \ +demos/Makefile \ +demos/lib/Makefile \ +demos/lib/Xmd/Makefile \ +demos/lib/Wsm/Makefile \ +demos/lib/Exm/Makefile \ +demos/lib/Exm/wml/Makefile \ +demos/programs/Makefile \ +demos/programs/Exm/Makefile \ +demos/programs/Exm/app_in_c/Makefile \ +demos/programs/Exm/app_in_uil/Makefile \ +demos/programs/Exm/simple_app/Makefile \ +demos/programs/airport/Makefile \ +demos/programs/animate/Makefile \ +demos/programs/drag_and_drop/Makefile \ +demos/programs/draw/Makefile \ +demos/programs/earth/Makefile \ +demos/programs/filemanager/Makefile \ +demos/programs/fileview/Makefile \ +demos/programs/getsubres/Makefile \ +demos/programs/hellomotif/Makefile \ +demos/programs/hellomotifi18n/Makefile \ +demos/programs/hellomotifi18n/C/Makefile \ +demos/programs/hellomotifi18n/C/uid/Makefile \ +demos/programs/hellomotifi18n/english/Makefile \ +demos/programs/hellomotifi18n/english/uid/Makefile \ +demos/programs/hellomotifi18n/french/Makefile \ +demos/programs/hellomotifi18n/french/uid/Makefile \ +demos/programs/hellomotifi18n/hebrew/Makefile \ +demos/programs/hellomotifi18n/hebrew/uid/Makefile \ +demos/programs/hellomotifi18n/japan/Makefile \ +demos/programs/hellomotifi18n/japan/uid/Makefile \ +demos/programs/hellomotifi18n/japanese/Makefile \ +demos/programs/hellomotifi18n/japanese/uid/Makefile \ +demos/programs/hellomotifi18n/swedish/Makefile \ +demos/programs/hellomotifi18n/swedish/uid/Makefile \ +demos/programs/i18ninput/Makefile \ +demos/programs/panner/Makefile \ +demos/programs/periodic/Makefile \ +demos/programs/piano/Makefile \ +demos/programs/popups/Makefile \ +demos/programs/sampler2_0/Makefile \ +demos/programs/setdate/Makefile \ +demos/programs/todo/Makefile \ +demos/programs/workspace/Makefile \ +demos/programs/tooltips/Makefile \ +demos/programs/FontSel/Makefile \ +demos/programs/ButtonBox/Makefile \ +demos/programs/ColorSel/Makefile \ +demos/programs/Column/Makefile \ +demos/programs/Combo2/Makefile \ +demos/programs/Ext18List/Makefile \ +demos/programs/Ext18List/pixmaps/Makefile \ +demos/programs/IconB/Makefile \ +demos/programs/Outline/Makefile \ +demos/programs/Paned/Makefile \ +demos/programs/TabStack/Makefile \ +demos/programs/Tree/Makefile \ +demos/programs/pixmaps/Makefile \ +demos/unsupported/Makefile \ +demos/unsupported/Exm/Makefile \ +demos/unsupported/aicon/Makefile \ +demos/unsupported/dainput/Makefile \ +demos/unsupported/dogs/Makefile \ +demos/unsupported/hellomotif/Makefile \ +demos/unsupported/motifshell/Makefile \ +demos/unsupported/uilsymdump/Makefile \ +demos/unsupported/xmapdef/Makefile \ +demos/unsupported/xmfonts/Makefile \ +demos/unsupported/xmforc/Makefile \ +demos/unsupported/xmform/Makefile \ +demos/doc/Makefile \ +demos/doc/programGuide/Makefile \ +demos/doc/programGuide/ch05/Makefile \ +demos/doc/programGuide/ch05/Scale/Makefile \ +demos/doc/programGuide/ch06/Makefile \ +demos/doc/programGuide/ch06/spin_box/Makefile \ +demos/doc/programGuide/ch06/combo_box/Makefile \ +demos/doc/programGuide/ch08/Makefile \ +demos/doc/programGuide/ch08/Notebook/Makefile \ +demos/doc/programGuide/ch08/Container/Makefile \ +demos/doc/programGuide/ch16/Makefile \ +demos/doc/programGuide/ch17/Makefile \ +demos/doc/programGuide/ch17/simple_drop/Makefile \ +demos/doc/programGuide/ch17/simple_drag/Makefile \ +lib/Xm/xmstring.list \ +]) +AC_OUTPUT diff --git a/doc/man/man1/mwm.1 b/doc/man/man1/mwm.1 index dd4b3b8..1cf2ad8 100644 --- a/doc/man/man1/mwm.1 +++ b/doc/man/man1/mwm.1 @@ -678,8 +678,8 @@ is set, \fBmwm\fP looks for \fI$HOME/$LANG\fP/ \fBconfigFile\fP\&. If that file \fB$HOME\fP/\fBconfigFile\fP\&. If the \fIconfigFile\fP pathname does not begin with "~/" or "/", \fBmwm\fP considers it to be relative to the current working directory\&. If the \fIconfigFile\fP resource is not specified or if that file does not exist, \fBmwm\fP uses several default -paths to find a configuration file\&. The order of the search is shown below: \fB/usr/X11R6/lib/X11/$LANG/system\&.mwmrc\fP\(dg -\fB/usr/X11R6/lib/X11/system\&.mwmrc\fP\(dg Paths marked with \&'\(dg\&' are +paths to find a configuration file\&. The order of the search is shown below: \fB/etc/X11/mwm/$LANG/system\&.mwmrc\fP\(dg +\fB/etc/X11/mwm/system\&.mwmrc\fP\(dg Paths marked with \&'\(dg\&' are implementation dependent\&. .IP "\fIdeiconifyKeyFocus\fP\ (class\ \fIDeiconifyKeyFocus\fP)" 10 This resource applies only when the keyboard input focus policy is explicit\&. @@ -1344,9 +1344,9 @@ the shell to use when executing commands via the \fBf\&.exec\fP function\&. .SS "Files" .PP -\fB/usr/X11R6/lib/X11/$LANG/system\&.mwmrc\fP +\fB/etc/X11/mwm/$LANG/system\&.mwmrc\fP .PP -\fB/usr/X11R6/lib/X11/system\&.mwmrc\fP +\fB/etc/X11/mwm/system\&.mwmrc\fP .PP \fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP .PP diff --git a/doc/man/man1/mwm.1.mwmrc_dir b/doc/man/man1/mwm.1.mwmrc_dir new file mode 100644 index 0000000..dd4b3b8 --- /dev/null +++ b/doc/man/man1/mwm.1.mwmrc_dir @@ -0,0 +1,1361 @@ +'\" t +...\" mwm.sgm /main/13 1996/09/25 11:30:27 cdedoc $ +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "mwm" "user cmd" +.SH "NAME" +\fBmwm\fP \(em The Motif +Window Manager +.SH "SYNOPSIS" +.PP +\fBmwm\fP [\fIoptions\fP] +.SH "DESCRIPTION" +.PP +The \fBmwm\fP window manager provides +functions that facilitate control (by the user and the programmer) +of elements of window state such as placement, size, icon/normal display, +and input-focus ownership\&. +.PP +The stand-alone window manager is not an integral part +of CDE and does not support communication with other components in the CDE +environment, such as the Style Manager and the Session Manager\&. +.SS "Options" +.IP "\fI-display\fP\ \fBdisplay\fP" 10 +This option specifies the display to use; see \fBX\fP(1)\&. +.IP "\fI-xrm\fP\ \fBresourcestring\fP" 10 +This option specifies a resource string to use\&. +.IP "\fI-multiscreen\fP" 10 +This option causes \fBmwm\fP to manage all screens on +the display\&. The default is to manage only a single screen. +.IP "\fI-name\fP\ \fBname\fP" 10 +This option causes \fBmwm\fP to retrieve its resources +using the specified name, as in \fBname*resource\fP\&. +.IP "\fI-screens\fP\ \fBname\ [name\ [\&.\&.\&.]]\fP" 10 +This option specifies the resource names to use for the screens managed +by \fBmwm\fP\&. If \fBmwm\fP is managing a single +screen, only the first name in the list is used\&. If \fBmwm\fP +is managing multiple screens, the names are assigned to the screens in order, +starting with screen 0\&. Screen 0 gets the first name, screen 1 the second +name, and so on\&. +.SS "Appearance" +.PP +The following sections describe the basic default behaviors of windows, +icons, the icon box, input focus, and window stacking\&. The appearance and +behavior of the window manager can be altered by changing the configuration +of specific resources\&. Resources are defined under the heading "X DEFAULTS\&." +.SS "Screens" +.PP +By default, \fBmwm\fP manages only the single screen specified +by the \fI-display\fP option or the \fBDISPLAY\fP environment variable (by default, screen 0)\&. If the \fI-multiscreen\fP option is specified or if the \fImultiScreen\fP resource is True, \fBmwm\fP tries to manage all +the screens on the display\&. +.PP +When \fBmwm\fP is managing multiple screens, the \fI-screens\fP option can be used to give each screen a unique +resource name\&. The names are separated by blanks, for example, \fI-screens\fP scr0 scr1\&. If there are more screens than names, +resources for the remaining screens will be retrieved using the first name\&. +By default, the screen number is used for the screen name\&. +.SS "Windows" +.PP +Default \fBmwm\fP window frames have distinct components +with associated functions: +.IP "\fITitle\ Area\fP" 10 +In addition to displaying the client\&'s title, the title area is used +to move the window\&. To move the window, place the pointer over the title area, +press button 1 and drag the window to a new location\&. By default, a wire +frame is moved during the drag to indicate the new location\&. When the button +is released, the window is moved to the new location\&. +.IP "\fITitle\ Bar\fP" 10 +The title bar includes the title area, the minimize button, the maximize +button, and the window menu button\&. In shaped windows, such as round windows, +the title bar floats above the window\&. +.IP "\fIMinimize\ Button\fP" 10 +To turn the window into an icon, click button 1 on the minimize button +(the frame box with a \fBsmall\fP square in it)\&. +.IP "\fIMaximize\ Button\fP" 10 +To make the window fill the screen (or enlarge to the largest size allowed +by the configuration files), click button 1 on the maximize button (the frame +box with a \fBlarge\fP square in it)\&. +.IP "\fIWindow\ Menu\ Button\fP" 10 +The window menu button is the frame box with a horizontal bar in it\&. +To pull down the window menu, press button 1\&. While pressing, drag the pointer +on the menu to your selection, then release the button when your selection +is highlighted\&. Pressing button 3 in the title bar or resize border handles +also posts the window menu\&. Alternately, you can click button 1 to pull down +the menu and keep it posted; then position the pointer and select\&. You can +also post the window menu by pressing or \&. +Double-clicking button 1 with the pointer on the window menu button closes +the window\&. +.PP +The following table lists the contents of the window menu\&. +.SS "Default Window Menu" +.TS +tab(); +lw(1.803823i) lw(1.062374i) lw(2.633803i). +SelectionAcceleratorDescription +RestoreT{ +Restores the window to its size before minimizing +or maximizing\&. +T} +MoveT{ +Allows the window to be moved with keys or +mouse\&. +T} +SizeAllows the window to be resized\&. +MinimizeTurns the window into an icon\&. +MaximizeMakes the window fill the screen\&. +LowerT{ +Moves window to bottom of window stack\&. +T} +CloseAlt+F4Causes client to terminate\&. +.TE +.IP "\fIResize\ Border\ Handles\fP" 10 +To change the size of a window, move the pointer over a resize border +handle (the cursor changes), press button 1, and drag the window to a new +size\&. When the button is released, the window is resized\&. While dragging is +being done, a rubber-band outline is displayed to indicate the new window +size\&. +.IP "\fIMatte\fP" 10 +An optional matte decoration can be added between the client area and +the window frame (see the \fImatteWidth\fP resource)\&. A +\fImatte\fP is not actually part of the window frame\&. +There is no functionality associated with a matte\&. +.SS "Icons" +.PP +Icons are small graphic representations of windows\&. A window can be +minimized (iconified) using the minimize button on the window frame\&. Icons +provide a way to reduce clutter on the screen\&. +.PP +Pressing mouse button 1 when the pointer is over an icon causes the +icon\&'s window menu to pop up\&. Releasing the button (press + release without +moving mouse = click) causes the menu to stay posted\&. The menu contains the +following selections: +.SS "Icon Window Menu" +.TS +tab(); +lw(0.913000i) lw(1.144000i) lw(3.443000i). +SelectionAcceleratorDescription +RestoreOpens the associated window\&. +MoveT{ +Allows the icon to be moved with keys\&. +T} +SizeInactive (not an option for icons)\&. +MinimizeInactive (not an option for icons)\&. +MaximizeT{ +Opens the associated window and makes it +fill the screen\&. +T} +LowerMoves icon to bottom of icon stack\&. +CloseAlt+F4T{ +Removes client from \fBmwm\fP +management\&. +T} +.TE +.PP +Note that pressing button 3 over an icon also causes the icon\&'s window +menu to pop up\&. To make a menu selection, drag the pointer over the menu and +release button 3 when the desired item is highlighted\&. +.PP +Double-clicking button 1 on an icon invokes the \fBf\&.restore_and_raise\fP function and restores the icon\&'s associated window to its previous +state\&. For example, if a maximized window is iconified, double-clicking button +1 restores it to its maximized state\&. Double-clicking button 1 on the icon +box\&'s icon opens the icon box and allows access to the contained icons\&. (In +general, double-clicking a mouse button is a quick way to perform a function\&.) +Pressing or (the pop-up menu key) causes the +icon window menu of the currently selected icon to pop up\&. +.SS "Icon Box" +.PP +When icons begin to clutter the screen, they can be packed into an icon +box\&. (To use an icon box, \fBmwm\fP must be started with the +icon box configuration already set\&.) The icon box is a \fBmwm\fP +window that holds client icons\&. It includes one or more scroll bars when there +are more window icons than the icon box can show at the same time\&. +.PP +Icons in the icon box can be manipulated with the mouse\&. The following +table summarizes the behavior of this interface\&. Button actions apply whenever +the pointer is on any part of the icon\&. Note that double-clicking an icon +in the icon box invokes the \fBf\&.restore_and_raise\fP function\&. +.TS +tab(); +lw(0.841046i) lw(1.051308i) lw(3.607646i). +ButtonActionDescription +Button 1clickSelects the icon\&. +Button 1double-clickT{ +Normalizes (opens) the associated window\&. +Raises an already open window to the top of the stack\&. +T} +Button 1dragMoves the icon\&. +Button 3pressT{ +Causes the menu for that icon to pop up\&. +T} +Button 3dragT{ +Highlights items as the pointer moves across +the menu\&. +T} +.TE +.PP +Pressing mouse button 3 when the pointer is over an icon causes the +menu for that icon to pop up\&. +.SS "Icon Menu for the Icon Box" +.TS +tab(); +lw(0.885312i) lw(1.062374i) lw(3.552314i). +SelectionAcceleratorDescription +RestoreT{ +Opens the associated window (if not already +open)\&. +T} +MoveT{ +Allows the icon to be moved with keys\&. +T} +SizeInactive\&. +MinimizeInactive\&. +MaximizeT{ +Opens the associated window (if not already +open) and maximizes its size\&. +T} +LowerInactive\&. +CloseAlt+F4T{ +Removes client from \fBmwm\fP +management\&. +T} +.TE +.PP +To pull down the window menu for the icon box itself, press button 1 +with the pointer over the menu button for the icon box\&. The window menu of +the icon box differs from the window menu of a client window: The "Close" +selection is replaced with the "PackIcons Shift+Alt+F7" selection\&. When selected, +PackIcons packs the icons in the box to achieve neat rows with no empty slots\&. +.PP +You can also post the window menu by pressing , or + \&. Pressing (the pop-up menu key) causes the icon +window menu of the currently selected icon to pop up\&. +.SS "Input Focus" +.PP +The \fBmwm\fP window manager supports (by default) a keyboard +input focus policy of explicit selection\&. This means when a window is selected +to get keyboard input, it continues to get keyboard input until the window +is withdrawn from window management, another window is explicitly selected +to get keyboard input, or the window is iconified\&. Several resources control +the input focus\&. The client window with the keyboard input focus has the active +window appearance with a visually distinct window frame\&. +.PP +The following tables summarize the keyboard input focus selection behavior: +.TS +tab(); +lw(0.880482i) lw(0.844298i) lw(1.350877i) lw(2.424342i). +ButtonActionObjectFunction Description +Button 1pressWindow / window frameKeyboard focus selection\&. +Button 1pressIconKeyboard focus selection\&. +.TE +.TS +tab(); +lw(1.394366i) lw(4.105634i). +Key ActionFunction Description +[Alt][Tab]T{ +Move input focus to next window in window +stack (available only in explicit focus mode)\&. +T} +[Alt][Shift][Tab]T{ +Move input focus to previous window in window +stack (available only in explicit focus mode)\&. +T} +.TE +.SS "Window Stacking" +.PP +There are two types of window stacks: global window stacks and an application\&'s +local family window stack\&. +.PP +The global stacking order of windows may be changed as a result of setting +the keyboard input focus, iconifying a window, or performing a window manager +window stacking function\&. When keyboard focus policy is explicit the default +value of the \fIfocusAutoRaise\fP resource is True\&. This causes +a window to be raised to the top of the stack when it receives input focus, +for example, by pressing button 1 on the title bar\&. The key actions defined +in the previous table will thus raise the window receiving focus to the top +of the stack\&. +.PP +In pointer mode, the default value of \fIfocusAutoRaise\fP +is False, that is, the window stacking order is not changed when a window +receives keyboard input focus\&. The following key actions can be used to cycle +through the global window stack\&. +.TS +tab(); +lw(1.567982i) lw(3.932018i). +Key ActionFunction Description +[Alt][ESC]T{ +Place top window on bottom of stack\&. +T} +[Alt][Shift][ESC]T{ +Place bottom window on top of stack\&. +T} +.TE +.PP +By default, a window\&'s icon is placed on the bottom of the stack when +the window is iconified; however, the default can be changed by the \fIlowerOnIconify\fP resource\&. +.PP +Transient windows (secondary windows such a dialog boxes) stay above +their parent windows by default; however, an application\&'s local family stacking +order may be changed to allow a transient window to be placed below its parent +top-level window\&. The following arguments show the modification of the stacking +order for the \fBf\&.lower\fP function\&. +.IP "\fBf\&.lower\fP" 10 +Lowers the transient window within the family (staying above the parent) +and lowers the family in the global window stack\&. +.IP "\fBf\&.lower\fP\ [ \fIwithin\fP]" 10 +Lowers the transient window within the family (staying above the parent) +but does not lower the family in the global window stack\&. +.IP "\fBf\&.lower\fP\ [\fIfreeFamily\fP ]" 10 +Lowers the window free from its family stack (below the parent), but +does not lower the family in the global window stack\&. +.PP +The arguments \fIwithin\fP and \fIfreeFamily\fP can also be used with \fBf\&.raise\fP +and \fBf\&.raise_lower\fP\&. +.SS "Session Management" +.PP +The window manager is an X Session Management Protocol aware client\&. It responds to SaveYourself +(and other associated messages) by saving the geometries of its clients to a state file\&. +\fBmwm\fP can then be restarted by the XSMP session manager\&. +The default location for the state file is \fB$HOME/\&.mwmclientdb\fP\&. +This location can be overriden with the resource \fBsessionClientDB\fP\&. +.SS "X Resources" +.PP +The \fBmwm\fP command is configured from its resource +database\&. This database is built from the following sources\&. They are listed +in order of precedence, low to high: +.PP +\fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP +.PP +\fB$HOME/Mwm\fP +.PP +\fBRESOURCE_MANAGER\fP root window property or \fB$HOME/\&.Xdefaults\fP +.PP +\fBXENVIRONMENT\fP variable or \fB$HOME/\&.Xdefaults-host\fP +.PP +\fBmwm\fP command line options +.PP +The file names \fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP and \fB$HOME/Mwm\fP represent customary locations for these files\&. The actual +location of the system-wide class resource file may depend on the \fBXFILESEARCHPATH\fP environment variable and the +current language environment\&. The actual location of the user-specific class +resource file may depend on the \fBXUSERFILESEARCHPATH\fP and \fBXAPPLRESDIR\fP +environment variables and the current language environment\&. +.PP +Entries in the resource database may refer to other resource files for +specific types of resources\&. These include files that contain bitmaps, fonts, +and \fBmwm\fP specific resources such as menus and behavior +specifications (for example, button and key bindings)\&. +.PP +\fIMwm\fP is the resource class name of \fBmwm\fP and \fBmwm\fP is the default resource name used by \fBmwm\fP to look up resources\&. the \fI-screens\fP +command line option specifies resource names, such as "mwm_b+w" and "mwm_color"\&.) +In the following discussion of resource specification, "Mwm" and "mwm" (and +the aliased \fBmwm\fP resource names) can be used interchangeably, +but "mwm" takes precedence over "Mwm"\&. +.PP +The \fBmwm\fP command uses the following types of resources: +.IP "\fBComponent Appearance Resources:\fP" 10 +These resources specify appearance attributes of window manager user +interface components\&. They can be applied to the appearance of window manager +menus, feedback windows (for example, the window reconfiguration feedback +window), client window frames, and icons\&. +.IP "\fBGeneral Appearance and Behavior Resources:\fP" 10 +These resources specify \fBmwm\fP appearance and behavior +(for example, window management policies)\&. They are not set separately for +different \fBmwm\fP user interface components\&. They apply to +all screens and workspaces\&. +.IP "\fBScreen Specific Appearance and Behavior Resources:\fP" 10 +These resources specify the appearance and behavior of \fBmwm\fP elements that are settable on a per-screen basis\&. +.IP "\fBClient Specific Resources:\fP" 10 +These \fBmwm\fP resources can be set for a particular +client window or class of client windows\&. They specify client-specific icon +and client window frame appearance and behavior\&. +.PP +Resource identifiers can be either a resource name (for example, foreground) +or a resource class (for example, Foreground)\&. If the value of a resource +is a filename and if the filename is prefixed by "~/", then it is relative +to the path contained in the \fBHOME\fP +environment variable (generally the user\&'s home directory)\&. +.SS "Component Appearance Resources" +.PP +The syntax for specifying component appearance resources that apply +to window manager icons, menus, and client window frames is \fIMwm*\fP \fBresource_id\fP +.PP +For example, \fIMwm*foreground\fP is used to specify +the foreground color for \fBmwm\fP menus, icons, client window +frames, and feedback dialogs\&. +.PP +The syntax for specifying component appearance resources that apply +to a particular \fBmwm\fP component is \fIMwm*\fP[\fImenu\fP|\fIicon\fP|\fIclient\fP|\fIfeedback\fP] \fI*\fP\fBresource_id\fP +.PP +If \fBmenu\fP is specified, the resource is applied only +to \fBmwm\fP menus; if \fBicon\fP is specified, +the resource is applied to icons; and if \fBclient\fP is specified, +the resource is applied to client window frames\&. For example, \fIMwm*icon*foreground\fP is used to specify the foreground color for \fBmwm\fP +icons, \fIMwm*menu*foreground\fP specifies the foreground +color for \fBmwm\fP menus, and \fIMwm*client*foreground\fP is used to specify the foreground color for \fBmwm\fP +client window frames\&. +.PP +The appearance of the title area of a client window frame (including +window management buttons) can be separately configured\&. The syntax for configuring +the title area of a client window frame is \fIMwm*client*title*\fP \fBresource_id\fP +.PP +For example, \fIMwm*client*title*foreground\fP specifies +the foreground color for the title area\&. Defaults for title area resources +are based on the values of the corresponding client window frame resources\&. +.PP +The appearance of menus can be configured based on the name of the menu\&. +The syntax for specifying menu appearance by name is \fIMwm*menu*\fP \fBmenu_name\fP\fI*\fP\fBresource_id\fP +.PP +For example, \fIMwm*menu*my_menu*foreground\fP specifies +the foreground color for the menu named \fImy_menu\fP\&. The +user can also specify resources for window manager menu components, that is, +the gadgets that comprise the menu\&. These may include for example, a menu +title, title separator, one or more buttons, and separators\&. If a menu contains +more than one instance of a class, such as multiple PushButtonGadgets, the +name of the first instance is "PushButtonGadget1", the second is "PushButtonGadget2", +and so on\&. The following list identifies the naming convention used for window +manager menu components: +.IP " \(bu" 6 +Menu Title LabelGadget - "TitleName" +.IP " \(bu" 6 +Menu Title SeparatorGadget - "TitleSeparator" +.IP " \(bu" 6 +CascadeButtonGadget - "CascadeButtonGadget" +.IP " \(bu" 6 +PushButtonGadget - "PushButtonGadget" +.IP " \(bu" 6 +SeparatorGadget - "SeparatorGadget" +.PP +Refer to the man page for each class for a list of resources that can +be specified\&. +.PP +The following component appearance resources that apply to all window +manager parts can be specified: +.SS "Component Appearance Resources - All Window Manager Parts" +.TS +tab(); +lw(1.802521i) lw(1.571429i) lw(1.178571i) lw(0.947479i). +NameClassValue TypeDefault +backgroundBackgroundcolorvaries\(dg +backgroundPixmapBackgroundPixmapstring\(dg\(dgvaries\(dg +bottomShadowColorForegroundcolorvaries\(dg +bottomShadowPixmapForegroundstring\(dg\(dgvaries\(dg +fontListFontListT{ +string\(dg\(dg\(dg +T}"fixed" +foregroundForegroundcolorvaries\(dg +saveUnderSaveUnderT/FF +topShadowColorBackgroundcolorvaries\(dg +topShadowPixmapTopShadowPixmapstring\(dg\(dgvaries\(dg +.TE +.PP +\(dgThe default is chosen based on the visual type of the screen\&. +\(dg\(dgImage name\&. See \fBXmInstallImage\fP(3)\&. \(dg\(dg\(dgX11 +X Logical Font Description +.IP "\fIbackground\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the background color\&. Any legal X color may +be specified\&. The default value is chosen based on the visual type of the +screen\&. +.IP "\fIbackgroundPixmap\fP\ (class\ \fIBackgroundPixmap\fP)" 10 +This resource specifies the background Pixmap of the \fBmwm\fP +decoration when the window is inactive (does not have the keyboard focus)\&. +The default value is chosen based on the visual type of the screen\&. +.IP "\fIbottomShadowColor\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the bottom shadow color\&. This color is used +for the lower and right bevels of the window manager decoration\&. Any legal +X color may be specified\&. The default value is chosen based on the visual +type of the screen\&. +.IP "\fIbottomShadowPixmap\fP\ (class\ \fIBottomShadowPixmap\fP)" 10 +This resource specifies the bottom shadow Pixmap\&. This Pixmap is used +for the lower and right bevels of the window manager decoration\&. The default +is chosen based on the visual type of the screen\&. +.IP "\fIfontList\fP\ (class\ \fIFontList\fP)" 10 +This resource specifies the font used in the window manager decoration\&. +The character encoding of the font should match the character encoding of +the strings that are used\&. The default is "fixed\&." +.IP "\fIforeground\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the foreground color\&. The default is chosen +based on the visual type of the screen\&. +.IP "\fIsaveUnder\fP\ (class\ \fISaveUnder\fP)" 10 +This is used to indicate whether "save unders" are used for \fBmwm\fP components\&. For this to have any effect, save unders must be +implemented by the X server\&. If save unders are implemented, the X server +saves the contents of windows obscured by windows that have the save under +attribute set\&. If the \fIsaveUnder\fP resource is True, \fBmwm\fP will set the save under attribute on the window manager frame +of any client that has it set\&. If \fIsaveUnder\fP is False, +save unders will not be used on any window manager frames\&. The default value +is False\&. +.IP "\fItopShadowColor\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the top shadow color\&. This color is used for +the upper and left bevels of the window manager decoration\&. The default is +chosen based on the visual type of the screen\&. +.IP "topShadowPixmap\ (\ class\ \fITopShadowPixmap)\fP" 10 +This resource specifies the top shadow Pixmap\&. This Pixmap is used for +the upper and left bevels of the window manager decoration\&. The default is +chosen based on the visual type of the screen\&. +.PP +The following component appearance resources that apply to frame and +icons can be specified: +.SS "Frame and Icon Components" +.TS +tab(); +lw(2.072144i) lw(1.653307i) lw(0.991984i) lw(0.782565i). +NameClassValue TypeDefault +activeBackgroundBackgroundcolorvaries\(dg +activeBackgroundPixmapBackgroundPixmapstring\(dg\(dgvaries\(dg +activeBottomShadowColorForegroundcolorvaries\(dg +activeBottomShadowPixmapBottomShadowPixmapstring\(dg\(dgvaries\(dg +activeForegroundForegroundcolorvaries\(dg +activeTopShadowColorBackgroundcolorvaries\(dg +activeTopShadowPixmapTopShadowPixmapstring\(dg\(dgvaries\(dg +.TE +.PP +\(dgThe default is chosen based on the visual type of the screen\&. +\(dg\(dgSee \fBXmInstallImage\fP(3)\&. +.IP "\fIactiveBackground\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the background color of the \fBmwm\fP +decoration when the window is active (has the keyboard focus)\&. The default +is chosen based on the visual type of the screen\&. +.IP "\fIactiveBackgroundPixmap\fP\ (class\ \fIActiveBackgroundPixmap\fP)" 10 +This resource specifies the background Pixmap of the \fBmwm\fP +decoration when the window is active (has the keyboard focus)\&. The default +is chosen based on the visual type of the screen\&. +.IP "\fIactiveBottomShadowColor\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the bottom shadow color of the \fBmwm\fP decoration when the window is active (has the keyboard focus)\&. +The default is chosen based on the visual type of the screen\&. +.IP "\fIactiveBottomShadowPixmap\fP\ (class\ \fIBottomShadowPixmap\fP)" 10 +This resource specifies the bottom shadow Pixmap of the \fBmwm\fP decoration when the window is active (has the keyboard focus)\&. +The default is chosen based on the visual type of the screen\&. +.IP "\fIactiveForeground\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the foreground color of the \fBmwm\fP +decoration when the window is active (has the keyboard focus)\&. The default +is chosen based on the visual type of the screen\&. +.IP "\fIactiveTopShadowColor\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the top shadow color of the \fBmwm\fP +decoration when the window is active (has the keyboard focus)\&. The default +is chosen based on the visual type of the screen\&. +.IP "\fIactiveTopShadowPixmap\fP\ (class\ \fITopShadowPixmap\fP)" 10 +This resource specifies the top shadow Pixmap of the \fBmwm\fP +decoration when the window is active (has the keyboard focus)\&. The default +is chosen based on the visual type of the screen\&. +.SS "General Appearance and Behavior Resources" +.PP +The syntax for specifying general appearance and behavior resources +is \fIMwm*\fP\fBresource_id\fP +.PP +For example, \fIMwm*keyboardFocusPolicy\fP specifies +the window manager policy for setting the keyboard focus to a particular client +window\&. +.PP +The following general appearance and behavior resources can be specified: +.SS "General Appearance and Behavior Resources" +.TS +tab(); +lw(1.528376i) lw(1.592955i) lw(1.054795i) lw(1.323875i). +NameClassValue TypeDefault +autoKeyFocusAutoKeyFocusT/FT +autoRaiseDelayAutoRaiseDelaymillisec500 +bitmap-Bitmap-directory/usr/X11R6/include- +DirectoryDirectory/X11/bitmaps +clientAutoPlaceClientAutoPlaceT/FT +colormapFocus-ColormapFocus-stringkeyboard +PolicyPolicy +configFileConfigFilefile$HOME/mwmrc +deiconifyKeyFocusDeiconifyKeyFocusT/FT +doubleClick-DoubleClick-millisec\&.multi-click +TimeTimetime\(dg +enableWarpenableWarpT/FT +enforceKeyFocusEnforceKeyFocusT/FT +frameStyleFrameStylestringrecessed +iconAutoPlaceIconAutoPlaceT/FT +iconClickIconClickT/FT +interactivePlacementInteractivePlacementT/FT +keyboardFocus-KeyboardFocus-stringexplicit +PolicyPolicy +lowerOnIconifyLowerOnIconifyT/FT +moveThresholdMoveThresholdpixels4 +multiScreenMultiScreenT/FF +passButtonsPassButtonsT/FF +passSelectButtonPassSelectButtonT/FT +positionIsFramePositionIsFrameT/FT +positionOnScreenPositionOnScreenT/FT +quitTimeoutQuitTimeoutmillisec\&.1000 +raiseKeyFocusRaiseKeyFocusT/FF +refreshByClearingRefreshByClearingT/FT +rootButtonClickRootButtonClickT/FF +screensScreensstringvaries +sessionClientDBSessionClientDBstring$HOME/\&.mwmclientdb +showFeedbackShowFeedbackstringall +startupKeyFocusStartupKeyFocusT/FT +wMenuButtonClickWMenuButtonClickT/FT +wMenuButtonClick2WMenuButtonClick2T/FT +.TE +.PP +\(dgThe resource doubleClickTime is included for backward compatibility\&. +Use of the Xt resource multiClickTime is preferred\&. +.IP "\fIautoKeyFocus\fP\ (class\ \fIAutoKeyFocus\fP)" 10 +This resource is available only when the keyboard input focus policy +is explicit\&. If \fIautoKeyFocus\fP is given a value of True, +then when a window with the keyboard input focus is withdrawn from window +management or is iconified, the focus is set to the previous window that had +the focus\&. If the value given is False, there is no automatic setting of the +keyboard input focus\&. It is recommended that both \fIautoKeyFocus\fP and \fIstartupKeyFocus\fP be True to work with +tear off menus\&. The default value is True\&. +.IP "\fIautoRaiseDelay\fP\ (class\ \fIAutoRaiseDelay\fP)" 10 +This resource is available only when the \fIfocusAutoRaise\fP +resource is True and the keyboard focus policy is pointer\&. The \fIautoRaiseDelay\fP resource specifies the amount of time (in milliseconds) +that \fBmwm\fP will wait before raising a window after it gets +the keyboard focus\&. The default value of this resource is 500 (ms)\&. +.IP "\fIbitmapDirectory\fP\ (class\ \fIBitmapDirectory\fP)" 10 +This resource identifies a directory to be searched for bitmaps referenced +by \fBmwm\fP resources\&. This directory is searched if a bitmap +is specified without an absolute pathname\&. The default value for this resource +is \fB/usr/X11R6/include/X11/bitmaps\fP\&. The directory \fB/usr/X11R6/include/X11/bitmaps\fP +represents the customary locations for this directory\&. The actual +location of this directory may vary on some systems\&. If the bitmap is not +found in the specified directory, \fBXBMLANGPATH\fP is searched\&. +.IP "\fIclientAutoPlace\fP\ (class\ \fIClientAutoPlace\fP)" 10 +This resource determines the position of a window when the window has +not been given a program- or user-specified position\&. With a value of True, +windows are positioned with the top left corners of the frames offset horizontally +and vertically\&. A value of False causes the currently configured position +of the window to be used\&. In either case, \fBmwm\fP will attempt +to place the windows totally on-screen\&. The default value is True\&. +.IP "\fIcolormapFocusPolicy\fP\ (class\ \fIColormapFocusPolicy\fP)" 10 +This resource indicates the colormap focus policy that is to be used\&. +If the resource value is explicit, a colormap selection action is done on +a client window to set the colormap focus to that window\&. If the value is +pointer, the client window containing the pointer has the colormap focus\&. +If the value is keyboard, the client window that has the keyboard input focus +has the colormap focus\&. The default value for this resource is keyboard\&. +.IP "\fIconfigFile\fP\ (class\ \fIConfigFile\fP)" 10 +The resource value is the pathname for a \fBmwm\fP resource +description file\&. If the pathname begins with "~/", \fBmwm\fP +considers it to be relative to the user\&'s home directory (as specified by +the \fBHOME\fP environment variable)\&. +If the \fBLANG\fP environment variable +is set, \fBmwm\fP looks for \fI$HOME/$LANG\fP/ \fBconfigFile\fP\&. If that file does not exist or if \fBLANG\fP is not set, \fBmwm\fP looks for +\fB$HOME\fP/\fBconfigFile\fP\&. If the \fIconfigFile\fP pathname does not begin with "~/" or "/", \fBmwm\fP considers it to be relative to the current working directory\&. If +the \fIconfigFile\fP resource is not specified +or if that file does not exist, \fBmwm\fP uses several default +paths to find a configuration file\&. The order of the search is shown below: \fB/usr/X11R6/lib/X11/$LANG/system\&.mwmrc\fP\(dg +\fB/usr/X11R6/lib/X11/system\&.mwmrc\fP\(dg Paths marked with \&'\(dg\&' are +implementation dependent\&. +.IP "\fIdeiconifyKeyFocus\fP\ (class\ \fIDeiconifyKeyFocus\fP)" 10 +This resource applies only when the keyboard input focus policy is explicit\&. +If a value of True is used, a window receives the keyboard input focus when +it is normalized (deiconified)\&. True is the default value\&. +.IP "\fIdoubleClickTime\fP\ (class\ \fIDoubleClickTime\fP)" 10 +This resource is used to set the maximum time (in ms) between the clicks +(button presses) that make up a double-click\&. The use of this resource is +deprecated\&. Use the Xt resource \fImultiClickTime\fP instead\&. +The value of \fIdoubleClickTime\fP dynamically defaults to +the value of \fImultiClickTime\fP\&. +.IP "\fIenableWarp\fP\ (class\ \fIEnableWarp\fP)" 10 +The default value of this resource, True, causes \fBmwm\fP +to warp the pointer to the center of the selected window during keyboard-controlled +resize and move operations\&. Setting the value to False causes \fBmwm\fP to leave the pointer at its original place on the screen, unless +the user explicitly moves it with the cursor keys or pointing device\&. +.IP "\fIenforceKeyFocus\fP\ (class\ \fIEnforceKeyFocus\fP)" 10 +If this resource is given a value of True, the keyboard input focus +is always explicitly set to selected windows even if there is an indication +that they are "globally active" input windows\&. (An example of a globally active +window is a scroll bar that can be operated without setting the focus to that +client\&.) If the resource is False, the keyboard input focus is not explicitly +set to globally active windows\&. The default value is True\&. +.IP "\fIframeStyle\fP\ (class\ \fIframeStyle\fP)" 10 +If this resource is given a value of "slab", the the window manager +frame is drawn such that the client area appears to be at the same height +as the top of the window frame\&. If the resource is set to "recessed", the +window frame is drawn such that the client area appears lower than the top +of the window frame\&. The default value is "recessed"\&. +.IP "\fIiconAutoPlace\fP\ (class\ \fIIconAutoPlace\fP)" 10 +This resource indicates whether the window manager arranges icons in +a particular area of the screen or places each icon where the window was when +it was iconified\&. The value True indicates that icons are arranged in a particular +area of the screen, determined by the \fIiconPlacement\fP resource\&. +The value False indicates that an icon is placed at the location of the window +when it is iconified\&. The default is True\&. +.IP "\fIiconClick\fP\ (class\ \fIIconClick\fP)" 10 +When this resource is given the value of True, the system menu is posted +and left posted when an icon is clicked\&. The default value is True\&. +.IP "\fIinteractivePlacement\fP\ (class\ \fIInteractivePlacement\fP)" 10 +This resource controls the initial placement of new windows on the screen\&. +If the value is True, the pointer shape changes before a new window is placed +on the screen to indicate to the user that a position should be selected for +the upper-left hand corner of the window\&. If the value is False, windows are +placed according to the initial window configuration attributes\&. The default +value of this resource is False\&. +.IP "\fIkeyboardFocusPolicy\fP\ (class\ \fIKeyboardFocusPolicy\fP)" 10 +If set to pointer, the keyboard focus policy is to have the keyboard +focus set to the client window that contains the pointer (the pointer could +also be in the client window decoration that \fBmwm\fP adds)\&. +If set to explicit, the policy is to have the keyboard focus set to a client +window when the user presses button 1 with the pointer on the client window +or any part of the associated \fBmwm\fP decoration\&. The default +value for this resource is explicit\&. +.IP "\fIlowerOnIconify\fP\ (class\ \fILowerOnIconify\fP)" 10 +If this resource is given the default value of True, a window\&'s icon +appears on the bottom of the window stack when the window is minimized (iconified)\&. +A value of False places the icon in the stacking order at the same place as +its associated window\&. The default value of this resource is True\&. +.IP "\fImoveThreshold\fP\ (class\ \fIMoveThreshold\fP)" 10 +This resource is used to control the sensitivity of dragging operations +that move windows and icons\&. The value of this resource is the number of pixels +that the locator is moved with a button down before the move operation is +initiated\&. This is used to prevent window/icon movement when you click or +double-click and there is unintentional pointer movement with the button down\&. +The default value of this resource is 4 (pixels)\&. +.IP "\fImultiScreen\fP\ (class\ \fIMultiScreen\fP)" 10 +This resource, if True, causes \fBmwm\fP to manage all +the screens on the display\&. If False, \fBmwm\fP manages only +a single screen\&. The default value is False\&. +.IP "\fIpassButtons\fP\ (class\ \fIPassButtons\fP)" 10 +This resource indicates whether or not button press events are passed +to clients after they are used to do a window manager function in the client +context\&. If the resource value is False, the button press is not passed to +the client\&. If the value is True, the button press is passed to the client +window\&. The window manager function is done in either case\&. The default value +for this resource is False\&. +.IP "\fIpassSelectButton\fP\ (class\ \fIPassSelectButton\fP)" 10 +This resource indicates whether or not to pass the select button press +events to clients after they are used to do a window manager function in the +client context\&. If the resource value is False, then the button press will +not be passed to the client\&. If the value is True, the button press is passed +to the client window\&. The window manager function is done in either case\&. +The default value for this resource is True\&. +.IP "\fIpositionIsFrame\fP\ (class\ \fIPositionIsFrame\fP)" 10 +This resource indicates how client window position information (from +the \fIWM_NORMAL_HINTS\fP property and from configuration requests) +is to be interpreted\&. If the resource value is True, the information is interpreted +as the position of the \fBmwm\fP client window frame\&. If the +value is False, it is interpreted as being the position of the client area +of the window\&. The default value of this resource is True\&. +.IP "\fIpositionOnScreen\fP\ (class\ \fIPositionOnScreen\fP)" 10 +This resource is used to indicate that windows should initially be placed +(if possible) so that they are not clipped by the edge of the screen (if the +resource value is True)\&. If a window is larger than the size of the screen, +at least the upper-left corner of the window is on-screen\&. If the resource +value is False, windows are placed in the requested position even if totally +off-screen\&. The default value of this resource is True\&. +.IP "\fIquitTimeout\fP\ (class\ \fIQuitTimeout\fP)" 10 +This resource specifies the amount of time (in milliseconds) that \fBmwm\fP will wait for a client to update the \fIWM_COMMAND\fP +property after \fBmwm\fP has sent the \fBWM_SAVE_YOURSELF\fP message\&. The default value of this resource is 1000 (ms)\&. (Refer +to the \fBf\&.kill\fP function description for additional information\&.) +.IP "\fIraiseKeyFocus\fP\ (class\ \fIRaiseKeyFocus\fP)" 10 +This resource is available only when the keyboard input focus policy +is explicit\&. When set to True, this resource specifies that a window raised +by means of the \fBf\&.normalize_and_raise\fP function also receives +the input focus\&. The default value of this resource is False\&. +.IP "\fIrefreshByClearing\fP\ (class\ \fIRefreshByClearing\fP)" 10 +This resource determines the mechanism used to refresh a window (or +the screen) when the \fBf\&.refresh_win\fP (\fBf\&.refresh\fP) function is executed\&. When set to True, an XClearArea is performed +over the window for \fBf\&.refresh_win\fP\&. When set to False, +a covering window is created and destroyed over the top of the window to be +refreshed\&. If the function is \fBf\&.refresh\fP and this resource +is set to True, then an XClearArea is performed over every window on the screen\&. +If the resource is set to False, then one large window covering the entire +screen is created and destroyed\&. The default value of this resource is True\&. +.IP "\fIrootButtonClick\fP\ (class\ \fIRootButtonClick\fP)" 10 +The \fIrootButtonClick\fP resource controls whether the +a click on the root window will post the root menu in a "sticky" mode\&. If +this resource is set to True, a button click on the root window will post +the menu bound to the button down event for that button in a "sticky" fashion\&. +If this resource is set to False, then the same button click would only cause +the menu to flash as it would be unposted once the button up event is seen\&. +The criterion used to determine if it is a button click is if the pointer +doesn\&'t move between the button down and button up events\&. The default value +for this resource is True\&. +.IP "\fIscreens\fP\ (class\ \fIScreens\fP)" 10 +This resource specifies the resource names to use for the screens managed +by \fBmwm\fP\&. If \fBmwm\fP is managing a single +screen, only the first name in the list is used\&. If \fBmwm\fP +is managing multiple screens, the names are assigned to the screens in order, +starting with screen 0\&. Screen 0 gets the first name, screen 1 the second +name, and so on\&. The default screen names are 0, 1, and so on\&. +.IP "\fIsessionClientDB\fP\ (class\ \fISessionClientDB\fP)" 10 +This resource identifies a file name to use as a root when saving state +at the request of an XSMP session manager\&. When the session is saved, the window manager will then reuse +the file name by automatically incrementing a suffix\&. +.IP "\fIshowFeedback\fP\ (class\ \fIShowFeedback\fP)" 10 +This resource controls whether or not feedback windows or confirmation +dialogs are displayed\&. A feedback window shows a client window\&'s initial +placement and shows position and size during move and resize operations\&. +Confirmation dialogs can be displayed for certain operations\&. The value for +this resource is a list of names of the feedback options to be enabled or +disabled; the names must be separated by a space\&. If an option is preceded +by a minus sign, that option is excluded from the list\&. The \fBsign\fP of the first item in the list determines the initial set of options\&. +If the sign of the first option is minus, \fBmwm\fP assumes +all options are present and starts subtracting from that set\&. If the sign +of the first decoration is plus (or not specified), \fBmwm\fP +starts with no options and builds up a list from the resource\&. +.PP +The names of the feedback options are shown below: +.TS +tab(); +lw(1.097588i) lw(4.402412i). +NameDescription +allShow all feedback (Default value)\&. +behaviorConfirm behavior switch\&. +killConfirm on receipt of KILL signal\&. +moveShow position during move\&. +noneShow no feedback\&. +placementT{ +Show position and size during initial placement\&. +T} +quitConfirm quitting \fBmwm\fP\&. +resizeShow size during resize\&. +restartConfirm \fBmwm\fP restart\&. +.TE +.PP +The following command line illustrates the syntax for showFeedback: +.PP +.nf +\f(CW\fIMwm*showFeedback: placement resize behavior restart\fP\fR +.fi +.PP +.PP +This resource specification provides feedback for initial client placement +and resize, and enables the dialog boxes to confirm the restart and set behavior +functions\&. It disables feedback for the move function\&. The default value for +this resource is all\&. +.IP "\fIstartupKeyFocus\fP\ (class\ \fIStartupKeyFocus\fP)" 10 +This resource is available only when the keyboard input focus policy +is explicit\&. When given the default value of True, a window gets the keyboard +input focus when the window is mapped (that is, initially managed by the window +manager)\&. It is recommended that both \fIautoKeyFocus\fP and \fIstartupKeyFocus\fP be True to work with tear off menus\&. The default +value is True\&. +.IP "\fIwMenuButtonClick\fP\ (class\ \fIWMenuButtonClick\fP)" 10 +This resource indicates whether a click of the mouse when the pointer +is over the window menu button posts and leaves posted the window menu\&. If +the value given this resource is True, the menu remains posted\&. True is the +default value for this resource\&. +.IP "\fIwMenuButtonClick2\fP\ (class\ \fIWMenuButtonClick2\fP)" 10 +When this resource is given the default value of True, a double-click +action on the window menu button does an \fIf\&.kill function\fP\&. +.SS "Screen Specific Appearance and Behavior Resources" +.PP +The syntax for specifying screen specific resources is \fIMwm*\fP \fBscreen_name\fP\fI*\fP\fBresource_id\fP For example, \fIMwm*1*keyBindings\fP specifies +the key bindings to use for screen "1"\&. +.SS "Screen Specific Resources" +.TS +tab(); +lw(1.768627i) lw(1.790196i) lw(0.927451i) lw(1.013725i). +NameClassValue TypeDefault +buttonBindingsButtonBindingsstringDefaultButtonBindings +cleanTextCleanTextT/FT +fadeNormalIconFadeNormalIconT/FF +feedbackGeometryFeedbackGeometrystringcenter on screen +frameBorderWidthFrameBorderWidthpixelsvaries +iconBoxGeometryIconBoxGeometrystring6x1+0-0 +iconBoxNameIconBoxNamestringiconbox +iconBoxSBDisplayPolicyIconBoxSBDisplayPolicystringall +iconBoxTitleIconBoxTitleXmStringIcons +iconDecorationIconDecorationstringvaries +iconImageMaximumIconImageMaximumwxh48x48 +iconImageMinimumIconImageMinimumwxh16x16 +iconPlacementIconPlacementstringleft bottom +iconPlacementMarginIconPlacementMarginpixelsvaries +keyBindingsKeyBindingsstringDefaultKeyBindings +limitResizeLimitResizeT/FT +maximumMaximumSizeMaximumMaximumSizewxh (pixels)2X screen w&h +moveOpaqueMoveOpaqueT/FF +resizeBorderWidthResizeBorderWidthpixelsvaries +resizeCursorsResizeCursorsT/FT +transientDecorationTransientDecorationstringmenu title +transientFunctionsTransientFunctionsstringT{ +-minimize-maximize +T} +useIconBoxUseIconBoxT/FF +.TE +.IP "\fIbuttonBindings\fP\ (class\ \fIButtonBindings\fP)" 10 +This resource identifies the set of button bindings for window management +functions\&. The named set of button bindings is specified in the \fBmwm\fP resource description file\&. These button bindings are \fBmerged\fP with the built-in default bindings\&. The default value for +this resource is "DefaultButtonBindings"\&. +.IP "\fIcleanText\fP\ (class\ \fICleanText\fP)" 10 +This resource controls the display of window manager text in the client +title and feedback windows\&. If the default value of True is used, the text +is drawn with a clear (no stipple) background\&. This makes text easier to read +on monochrome systems where a backgroundPixmap is specified\&. Only the stippling +in the area immediately around the text is cleared\&. If False, the text is +drawn directly on top of the existing background\&. +.IP "\fIfadeNormalIcon\fP\ (class\ \fIFadeNormalIcon\fP)" 10 +If this resource is given a value of True, an icon is grayed out whenever +it has been normalized (its window has been opened)\&. The default value is +False\&. +.IP "\fIfeedbackGeometry\fP\ (class\ \fIFeedbackGeometry\fP)" 10 +This resource sets the position of the move and resize feedback window\&. +If this resource is not specified, the default is to place the feedback window +at the center of the screen\&. The value of the resource is a standard window +geometry string with the following syntax: [\fI=\fP]{ \fI+-\fP}\fBxoffset\fP{\fI+-\fP} \fByoffset\fP] +.IP "\fIframeBorderWidth\fP\ (class\ \fIFrameBorderWidth\fP)" 10 +This resource specifies the width (in pixels) of a client window frame +border without resize handles\&. The border width includes the 3-D shadows\&. +The default value is based on the size and resolution of the screen\&. +.IP "\fIiconBoxGeometry\fP\ (class\ \fIIconBoxGeometry\fP)" 10 +This resource indicates the initial position and size of the icon box\&. +The value of the resource is a standard window geometry string with the following +syntax: [\fI=\fP][\fBwidth\fP \fIx\fP\fBheight\fP][{\fI+-\fP}\fBxoffset\fP {\fI+-\fP}\fByoffset\fP] If the offsets +are not provided, the iconPlacement policy is used to determine the initial +placement\&. The units for width and height are columns and rows\&. The actual +screen size of the icon box window depends on the iconImageMaximum (size) +and \fIiconDecoration\fP resources\&. The default value for size +is (6 * iconWidth + padding) wide by (1 * iconHeight + padding) high\&. The +default value of the location is +0 -0\&. +.IP "\fIiconBoxName\fP\ (class\ \fIIconBoxName\fP)" 10 +This resource specifies the name that is used to look up icon box resources\&. +The default name is iconbox\&. +.IP "\fIiconBoxSBDisplayPolicy\fP\ (class\ \fIIconBoxSBDisplayPolicy\fP)" 10 +This resource specifies the scroll bar display policy of the window +manager in the icon box\&. The resource has three possible values: all, vertical, +and horizontal\&. The default value, "all", causes both vertical and horizontal +scroll bars always to appear\&. The value "vertical" causes a single vertical +scroll bar to appear in the icon box and sets the orientation of the icon +box to horizontal (regardless of the iconBoxGeometry specification)\&. The value +"horizontal" causes a single horizontal scroll bar to appear in the icon box +and sets the orientation of the icon box to vertical (regardless of the iconBoxGeometry +specification)\&. +.IP "\fIiconBoxTitle\fP\ (class\ \fIIconBoxTitle\fP)" 10 +This resource specifies the name that is used in the title area of the +icon box frame\&. The default value is Icons\&. +.IP "\fIiconDecoration\fP\ (class\ \fIIconDecoration\fP)" 10 +This resource specifies the general icon decoration\&. The resource value +is label (only the label part is displayed) or image (only the image part +is displayed) or label image (both the label and image parts are displayed)\&. +A value of activelabel can also be specified to get a label (not truncated +to the width of the icon) when the icon is selected\&. The default icon decoration +for icon box icons is that each icon has a label part and an image part (label +image)\&. The default icon decoration for stand alone icons is that each icon +has an active label part, a label part, and an image part (activelabel label +image)\&. +.IP "\fIiconImageMaximum\fP\ (class\ \fIIconImageMaximum\fP)" 10 +This resource specifies the maximum size of the icon image\&. The resource +value is \fBwidth\fP\fIx\fP \fBheight\fP (for example, 64x64)\&. The maximum supported size is 128x128\&. +The default value of this resource is 50x50\&. +.IP "\fIiconImageMinimum\fP\ (class\ \fIIconImageMinimum\fP)" 10 +This resource specifies the minimum size of the icon image\&. The resource +value is \fBwidth\fP\fIx\fP \fBheight\fP (for example, 32x50)\&. The minimum supported size is 16x16\&. +The default value of this resource is 16x16\&. +.IP "\fIiconPlacement\fP\ (class\ \fIIconPlacement\fP)" 10 +This resource specifies the icon placement scheme to be used\&. The resource +value has the following syntax: +.IP "" 10 +\fBprimary_layout secondary_layout [tight]\fP +.PP +The layout values are one of the following: +.TS +tab(); +lw(0.796053i) lw(4.703947i). +ValueDescription +topLay the icons out top to bottom\&. +bottomLay the icons out bottom to top\&. +leftLay the icons out left to right\&. +rightLay the icons out right to left\&. +.TE +.PP +A horizontal (vertical) layout value should not be used for both the \fBprimary_layout\fP and the \fBsecondary_layout\fP (for +example, don\&'t use top for the \fBprimary_layout\fP and bottom +for the \fBsecondary_layout\fP)\&. +.PP +The \fBprimary_layout\fP indicates whether, when an icon +placement is done, the icon is placed in a row or a column and the direction +of placement\&. The \fBsecondary_layout\fP indicates where to place +new rows or columns\&. For example, top right indicates that icons should be +placed top to bottom on the screen and that columns should be added from right +to left on the screen\&. +.PP +The default placement is left bottom (icons are placed left to right +on the screen, with the first row on the bottom of the screen, and new rows +added from the bottom of the screen to the top of the screen)\&. A \fBtight\fP value places icons with zero spacing in between icons\&. This +value is useful for aesthetic reasons, as well as X-terminals with small screens\&. +.IP "\fIiconPlacementMargin\fP\ (class\ \fIIconPlacementMargin\fP)" 10 +This resource sets the distance between the edge of the screen and the +icons that are placed along the edge of the screen\&. The value should be greater +than or equal to 0\&. A default value (see below) is used if the value specified +is invalid\&. The default value for this resource is equal to the space between +icons as they are placed on the screen (this space is based on maximizing +the number of icons in each row and column)\&. +.IP "\fIkeyBindings\fP\ (class\ \fIKeyBindings\fP)" 10 +This resource identifies the set of key bindings for window management +functions\&. If specified, these key bindings \fBreplace\fP the +built-in default bindings\&. The named set of key bindings is specified in \fBmwm\fP resource description file\&. The default value for this resource +is "DefaultKeyBindings"\&. +.IP "\fIlimitResize\fP\ (class\ \fILimitResize\fP)" 10 +If this resource is True, the user is not allowed to resize a window +to greater than the maximum size\&. The default value for this resource is True\&. +.IP "\fImaximumMaximumSize\fP\ (class\ \fIMaximumMaximumSize\fP)" 10 +This resource is used to limit the maximum size of a client window as +set by the user or client\&. The resource value is \fBwidth\fP\fIx\fP\fBheight\fP (for example, 1024x1024) +where the width and height are in pixels\&. The default value of this resource +is twice the screen width and height\&. +.IP "\fImoveOpaque\fP\ (class\ \fIMoveOpaque\fP)" 10 +This resource controls whether the actual window is moved or a rectangular +outline of the window is moved\&. A default value of False displays a rectangular +outline on moves\&. +.IP "\fIresizeBorderWidth\fP\ (class\ \fIResizeBorderWidth\fP)" 10 +This resource specifies the width (in pixels) of a client window frame +border with resize handles\&. The specified border width includes the 3-D shadows\&. +The default value is based on the size and resolution of the screen\&. +.IP "\fIresizeCursors\fP\ (class\ \fIResizeCursors\fP)" 10 +This is used to indicate whether the resize cursors are always displayed +when the pointer is in the window size border\&. If True, the cursors are shown, +otherwise the window manager cursor is shown\&. The default value is True\&. +.IP "\fItransientDecoration\fP\ (class\ \fITransientDecoration\fP)" 10 +This controls the amount of decoration that \fBmwm\fP +puts on transient windows\&. The decoration specification is exactly the same +as for the \fIclientDecoration\fP (client specific) resource\&. +Transient windows are identified by the \fIWM_TRANSIENT_FOR\fP +property, which is added by the client to indicate a relatively temporary +window\&. The default value for this resource is menu title (that is, transient +windows have frame borders and a titlebar with a window menu button)\&. +.IP "" 10 +An application can also specify which decorations \fBmwm\fP +should apply to its windows\&. If it does so, \fBmwm\fP applies +only those decorations indicated by both the application and the \fItransientDecoration\fP resource\&. Otherwise, \fBmwm\fP +applies the decorations indicated by the \fItransientDecoration\fP +resource\&. For more information see the description of \fBXmNmwmDecorations\fP on the \fBVendorShell\fP(3) +reference page\&. +.IP "\fItransientFunctions\fP\ (class\ \fITransientFunctions\fP)" 10 +This resource is used to indicate which window management functions +are applicable (or not applicable) to transient windows\&. The function specification +is exactly the same as for the \fIclientFunctions\fP (client +specific) resource\&. The default value for this resource is -minimize -maximize\&. +.IP "" 10 +An application can also specify which functions \fBmwm\fP +should apply to its windows\&. If it does so, \fBmwm\fP applies +only those functions indicated by both the application and the \fItransientFunctions\fP resource\&. Otherwise, \fBmwm\fP +applies the functions indicated by the \fItransientFunctions\fP +resource\&. For more information see the description of \fBXmNmwmFunctions\fP on the \fBVendorShell\fP(3) reference +page\&. +.IP "\fIuseIconBox\fP\ (class\ \fIUseIconBox\fP)" 10 +If this resource is given a value of True, icons are placed in an icon +box\&. When an icon box is not used, the icons are placed on the root window +(default value)\&. +.SS "Client Specific Resources" +.PP +The syntax for specifying client specific resources is +.PP +\fIMwm*\fP\fBclient_name_or_class\fP \fI*\fP\fBresource_id\fP +.PP +For example, \fIMwm*mterm*windowMenu\fP is used to specify +the window menu to be used with mterm clients\&. The syntax for specifying client +specific resources for all classes of clients is +.PP +\fIMwm*\fP\fBresource_id\fP +.PP +Specific client specifications take precedence over the specifications +for all clients\&. For example, \fIMwm*windowMenu\fP is used +to specify the window menu to be used for all classes of clients that don\&'t +have a window menu specified\&. +.PP +The syntax for specifying resource values for windows that have an unknown +name and class (that is, windows that do not have a \fBWM_CLASS\fP +property associated with them) is +.PP +\fIMwm*defaults*\fP\fBresource_id\fP +.PP +For example, \fIMwm*defaults*iconImage\fP is used to +specify the icon image to be used for windows that have an unknown name and +class\&. +.PP +The following client specific resources can be specified: +.SS "Client Specific Resources" +.TS +tab(); +lw(1.999018i) lw(1.458743i) lw(0.918468i) lw(1.123772i). +NameClassValue TypeDefault +clientDecorationClientDecorationstringall\&. +clientFunctionsClientFunctionsstringall\&. +focusAutoRaiseFocusAutoRaiseT/Fvaries +iconImageIconImagepathname(image) +iconImage-Backgroundcoloricon background +Background +iconImageBottom-Foregroundcoloricon +ShadowColorbottom shadow +iconImageBottom-BottomShadow-coloricon bottom +ShadowPixmapPixmapshadow pixmap +iconImageForegroundForegroundcolorvaries +iconImageTopShadowColorBackgroundcoloricon top +shadow color +iconImageTop-TopShadowPixmapcoloricon top +ShadowPixmapshadow pixmap +matteBackgroundBackgroundcolorbackground +matteBottom-Foregroundcolorbottom +ShadowColorshadow color +matteBottom-BottomShadow-colorbottom +ShadowPixmapPixmapshadow pixmap +matteForegroundForegroundcolorforeground +matteTopShadowColorBackgroundcolortop +shadow color +matteTopShadowPixmapTopShadowPixmapcolortop +shadow pixmap +matteWidthMatteWidthpixels0 +maximumClientSizeMaximumClientSizewxh +vertical horizontalfill the screen +useClientIconUseClientIconT/FT +usePPositionUsePPositionstringnonzero +windowMenuWindowMenustringDefaultWindowMenu +.TE +.IP "\fIclientDecoration\fP\ (class\ \fIClientDecoration\fP)" 10 +This resource controls the amount of window frame decoration\&. The resource +is specified as a list of decorations to specify their inclusion in the frame\&. +If a decoration is preceded by a minus sign, that decoration is excluded from +the frame\&. The \fBsign\fP of the first item in the list determines +the initial amount of decoration\&. If the sign of the first decoration is minus, \fBmwm\fP assumes all decorations are present and starts subtracting +from that set\&. If the sign of the first decoration is plus (or not specified), +then \fBmwm\fP starts with no decoration and builds up a list +from the resource\&. +.IP "" 10 +An application can also specify which decorations \fBmwm\fP +should apply to its windows\&. If it does so, \fBmwm\fP applies +only those decorations indicated by both the application and the \fIclientDecoration\fP resource\&. Otherwise, \fBmwm\fP applies +the decorations indicated by the \fIclientDecoration\fP resource\&. +For more information see the description of \fBXmNmwmDecorations\fP on the \fBVendorShell\fP(3) reference +page\&. +.TS +tab(); +lw(0.989035i) lw(4.510965i). +NameDescription +allT{ +Include all decorations (default value)\&. +T} +borderWindow border\&. +maximizeT{ +Maximize button (includes title bar)\&. +T} +minimizeT{ +Minimize button (includes title bar)\&. +T} +noneNo decorations\&. +resizehT{ +Border resize handles (includes border)\&. +T} +menuT{ +Window menu button (includes title bar)\&. +T} +titleTitle bar (includes border)\&. +.TE +.PP +Examples: \fIMwm*XClock\&.clientDecoration: -resizeh -maximize\fP This removes the resize handles and maximize button from XClock +windows\&. \fIMwm*XClock\&.clientDecoration: menu minimize border\fP This does the same thing as above\&. Note that either \fImenu\fP or \fIminimize\fP implies +\fItitle\fP\&. +.IP "\fIclientFunctions\fP\ (class\ \fIClientFunctions\fP)" 10 +This resource is used to indicate which \fBmwm\fP functions +are applicable (or not applicable) to the client window\&. The value for the +resource is a list of functions\&. If the first function in the list has a minus +sign in front of it, then \fBmwm\fP starts with all functions +and subtracts from that set\&. If the first function in the list has a plus +sign in front of it, then \fBmwm\fP starts with no functions +and builds up a list\&. Each function in the list must be preceded by the appropriate +plus or minus sign and separated from the next function by a space\&. +.IP "" 10 +An application can also specify which functions \fBmwm\fP +should apply to its windows\&. If it does so, \fBmwm\fP applies +only those functions indicated by both the application and the \fIclientFunctions\fP resource\&. Otherwise, \fBmwm\fP applies +the functions indicated by the \fIclientFunctions\fP resource\&. +For more information see the description of \fBXmNmwmFunctions\fP on the \fBVendorShell\fP(3) reference +page\&. +.PP +The following table lists the functions available for this resource: +.TS +tab(); +lw(0.928728i) lw(4.571272i). +NameDescription +allT{ +Include all functions (default value)\&. +T} +noneNo functions\&. +resizef\&.resize\(dg\&. +movef\&.move\(dg\&. +minimizef\&.minimize\(dg\&. +maximizef\&.maximize\(dg\&. +closef\&.kill\(dg\&. +.TE +.PP +\(dgSee \fBmwmrc\fP(4)\&. +.IP "\fIfocusAutoRaise\fP\ (class\ \fIFocusAutoRaise\fP)" 10 +When the value of this resource is True, clients are raised when they +get the keyboard input focus\&. If the value is False, the stacking of windows +on the display is not changed when a window gets the keyboard input focus\&. +The default value is True when the keyboardFocusPolicy is explicit and False +when the keyboardFocusPolicy is pointer\&. +.IP "\fIiconImage\fP\ (class\ \fIIconImage\fP)" 10 +This resource can be used to specify an icon image for a client (for +example, "Mwm*myclock*iconImage")\&. The resource value is a pathname for a +pixmap or bitmap file\&. The value of the (client specific) \fIuseClientIcon\fP resource is used to determine whether or not user supplied icon +images are used instead of client supplied icon images\&. The default value +is to display a built-in window manager icon image\&. +.IP "\fIiconImageBackground\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the background color of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +is the icon background color (that is, specified by "Mwm*background or Mwm*icon*background)\&. +.IP "\fIiconImageBottomShadowColor\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the bottom shadow color of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +is the icon bottom shadow color (that is, specified by Mwm*icon*bottomShadowColor)\&. +.IP "\fIiconImageBottomShadowPixmap\fP\ (class\ \fIBottomShadowPixmap\fP)" 10 +This resource specifies the bottom shadow Pixmap of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +is the icon bottom shadow Pixmap (that is, specified by Mwm*icon*bottomShadowPixmap)\&. +.IP "\fIiconImageForeground\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the foreground color of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +varies depending on the icon background\&. +.IP "\fIiconImageTopShadowColor\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the top shadow color of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +is the icon top shadow color (that is, specified by Mwm*icon*topShadowColor)\&. +.IP "\fIiconImageTopShadowPixmap\fP\ (class\ \fITopShadowPixmap\fP)" 10 +This resource specifies the top shadow Pixmap of the icon image that +is displayed in the image part of an icon\&. The default value of this resource +is the icon top shadow pixmap (that is, specified by Mwm*icon*topShadowPixmap)\&. +.IP "\fImatteBackground\fP\ \ (class\ \fIBackground\fP)" 10 +This resource specifies the background color of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client background color (that is, specified by "Mwm*background or Mwm*client*background)\&. +.IP "\fImatteBottomShadowColor\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the bottom shadow color of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client bottom shadow color (that is, specified by Mwm*bottomShadowColor or +Mwm*client*bottomShadowColor)\&. +.IP "\fImatteBottomShadowPixmap\fP\ (class\ \fIBottomShadowPixmap\fP)" 10 +This resource specifies the bottom shadow Pixmap of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client bottom shadow pixmap (that is, specified by Mwm*bottomShadowPixmap +or Mwm*client*bottomShadowPixmap)\&. +.IP "\fImatteForeground\fP\ (class\ \fIForeground\fP)" 10 +This resource specifies the foreground color of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client foreground color (that is, specified by Mwm*foreground or Mwm*client*foreground)\&. +.IP "\fImatteTopShadowColor\fP\ (class\ \fIBackground\fP)" 10 +This resource specifies the top shadow color of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client top shadow color (that is, specified by Mwm*topShadowColor or Mwm*client*topShadowColor)\&. +.IP "\fImatteTopShadowPixmap\fP\ (class\ \fITopShadowPixmap\fP)" 10 +This resource specifies the top shadow pixmap of the matte, when \fImatteWidth\fP is positive\&. The default value of this resource is the +client top shadow pixmap (that is, specified by "Mwm*topShadowPixmap or Mwm*client*topShadowPixmap)\&. +.IP "\fImatteWidth\fP\ (class\ \fIMatteWidth\fP)" 10 +This resource specifies the width of the optional matte\&. The default +value is 0, which effectively disables the matte\&. +.IP "\fImaximumClientSize\fP\ (class\ \fIMaximumClientSize\fP)" 10 +This resource is either a size specification or a direction that indicates +how a client window is to be maximized\&. The resource value can be specified +as a size specification \fBwidth\fP\fIx\fP\fBheight\fP\&. The width and height are interpreted in +the units that the client uses (for example, for terminal emulators this is +generally characters)\&. Alternately, "vertical" or "horizontal" can be specified +to indicate the direction in which the client maximizes\&. +.IP "" 10 +If this resource is not specified, the maximum size from the \fIWM_NORMAL_HINTS\fP property is used if set\&. Otherwise the default +value is the size where the client window with window management borders fills +the screen\&. When the maximum client size is not determined by the \fImaximumClientSize\fP resource, the \fImaximumMaximumSize\fP +resource value is used as a constraint on the maximum size\&. +.IP "\fIuseClientIcon\fP\ (class\ \fIUseClientIcon\fP)" 10 +If the value given for this resource is True, a client-supplied icon +image takes precedence over a user-supplied icon image\&. The default value +is True, giving the client-supplied icon image higher precedence than the +user-supplied icon image\&. +.IP "\fIusePPosition\fP\ (class\ \fIUsePPosition\fP)" 10 +This resource specifies whether Mwm honors program specified position \fBPPosition\fP specified in the \fIWM_NORMAL_HINTS\fP property in the absence of an user specified position\&. Setting +this resource to on, causes \fBmwm\fP to always honor program +specified position\&. Setting this resource to off, causes \fBmwm\fP +to always ignore program specified position\&. Setting this resource to the +default value of nonzero cause \fBmwm\fP to honor program specified +position other than (0,0)\&. +.IP "\fIwindowMenu\fP\ (class\ \fIWindowMenu\fP)" 10 +This resource indicates the name of the menu pane that is posted when +the window menu is popped up (usually by pressing button 1 on the window +menu button on the client window frame)\&. Menu panes are specified in the \fBmwm\fP resource description file\&. Window menus can be customized on +a client class basis by creating custom menus in your \fBmwmrc\fP +file (see \fBmwmrc\fP(4) and specifying resources to activate +the custom menus\&. The resources have the form \fIMwm*\fP \fBclient_name_or_class\fP\fI*windowMenu\fP\&. The default +value of this resource is DefaultWindowMenu\&. +.SS "Resource Description File" +.PP +The \fBmwm\fP resource description file is a supplementary +resource file that contains resource descriptions that are referred to by +entries in the resource manager property (see \fBxrdb\fP(1) and +the defaults files (\fB\&.Xdefaults\fP, \fBapp-defaults/Mwm\fP )\&. It contains descriptions of resources that are to be used by \fBmwm\fP, and that cannot be easily encoded in the defaults files (a +bitmap file is an analogous type of resource description file)\&. A particular \fBmwm\fP resource description file can be selected using the +\fIconfigFile\fP resource\&. +.PP +The following types of resources can be described in the \fBmwm\fP resource description file: +.IP "\fIButtons\fP" 10 +Window manager functions can be bound (associated) with button events\&. +.IP "\fIKeys\fP" 10 +Window manager functions can be bound (associated) with key press events\&. +.IP "\fIMenus\fP" 10 +Menu panes can be used for the window menu and other menus posted with +key bindings and button bindings\&. +.IP "" 10 +The \fBmwm\fP resource description file is described in \fBmwmrc\fP(4)\&. +.SS "Environment" +.PP +The \fBmwm\fP window manager uses the environment variable \fBHOME\fP specifying the user\&'s home directory\&. +.PP +The \fBmwm\fP window manager uses the environment variable \fBLANG\fP specifying the user\&'s choice of language +for the \fBmwm\fP message catalog and the \fBmwm\fP +resource description file\&. +.PP +The \fBmwm\fP window uses the environment variable \fBXFILESEARCHPATH\fP, \fBXUSERFILESEARCHPATH\fP, \fBXAPPLRESDIR\fP, \fBXENVIRONMENT\fP, \fBLANG\fP, and \fBHOME\fP in determining search paths for resource defaults files\&. +The \fBmwm\fP window manager may also us \fBXBMLANGPATH\fP to search for bitmap files\&. +.PP +The \fBmwm\fP window manager reads the \fB$HOME/\&.motifbind\fP +file if it exists to install a virtual key bindings property on +the root window\&. For more information on the content of the \fB\&.motifbind\fP file, see +.PP +The \fBmwm\fP window manager uses the environment variable +\fBMWMSHELL\fP (or \fBSHELL\fP, \fIif\fP \fBMWMSHELL\fP is not set), specifying +the shell to use when executing commands via the \fBf\&.exec\fP +function\&. +.SS "Files" +.PP +\fB/usr/X11R6/lib/X11/$LANG/system\&.mwmrc\fP +.PP +\fB/usr/X11R6/lib/X11/system\&.mwmrc\fP +.PP +\fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP +.PP +\fB$HOME/Mwm\fP +.PP +\fB$HOME/$LANG/\&.mwmrc\fP +.PP +\fB$HOME/\&.mwmrc\fP +.SS "RELATED INFORMATION" +.PP +\fBVendorShell\fP(3), \fBVirtualBindings\fP(3), \fBX\fP(1), \fBXmInstallImage\fP(3), \fBxrdb\fP(1)\&. +...\" created by instant / docbook-to-man, Sun 22 Dec 1996, 20:15 diff --git a/doc/man/man4/mwmrc.4 b/doc/man/man4/mwmrc.4 index e8de9f9..5d16fca 100644 --- a/doc/man/man4/mwmrc.4 +++ b/doc/man/man4/mwmrc.4 @@ -57,7 +57,7 @@ file that controls much of the behavior of the Motif window manager \fBmwm\fP\&. It contains descriptions of resources that cannot easily be written using standard X Window System, Version 11 resource syntax\&. The resource description file contains entries that are referred to by X resources in -defaults files (for example, \fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP) +defaults files (for example, \fB/usr/share/X11/app-defaults/Mwm\fP) or in the \fBRESOURCE_MANAGER\fP property on the root window\&. For example, the resource description file enables you to specify different types of window menus; however, an X resource is used to specify @@ -72,8 +72,8 @@ on a per-user basis: .nf \f(CW$HOME/$LANG/\&.mwmrc $HOME/\&.mwmrc -/usr/X11R6/lib/X11/$LANG/system\&.mwmrc -/usr/X11R6/lib/X11/system\&.mwmrc\fR +/etc/X11/mwm/$LANG/system\&.mwmrc +/etc/X11/mwm/system\&.mwmrc\fR .fi .PP .PP @@ -84,7 +84,7 @@ resource\&. The following shows how a different resource description file can be specified from the command line: .PP .nf -\f(CW/usr/X11R6/bin/X11/mwm -xrm "mwm*configFile: mymwmrc"\fR +\f(CW/usr/bin/mwm -xrm "mwm*configFile: mymwmrc"\fR .fi .PP .SS "Resource Types" @@ -626,8 +626,8 @@ is not what you expect\&. .nf \fB$HOME/$LANG/\&.mwmrc $HOME/\&.mwmrc -/usr/X11R6/lib/X11/$LANG/system\&.mwmrc -/usr/X11R6/lib/X11/system\&.mwmrc\fP +/etc/X11/mwm/$LANG/system\&.mwmrc +/etc/X11/mwm/system\&.mwmrc\fP .fi .SH "RELATED INFORMATION" .PP diff --git a/doc/man/man4/mwmrc.4.mwmrc_dir b/doc/man/man4/mwmrc.4.mwmrc_dir new file mode 100644 index 0000000..e8de9f9 --- /dev/null +++ b/doc/man/man4/mwmrc.4.mwmrc_dir @@ -0,0 +1,636 @@ +'\" t +...\" mwmrc.sgm /main/8 1996/09/08 21:43:59 rws $ +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "mwmrc" "special file" +.SH "NAME" +\fBmwmrc\fP \(em the +Motif Window Manager Resource Description File +.SH "DESCRIPTION" +.PP +The \fBmwmrc\fP file is a supplementary resource +file that controls much of the behavior of the Motif window manager \fBmwm\fP\&. +It contains descriptions of resources that cannot easily be +written using standard X Window System, Version 11 resource syntax\&. The resource +description file contains entries that are referred to by X resources in +defaults files (for example, \fB/usr/X11R6/lib/X11/app-defaults/Mwm\fP) +or in the \fBRESOURCE_MANAGER\fP property on the +root window\&. For example, the resource description file enables you to specify +different types of window menus; however, an X resource is used to specify +which of these window menus \fBmwm\fP should use for a particular +window\&. +.SS "Location" +.PP +The window manager searches for one of the following resource description +files, where \fI$LANG\fP is the value of the language environment +on a per-user basis: +.PP +.nf +\f(CW$HOME/$LANG/\&.mwmrc +$HOME/\&.mwmrc +/usr/X11R6/lib/X11/$LANG/system\&.mwmrc +/usr/X11R6/lib/X11/system\&.mwmrc\fR +.fi +.PP +.PP +The first file found is the first used\&. If no file is found, a +set of built-in specifications is used\&. A particular resource description +file can be selected using the \fIconfigFile\fP +resource\&. The following shows how a different resource description file can +be specified from the command line: +.PP +.nf +\f(CW/usr/X11R6/bin/X11/mwm -xrm "mwm*configFile: mymwmrc"\fR +.fi +.PP +.SS "Resource Types" +.PP +The following types of resources can be described in the mwm resource +description file: +.IP "\fBButtons\fP" 10 +Window manager functions can be bound (associated) with button events\&. +.IP "\fBKeys\fP" 10 +Window manager functions can be bound (associated) with key press +events\&. +.IP "\fBMenus\fP" 10 +Menu panes can be used for the window menu and other menus posted with +key bindings and button bindings\&. +.SH "MWM RESOURCE DESCRIPTION FILE SYNTAX" +.PP +The \fBmwm\fP resource description file is a standard +text file that contains items of information separated by blanks, tabs, and +new lines characters\&. Blank lines are ignored\&. Items or characters can be +quoted to avoid special interpretation (for example, the comment character +can be quoted to prevent it from being interpreted as the comment character)\&. +A quoted item can be contained in double quotes (\fB" "\fP)\&. +Single characters can be quoted by preceding them by the back-slash character +(\fB\\\fP)\&. If a line ends with a back-slash, the next line is considered +a continuation of that line\&. All text from an unquoted \fB#\fP +to the end of the line is regarded as a comment and is not interpreted as +part of a resource description\&. If \fB!\fP is the first character +in a line, the line is regarded as a comment\&. +.SS "Window Manager Functions" +.PP +Window manager functions can be accessed with button and key bindings, +and with window manager menus\&. Functions are indicated as part of the specifications +for button and key binding sets, and menu panes\&. The function specification +has the following syntax: +.PP +.nf +\f(CW\fBfunction\fP = \fBfunction_name\fP [\fBfunction_args\fP] +\fBfunction_name\fP = \fBwindow manager function\fP +\fBfunction_args\fP = {\fBquoted_item\fP | \fBunquoted_item\fP}\fR +.fi +.PP +.PP +The following functions are supported\&. If a function is specified that +isn\&'t one of the supported functions then it is interpreted by \fBmwm\fP as \fBf\&.nop\fP\&. +.IP "\fBf\&.beep\fP" 10 +This function causes a beep\&. +.IP "\fBf\&.circle_down\fP [ \fIicon\fP | \fIwindow\fP]" 10 +This function causes the window or icon that is on the top of the window +stack to be put on the bottom of the window stack (so that it is no longer +obscuring any other window or icon)\&. This function affects only those windows +and icons that are obscuring other windows and icons, or that are obscured +by other windows and icons\&. Secondary windows (that is, transient windows) +are restacked with their associated primary window\&. Secondary windows always +stay on top of the associated primary window and there can be no other primary +windows between the secondary windows and their primary window\&. If an +\fIicon\fP function argument is specified, then the function +applies only to icons\&. If a \fIwindow\fP function +argument is specified then the function applies only to windows\&. +.IP "\fBf\&.circle_up\fP [ \fIicon\fP | \fIwindow\fP]" 10 +This function raises the window or icon on the bottom of the window +stack (so that it is not obscured by any other windows)\&. This function affects +only those windows and icons that are obscuring other windows and icons, or +that are obscured by other windows and icons\&. Secondary windows (that is, +transient windows) are restacked with their associated primary window\&. If +an \fIicon\fP function argument is specified then +the function applies only to icons\&. If an \fIwindow\fP +function argument is specified then the function applies only to windows\&. +.IP "\fBf\&.exec\fP \fBcommand\fP (or \fI!\fP \fBcommand\fP)" 10 +This function causes \fIcommand\fP to be +executed (using the value of the \fI$MWMSHELL\fP or \fI$SHELL\fP environment variable if set; otherwise, \fB/bin/sh\fP )\&. The \fI!\fP notation can be used in place of the \fBf\&.exec\fP function name\&. +.IP "\fBf\&.focus_color\fP" 10 +This function sets the colormap focus to a client window\&. If this function +is done in a root context, then the default colormap (setup by the X Window +System for the screen where \fBmwm\fP is running) is installed +and there is no specific client window colormap focus\&. This function is treated +as \fBf\&.nop\fP if \fIcolormapFocusPolicy\fP +is not explicit\&. +.IP "\fBf\&.focus_key\fP" 10 +This function sets the keyboard input focus to a client window or icon\&. +This function is treated as \fBf\&.nop\fP if \fIkeyboardFocusPolicy\fP is not explicit or the function is executed in a root context\&. +.IP "\fBf\&.kill\fP" 10 +This function is used to close application windows\&. The actual processing +that occurs depends on the protocols that the application observes\&. The application +lists the protocols it observes in the \fBWM_PROTOCOLS\fP property +on its top level window\&. If the application observes the \fBWM_DELETE_WINDOW\fP protocol, it is sent a message that requests the window be deleted\&. +If the application observes both \fBWM_DELETE_WINDOW\fP and \fBWM_SAVE_YOURSELF\fP, it is sent one message requesting the window +be deleted and another message advising it to save its state\&. If the application +observes only the \fBWM_SAVE_YOURSELF\fPprotocol \fI,\fP it is sent a message advising it to save its state\&. After a +delay (specified by the resource \fIquitTimeout\fP), the application\&'s +connection to the X server is terminated\&. If the application observes neither +of these protocols, its connection to the X server is terminated\&. +.IP "\fBf\&.lower\fP\ [\fI-\fP \fBclient\fP | \fIwithin\fP\ | \fIfreeFamily\fP]" 10 +This function lowers a primary window to the bottom of the global window +stack (where it obscures no other window) and lowers the secondary window +(transient window or dialog box) within the client family\&. The arguments to +this function are mutually exclusive\&. The \fIclient\fP +argument indicates the name or class of a client to lower\&. The name or class +of a client appears in the \fBWM_CLASS\fP property on the +client\&'s top-level window\&. If the \fIclient\fP +argument is not specified, the context that the function was invoked in indicates +the window or icon to lower\&. Specifying \fIwithin\fP +lowers the secondary window within the family (staying above the parent) but +does not lower the client family in the global window stack\&. Specifying \fIfreeFamily\fP lowers the window to the bottom of the global windows +stack from its local family stack\&. +.IP "\fBf\&.maximize\fP" 10 +This function causes a client window to be displayed with its maximum +size\&. Refer to the \fImaximumClientSize\fP, \fImaximumMaximumSize\fP, and \fIlimitResize\fP resources in \fBmwm\fP(1)\&. +.IP "\fBf\&.menu\fP \fImenu_name\fP" 10 +This function associates a cascading (pull-right) menu with a menu +pane entry or a menu with a button or key binding\&. The \fImenu_name\fP function argument identifies the menu to be used\&. +.IP "\fBf\&.minimize\fP" 10 +This function causes a client window to be minimized (iconified)\&. When +a window is minimized with no icon box in use, and if the \fIlowerOnIconify\fP resource has the value True (the default), the icon is placed +on the bottom of the window stack (such that it obscures no other window)\&. +If an icon box is used, then the client\&'s icon changes to its iconified form +inside the icon box\&. Secondary windows (that is, transient windows) are minimized +with their associated primary window\&. There is only one icon for a primary +window and all its secondary windows\&. +.IP "\fBf\&.move\fP" 10 +This function initiates an interactive move of a client window\&. +.IP "\fBf\&.next_cmap\fP" 10 +This function installs the next colormap in the list of colormaps for +the window with the colormap focus\&. +.IP "\fBf\&.next_key\fP [ \fIicon\fP | \fIwindow\fP | \fItransient\fP]" 10 +This function sets the keyboard input focus to the next window/icon +in the set of windows/icons managed by the window manager (the ordering +of this set is based on the stacking of windows on the screen)\&. This function +is treated as \fBf\&.nop\fP if \fBkeyboardFocusPolicy\fP +is not explicit\&. The keyboard input focus is only moved to windows that do +not have an associated secondary window that is application modal\&. If the +\fItransient\fP argument is specified, then transient (secondary) +windows are traversed (otherwise, if only \fIwindow\fP +is specified, traversal is done only to the last focused window in a transient +group)\&. If an \fIicon\fP function argument is specified, +then the function applies only to icons\&. If a \fIwindow\fP function argument is specified, then the function applies only to +windows\&. +.IP "\fBf\&.nop\fP" 10 +This function does nothing\&. +.IP "\fBf\&.normalize\fP" 10 +This function causes a client window to be displayed with its normal +size\&. Secondary windows (that is, transient windows) are placed in their normal +state along with their associated primary window\&. +.IP "\fBf\&.normalize_and_raise\fP" 10 +This function causes a client window to be displayed with its normal +size and raised to the top of the window stack\&. Secondary windows (that is, +transient windows) are placed in their normal state along with their associated +primary window\&. +.IP "\fBf\&.pack_icons\fP" 10 +This function is used to relayout icons (based on the layout policy +being used) on the root window or in the icon box\&. In general this causes +icons to be "packed" into the icon grid\&. +.IP "\fBf\&.pass_keys\fP" 10 +This function is used to enable/disable (toggle) processing of key bindings +for window manager functions\&. When it disables key binding processing all +keys are passed on to the window with the keyboard input focus and no window +manager functions are invoked\&. If the \fBf\&.pass_keys\fP function +is invoked with a key binding to disable key binding processing the same key +binding can be used to enable key binding processing\&. +.IP "\fBf\&.post_wmenu\fP" 10 +This function is used to post the window menu\&. If a key is used to post +the window menu and a window menu button is present, the window menu is automatically +placed with its top-left corner at the bottom-left corner of the window menu +button for the client window\&. If no window menu button is present, the window +menu is placed at the top-left corner of the client window\&. +.IP "\fBf\&.prev_cmap\fP" 10 +This function installs the previous colormap in the list of colormaps +for the window with the colormap focus\&. +.IP "\fBf\&.prev_key\fP [ \fIicon\fP | \fIwindow\fP | \fItransient\fP]" 10 +This function sets the keyboard input focus to the previous window/icon +in the set of windows/icons managed by the window manager (the ordering +of this set is based on the stacking of windows on the screen)\&. This function +is treated as \fBf\&.nop\fP if \fIkeyboardFocusPolicy\fP is not explicit\&. The keyboard input focus is only moved to windows +that do not have an associated secondary window that is application modal\&. +If the \fItransient\fP argument is specified, then +transient (secondary) windows are traversed (otherwise, if only \fIwindow\fP is specified, traversal is done only to the last focused window +in a transient group)\&. If an \fIicon\fP function +argument is specified then the function applies only to icons\&. If an +\fIwindow\fP function argument is specified then the function +applies only to windows\&. +.IP "\fBf\&.quit_mwm\fP" 10 +This function terminates mwm (but NOT the X window system)\&. +.IP "\fBf\&.raise\fP\ [\fI-\fP\fIclient\fP | \fIwithin\fP | \fIfreeFamily\fP]" 10 +This function raises a primary window to the top of the global window +stack (where it is obscured by no other window) and raises the secondary window +(transient window or dialog box) within the client family\&. The arguments to +this function are mutually exclusive\&. The \fIclient\fP +argument indicates the name or class of a client to lower\&. If the \fIclient\fP +is not specified, the context that the function +was invoked in indicates the window or icon to lower\&. Specifying \fIwithin\fP raises the secondary window within the family but does not +raise the client family in the global window stack\&. Specifying \fIfreeFamily\fP raises the window to the top of its local family stack +and raises the family to the top of the global window stack\&. +.IP "\fBf\&.raise_lower\fP\ [ \fIwithin\fP | \fIfreeFamily\fP]" 10 +This function raises a primary window to the top of the global window +stack if it is partially obscured by another window; otherwise, it lowers +the window to the bottom of the window stack\&. The arguments to this function +are mutually exclusive\&. Specifying \fIwithin\fP +raises a secondary window within the family (staying above the parent window), +if it is partially obscured by another window in the application\&'s family; +otherwise, it lowers the window to the bottom of the family stack\&. It has +no effect on the global window stacking order\&. Specifying \fIfreeFamily\fP raises the window to the top of its local family stack, if obscured +by another window, and raises the family to the top of the global window +stack; otherwise, it lowers the window to the bottom of its local family stack +and lowers the family to the bottom of the global window stack\&. +.IP "\fBf\&.refresh\fP" 10 +This function causes all windows to be redrawn\&. +.IP "\fBf\&.refresh_win\fP" 10 +This function causes a client window to be redrawn\&. +.IP "\fBf\&.resize\fP" 10 +This function initiates an interactive resize of a client window\&. +.IP "\fBf\&.restore\fP" 10 +This function restores the previous state of an icon\&'s associated window\&. +If a maximized window is iconified, then \fBf\&.restore\fP restores +it to its maximized state\&. If a normal window is iconified, then \fBf\&.restore\fP restores it to its normalized state\&. +.IP "\fBf\&.restore_and_raise\fP" 10 +This function restores the previous state of an icon\&'s associated window +and raises the window to the top of the window stack\&. If a maximized window +is iconified, then \fBf\&.restore_and_raise\fP restores it to +its maximized state and raises it to the top of the window stack\&. If a normal +window is iconified, then \fBf\&.restore_and_raise\fP restores +it to its normalized state and raises it to the top of the window stack\&. +.IP "\fBf\&.restart\fP" 10 +This function causes mwm to be restarted (effectively terminated and +re-executed)\&. Restart is necessary for \fBmwm\fP to incorporate +changes in both the \fBmwmrc\fP file and X resources\&. +.IP "\fBf\&.screen\fP\ [ \fInext\fP | \fIprev\fP | \fIback\fP | \fIscreen_number\fP]" 10 +This function causes the pointer to be warp to a specific screen number +or to the \fInext\fP, \fIprevious\fP, or last visited (\fIback\fP) +screen\&. The arguments to this function are mutually exclusive\&. The +\fIscreen_number\fP argument indicates the screen number +that the pointer is to be warped\&. Screens are numbered starting from screen +0\&. Specifying \fInext\fP cause the pointer to warp +to the next managed screen (skipping over any unmanaged screens)\&. Specifying +\fIprev\fP cause the pointer to warp to the previous managed +screen (skipping over any unmanaged screens)\&. Specifying \fIback\fP cause the pointer to warp to the last visited screen\&. +.IP "\fBf\&.send_msg\fP \fImessage_number\fP" 10 +This function sends an \fBXClientMessageEvent\fR of type \fB_MOTIF_WM_MESSAGES\fP with +\fImessage_type\fP set to \fImessage_number\fP\&. +The client message is sent only if \fImessage_number\fP +is included in the client\&'s \fB_MOTIF_WM_MESSAGES\fP +property\&. A menu item label is grayed out if the menu item is used to do \fBf\&.send_msg\fP of a message that is not included in the client\&'s \fB_MOTIF_WM_MESSAGES\fP property\&. +.IP "\fBf\&.separator\fP" 10 +This function causes a menu separator to be put in the menu pane at +the specified location (the label is ignored)\&. +.IP "\fBf\&.set_behavior\fP" 10 +This function causes the window manager to restart with the default +behavior (if a custom behavior is configured) or a custom behavior (if a +default behavior is configured)\&. By default this is bound to \fIShift\ Ctrl\ Alt\ !\fP\&. +.IP "\fBf\&.title\fP" 10 +This function inserts a title in the menu pane at the specified location\&. +.IP "\fBf\&.version\fP" 10 +This function causes the window manager to display its release version +in a dialog box\&. +.SS "Function Constraints" +.PP +Each function may be constrained as to which resource types can specify +the function (for example, menu pane) and also what context the function +can be used in (for example, the function is done to the selected client window)\&. +Function contexts are: +.IP "\fIroot\fP" 10 +No client window or icon has been selected as an object for the function\&. +.IP "\fIwindow\fP" 10 +A client window has been selected as an object for the function\&. This +includes the window\&'s title bar and frame\&. Some functions are applied only +when the window is in its normalized state (for example, \fBf\&.maximize\fP) or its maximized state (for example, \fBf\&.normalize\fP)\&. +.IP "\fIicon\fP" 10 +An icon has been selected as an object for the function\&. +.PP +If a function is specified in a type of resource where it is not supported +or is invoked in a context that does not apply then the function is treated +as \fBf\&.nop\fP\&. The following table indicates the resource +types and function contexts in which window manager functions apply\&. +.PP +.TS +tab(); +lw(2.289841i) lw(1.851594i) lw(1.358566i). +FunctionContextsResources +_ +\fBf\&.beep\fProot,icon,windowbutton,key,menu +\fBf\&.circle_down\fProot,icon,windowbutton,key,menu +\fBf\&.circle_up\fProot,icon,windowbutton,key,menu +\fBf\&.exec\fProot,icon,windowbutton,key,menu +\fBf\&.focus_color\fProot,icon,windowbutton,key,menu +\fBf\&.focus_key\fProot,icon,windowbutton,key,menu +\fBf\&.kill\fPicon,windowbutton,key,menu +\fBf\&.lower\fProot,icon,windowbutton,key,menu +\fBf\&.maximize\fPicon,window(normal)button,key,menu +\fBf\&.menu\fProot,icon,windowbutton,key,menu +\fBf\&.minimize\fPwindowbutton,key,menu +\fBf\&.move\fPicon,windowbutton,key,menu +\fBf\&.next_cmap\fProot,icon,windowbutton,key,menu +\fBf\&.next_key\fProot,icon,windowbutton,key,menu +\fBf\&.nop\fProot,icon,windowbutton,key,menu +\fBf\&.normalize\fPicon,window(maximized)button,key,menu +\fBf\&.normalize_and_raise\fPicon,windowbutton,key,menu +\fBf\&.pack_icons\fProot,icon,windowbutton,key,menu +\fBf\&.pass_keys\fProot,icon,windowbutton,key,menu +\fBf\&.post_wmenu\fProot,icon,windowbutton,key +\fBf\&.prev_cmap\fProot,icon,windowbutton,key,menu +\fBf\&.prev_key\fProot,icon,windowbutton,key,menu +\fBf\&.quit_mwm\fProotbutton,key,menu (root only) +\fBf\&.raise\fProot,icon,windowbutton,key,menu +\fBf\&.raise_lower\fPicon,windowbutton,key,menu +\fBf\&.refresh\fProot,icon,windowbutton,key,menu +\fBf\&.refresh_win\fPwindowbutton,key,menu +\fBf\&.resize\fPwindowbutton,key,menu +\fBf\&.restart\fProotbutton,key,menu (root only) +\fBf\&.restore\fPicon,windowbutton,key,menu +\fBf\&.restore_and_raise\fPicon,windowbutton,key,menu +\fBf\&.screen\fProot,icon,windowbutton,key,menu +\fBf\&.send_msg\fPicon,windowbutton,key,menu +\fBf\&.separator\fProot,icon,windowmenu +\fBf\&.set_behavior\fProot,icon,windowbutton,key,menu +\fBf\&.title\fProot,icon,windowmenu +\fBf\&.version\fProot,icon,windowbutton,key,menu +.TE +.SH "WINDOW MANAGER EVENT SPECIFICATION" +.PP +Events are indicated as part of the specifications for button and key +binding sets, and menu panes\&. Button events have the following syntax: +.PP +.nf +\f(CW\fBbutton\fP =~[\fBmodifier_list\fP ]\fI<\fP\fBbutton_event_name\fP \fI>\fP +\fBmodifier_list\fP =~\fBmodifier_name\fP { \fBmodifier_name\fP}\fR +.fi +.PP +.PP +The following table indicates the values that can be used for \fBmodifier_name\fP\&. Note that [Alt] and [Meta] can be used interchangably +on some hardware\&. +.PP +.TS +tab(); +lw(1.097588i) lw(4.402412i). +ModifierDescription +_ +CtrlControl Key +ShiftShift Key +AltAlt Key +MetaMeta Key +Mod1Modifier1 +Mod2Modifier2 +Mod3Modifier3 +Mod4Modifier4 +Mod5Modifier5 +.TE +.PP +Locking modifiers are ignored when processing button and key bindings\&. +The following table lists keys that are interpreted as locking modifiers\&. +The X server may map some of these symbols to the Mod1 - Mod5 modifier keys\&. +These keys may or may not be available on your hardware: Key Symbol Caps Lock +Shift Lock Kana Lock Num Lock Scroll Lock The following table indicates the +values that can be used for \fBbutton_event_name\fP\&. +.PP +.TS +tab(); +lw(1.290570i) lw(4.209430i). +ButtonDescription +_ +Btn1DownButton 1 Press +Btn1UpButton 1 Release +Btn1ClickButton 1 Press and Release +Btn1Click2Button 1 Double Click +Btn2DownButton 2 Press +Btn2UpButton 2 Release +Btn2ClickButton 2 Press and Release +Btn2Click2Button 2 Double Click +Btn3DownButton 3 Press +Btn3UpButton 3 Release +Btn3ClickButton 3 Press and Release +Btn3Click2Button 3 Double Click +Btn4DownButton 4 Press +Btn4UpButton 4 Release +Btn4ClickButton 4 Press and Release +Btn4Click2Button 4 Double Click +Btn5DownButton 5 Press +Btn5UpButton 5 Release +Btn5ClickButton 5 Press and Release +Btn5Click2Button 5 Double Click +.TE +.PP +Key events that are used by the window manager for menu mnemonics +and for binding to window manager functions are single key presses; key +releases are ignored\&. Key events have the following syntax: +.PP +.nf +\f(CW\fBkey\fP =~[\fBmodifier_list\fP] \fB\fP\fBkey_name\fP +\fBmodifier_list\fP =~\fBmodifier_name\fP { \fBmodifier_name\fP}\fR +.fi +.PP +.PP +All modifiers specified are interpreted as being exclusive (this means +that only the specified modifiers can be present when the key event occurs)\&. +Modifiers for keys are the same as those that apply to buttons\&. The \fBkey_name\fP is an X11 keysym name\&. Keysym names can be found in the +\fBkeysymdef\&.h\fP file (remove the \fBXK_\fP +prefix)\&. +.SH "BUTTON BINDINGS" +.PP +The \fBbuttonBindings\fP resource value is the name of +a set of button bindings that are used to configure window manager behavior\&. +A window manager function can be done when a button press occurs with +the pointer over a framed client window, an icon or the root window\&. The +context for indicating where the button press applies is also the context +for invoking the window manager function when the button press is done +(significant for functions that are context sensitive)\&. The button binding +syntax is +.PP +.nf +\f(CW\fIButtons\fP \fBbindings_set_name\fP +\fI{\fP + \fBbutton\fP \fBcontext\fP \fBfunction\fP + \fBbutton\fP \fBcontext\fP \fBfunction\fP + \&.\&.\&. + \fBbutton\fP \fBcontext\fP \fBfunction\fP +\fI}\fP\fR +.fi +.PP +.PP +The syntax for the \fBcontext\fP specification is: \fBcontext\fP = \fBobject\fP[\fI|\fP \fBcontext\fP] \fBobject\fP = \fIroot\fP | \fIicon\fP | \fIwindow\fP | \fItitle\fP | \fIframe\fP | \fIborder\fP | \fIapp\fP The context specification indicates where the pointer must be +for the button binding to be effective\&. For example, a context of +\fIwindow\fP indicates that the pointer must be over a +client window or window management frame for the button binding to be effective\&. +The \fIframe\fP context is for the window management +frame around a client window (including the border and titlebar), the +\fIborder\fP context is for the border part of the window +management frame (not including the titlebar), the \fItitle\fP context is for the title area of the window management frame, +and the \fIapp\fP context is for the application +window (not including the window management frame)\&. If an \fBf\&.nop\fP function is specified for a button binding, the button binding +is not done\&. +.SH "KEY BINDINGS" +.PP +The \fBkeyBindings\fP resource value is the name of a set +of key bindings that are used to configure window manager behavior\&. A +window manager function can be done when a particular key is pressed\&. The +context in which the key binding applies is indicated in the key binding specification\&. +The valid contexts are the same as those that apply to button bindings\&. The +key binding syntax is: +.PP +.nf +\f(CW\fIKeys\fP \fBbindings_set_name\fP +\fI{\fP + \fBkey\fP \fBcontext\fP \fBfunction\fP + \fBkey\fP \fBcontext\fP \fBfunction\fP + \&.\&.\&. + \fBkey\fP \fBcontext\fP \fBfunction\fP +\fI}\fP\fR +.fi +.PP +.PP +If an \fBf\&.nop\fP function is specified for a key binding, +the key binding is not done\&. If an \fBf\&.post_wmenu\fP or \fBf\&.menu\fP function is bound to a key, \fBmwm\fP automatically +uses the same key for removing the menu from the screen after it has been +popped up\&. The \fBcontext\fP specification syntax is the same +as for button bindings with one addition\&. The context \fIifkey\fP +may be specified for binding keys that may not be available on all displays\&. +If the key is not available and if \fIifkey\fP is in the context, +then reporting of the error message to the error log is suppressed\&. This feature +is useful for networked, heterogeneous environments\&. For key bindings, the +\fIframe\fP, \fItitle\fP, +\fIborder\fP, and \fIapp\fP +contexts are equivalent to the \fIwindow\fP context\&. +The context for a key event is the window or icon that has the keyboard input +focus (\fIroot\fP if no window or icon has the +keyboard input focus)\&. +.SH "MENU PANES" +.PP +Menus can be popped up using the \fBf\&.post_wmenu\fP and \fBf\&.menu\fP window manager functions\&. The context for window manager +functions that are done from a menu is \fIroot\fP, +\fIicon\fP or \fIwindow\fP depending +on how the menu was popped up\&. In the case of the \fIwindow\fP menu or menus popped up with a key binding, the location of +the keyboard input focus indicates the context\&. For menus popped up using +a button binding, the context of the button binding is the context of the +menu\&. The menu pane specification syntax is: +.PP +.nf +\f(CW\fIMenu\fP \fBmenu_name\fP +\fI{\fP + \fBlabel\fP [\fBmnemonic\fP] [\fBaccelerator\fP ] \fBfunction\fP + \fBlabel\fP [\fBmnemonic\fP] [\fBaccelerator\fP ] \fBfunction\fP + \&.\&.\&. + \fBlabel\fP [\fBmnemonic\fP] [\fBaccelerator\fP ] \fBfunction\fP +\fI}\fP\fR +.fi +.PP +.PP +Each line in the \fIMenu\fP specification identifies +the label for a menu item and the function to be done if the menu item is +selected\&. Optionally a menu button mnemonic and a menu button keyboard accelerator +may be specified\&. Mnemonics are functional only when the menu is posted and +keyboard traversal applies\&. The \fBlabel\fP may be a string or +a bitmap file\&. The label specification has the following syntax: +.PP +.nf +\f(CW\fBlabel\fP = \fBtext\fP | \fBbitmap_file\fP +\fBbitmap_file\fP = \fI@\fP\fBfile_name\fP +\fBtext\fP = \fBquoted_item\fP | \fBunquoted_item\fP\fR +.fi +.PP +.PP +The string encoding for labels must be compatible with the menu font +that is used\&. Labels are greyed out for menu items that do the \fBf\&.nop\fP function or an invalid function or a function that doesn\&'t +apply in the current context\&. A \fBmnemonic\fP specification +has the following syntax: +.PP +.nf +\f(CW\fBmnemonic\fP = \fI_\fP \fBcharacter\fP\fR +.fi +.PP +.PP +The first matching \fBcharacter\fP in the label is underlined\&. +If there is no matching \fBcharacter\fP in the label, no mnemonic +is registered with the window manager for that label\&. Although the \fBcharacter\fP must exactly match a character in the label, the mnemonic +does not execute if any modifier (such as Shift) is pressed with the character +key\&. The \fBaccelerator\fP specification is a key event specification +with the same syntax as is used for key bindings to window manager functions\&. +.SH "INCLUDING FILES" +.PP +You may include other files into your mwmrc file by using the +\fIinclude\fP construct\&. For example, +.PP +.nf +\f(CWINCLUDE +{ + /usr/local/shared/mwm\&.menus + /home/kmt/personal/my\&.bindings +}\fR +.fi +.PP +.PP +causes the files named to be read in and interpreted in order as an +additional part of the mwmrc file\&. \fIInclude\fP is a top-level +construct\&. It cannot be nested inside another construct\&. +.SH "WARNINGS" +.PP +Errors that occur during the processing of the resource description +file are recorded in: \fB$HOME/\&.mwm/errorlog\fP\&. Be sure to +check this file if the appearance or behavior of \fBmwm\fP +is not what you expect\&. +.SH "FILES" +.PP +.nf +\fB$HOME/$LANG/\&.mwmrc +$HOME/\&.mwmrc +/usr/X11R6/lib/X11/$LANG/system\&.mwmrc +/usr/X11R6/lib/X11/system\&.mwmrc\fP +.fi +.SH "RELATED INFORMATION" +.PP +\fBmwm\fP(1), +\fBX\fP(1)\&. +...\" created by instant / docbook-to-man, Sun 22 Dec 1996, 20:36