/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1989, 1990, 1991, 1992, 1993, 1994 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * Motif Release 1.2.4 */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$TOG: WmInitWs.c /main/18 1999/09/20 15:18:22 mgreess $" #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. */ /* * Included Files: */ #include "WmGlobal.h" #include "WmResNames.h" #ifdef WSM #include "WmHelp.h" #endif /* WSM */ #include "WmICCC.h" #ifdef PANELIST #define DTWM_NEED_FNTPL #include "WmIBitmap.h" #endif /* PANELIST */ #ifndef NO_OL_COMPAT #include "WmOL.h" #endif /* NO_OL_COMPAT */ #include #include #include #include #include #include #ifndef NO_HP_KEY_REMAP #include #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) # include #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ typedef struct { String default_name ; String new_name ; } str_xref_rec, *str_xref ; #endif /* NO_HP_KEY_REMAP */ #ifdef WSM #include
#include
#include
#include
#include
#endif /* WSM */ /* Busy is also defined in the BMS -> bms.h. This conflicts with * /usr/include/X11/Xasync.h on ibm. */ #ifdef _AIX #ifdef Busy #undef Busy #endif #endif #include /* * include extern functions */ #ifdef WSM #include "WmBackdrop.h" #endif /* WSM */ #include "WmCDInfo.h" #include "WmColormap.h" #include "WmError.h" #include "WmEvent.h" #include "WmFeedback.h" #include "WmFunction.h" #include "WmIDecor.h" #ifdef WSM #include "WmIPC.h" #endif /* WSM */ #include "WmIPlace.h" #include "WmIconBox.h" #include "WmKeyFocus.h" #ifdef PANELIST #include "WmPanelP.h" /* for typedef in WmManage.h */ #endif /* PANELIST */ #include "WmManage.h" #include "WmMenu.h" #ifdef WSM #include "WmPresence.h" #endif /* WSM */ #include "WmProperty.h" #include "WmResCvt.h" #include "WmResource.h" #include "WmSignal.h" #include "WmProtocol.h" #include "WmCDecor.h" #include "stdio.h" #include "WmResParse.h" #ifdef WSM #include #endif /* WSM */ #include "WmXSMP.h" /* * Function Declarations: */ #include "WmInitWs.h" #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) # include "WmWsmLib/wsm_proto.h" # include "WmWsmLib/utm_send.h" #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ #ifdef WSM static void InsureDefaultBackdropDir(char **ppchBackdropDirs); #endif /* WSM */ void InitWmDisplayEnv (void); #ifndef NO_MESSAGE_CATALOG void InitNlsStrings (void); #endif #ifndef NO_HP_KEY_REMAP Boolean VirtKeys4DIN(Display *dpy); #endif /* NO_HP_KEY_REMAP */ #ifdef WSM /* limited to 3 chars max */ #define UNSPECIFIED_SCREEN_NAME "fbk" char **dpy2Argv; /* copy for second display */ int dpy2Argc; #ifndef PANELIST WmScreenData *dtSD; /* for the "DT screen" of the display */ #endif /* PANELIST */ #endif /* WSM */ /* * Global Variables: */ extern int firstTime; #ifndef NO_MESSAGE_CATALOG extern char * pWarningStringFile; extern char * pWarningStringLine; #endif /* * InitMouseBinding * * Special case for a two button mouse; move the BMENU binding * from Button3 to Button2. Fails for one-button mice. */ static void InitMouseBinding(void) { wmGD.numMouseButtons = XGetPointerMapping(DISPLAY, (unsigned char *)0, 0); if (wmGD.numMouseButtons < 3) { wmGD.bMenuButton = Button2; } else { wmGD.bMenuButton = Button3; } } /******************************<->************************************* * * BuildLockMaskSequence () * * Set up the sequence of modifier masks to use to when grabbing * key- and button-bindings. This sequence of masks is NULL * terminated. * * Input: * wmGD.lockingModMask * * Output: * wmGD.pLockMaskSequence * * *************************************<->***********************************/ static void BuildLockMaskSequence(void) { int i, j, k; unsigned int mask; unsigned int thisbit; Boolean bit_on; int num_masks; int num_bits; int bit; int run; /* * Count the bits to determine the number of elements in * the mask sequence. The actual number of masks is * 2^ - 1. We're not interested in the case * where there none of the mask bits are set. */ mask = wmGD.lockingModMask; num_bits=0; while (mask) { if (mask & 0x1) { num_bits++; } mask = mask >> 1; } num_masks = (0x1 << num_bits) - 1; /* * Allocate the space for the mask sequence + terminator. */ wmGD.pLockMaskSequence = (unsigned int *) XtCalloc (num_masks+1, sizeof (unsigned int)); /* * Fill in the mask sequence */ mask = wmGD.lockingModMask; thisbit = 0x1; bit = 0; while (mask && thisbit) { /* find next bit */ while (!(thisbit & mask)) { thisbit = thisbit << 1; } /* clear it from mask */ mask &= ~thisbit; bit++; /* * Set it in the appropriate slots in the * mask sequence. The start of the loop is * funny because we skip the case of all the * bits cleared. */ run = (0x1 << bit-1); /* number of consecutive masks to set bits in */ bit_on = False; /* are we setting bits or not? */ for (j=0, k=run-1; j************************************* * * SetupLockingModifierMask () * * Set up the mask used to ignore locking modifier keys (e.g. Shift Lock) * when processing key- and button-bindings. * * We want to try to ignore the set of locking modifers * such as Shift Lock, Num Lock, Kana Lock, etc. This involves * some amount of guessing since these things can be mapped * onto any of the Mod1-Mod5 modifiers. The approach taken is to * identify the mapping of the locking modifier keysyms to * Mod1-Mod5 and build the set of masks needed to ignore them. * *************************************<->***********************************/ /* * This is the set of locking modifiers keysyms that might be * bound to Mod1-Mod5. (Caps Lock is handled independently of * this set.) */ static KeySym pksLockingMods[] = { XK_Scroll_Lock, XK_Kana_Lock, XK_Num_Lock, XK_Mode_switch }; #define NUM_LOCKING_MODS (sizeof(pksLockingMods)/sizeof(KeySym)) static void SetupLockingModifierMask(void) { int i, j, start_index; XModifierKeymap *modifier_map = NULL; static Modifiers mod_masks[] = { None, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; Display *dpy = wmGD.display; int pkcLockingMods[NUM_LOCKING_MODS]; int kcq, kc; for (i=0; imax_keypermod * Mod1MapIndex; for (i = start_index; i < modifier_map->max_keypermod * 8; i++) { int this_mod = ((i - start_index) / modifier_map->max_keypermod) + 1; kc = modifier_map->modifiermap[i]; if (kc) { for (j=0; j************************************* * * MappingEventHandler (Widget, XtPointer, XEvent *, Boolean *) * * Catch and handle changes to the mapping of the modifier keys. * *************************************<->***********************************/ static void MappingEventHandler( Widget w, XtPointer client_data, XEvent *event, Boolean *cont_to_dispatch) { if(event->xany.type != MappingNotify || event->xmapping.request == MappingPointer) return; if(event->xmapping.request == MappingModifier) SetupLockingModifierMask(); } /******************************<->************************************* * * InitWmGlobal (argc, argv, environ) * * * Description: * ----------- * This function initializes the workspace manager. * * * Inputs: * ------ * argc = number of command line arguments (+1) * * argv = window manager command line arguments * * environ = window manager environment * * * Outputs: * ------- * wmGD = (initialize the global data structure) * *************************************<->***********************************/ void InitWmGlobal (int argc, char *argv [], char *environ []) { XSetWindowAttributes sAttributes; int scr; int managed = 0; char pch[80]; Boolean activeSet = False; Boolean processedGlobalResources = False; WmScreenData *pSD; Arg args[20]; int argnum; char *res_class; int savedArgc; wmGD.errorFlag = False; #ifdef WSM #ifndef PANELIST dtSD = NULL; #else /* PANELIST */ wmGD.dtSD = NULL; wmGD.iSlideUpsInProgress = 0; #endif /*PANELIST */ #endif /* WSM */ SetupWmSignalHandlers (0); /* dummy paramater */ /* * Do (pre-toolkit) initialization: */ wmGD.windowContextType = XUniqueContext (); wmGD.screenContextType = XUniqueContext (); #ifndef IBM_169380 wmGD.cmapWindowContextType = XUniqueContext (); #endif #ifdef WSM wmGD.mwmWindowContextType = XUniqueContext (); #endif /* WSM */ /* copy argv (the XtInititalize changes the original) for use in restart */ savedArgc = argc; CopyArgv (argc, argv); wmGD.environ = environ; #ifdef WSM wmGD.pWmPB = _DtWmParseNewBuf(); #endif /* WSM */ /* set our name */ if ((wmGD.mwmName = (char*)strrchr (wmGD.argv[0], '/')) != NULL) { wmGD.mwmName++; } else { wmGD.mwmName = wmGD.argv[0]; } #ifdef WSM if (MwmBehavior) { res_class = WM_RESOURCE_CLASS; } else { res_class = DT_WM_RESOURCE_CLASS; } wmGD.statusColorServer = CSERVE_NOT_AVAILABLE; #else /* WSM */ res_class = WM_RESOURCE_CLASS; #endif /* WSM */ wmGD.display = (Display *)NULL; wmGD.topLevelW = (Widget)NULL; /* * Do X Tookit initialization: */ XtToolkitInitialize(); wmGD.mwmAppContext = XtCreateApplicationContext(); AddWmResourceConverters (); wmGD.display = XtOpenDisplay (wmGD.mwmAppContext, NULL, wmGD.mwmName, res_class, NULL, 0, &argc, /* R5 changed from Cardinal to int*/ argv); if (!wmGD.display) { Warning(((char *)GETMESSAGE(40, 1, "Could not open display."))); ExitWM (WM_ERROR_EXIT_VALUE); } #if defined(sun) && defined(ALLPLANES) { int dummy; wmGD.allplanes = XAllPlanesQueryExtension(wmGD.display, &dummy, &dummy); } #endif /* defined(sun) && defined(ALLPLANES) */ /* * Setup error handling: */ WmInitErrorHandler(wmGD.display); /* * Initialize cursor size info and * display the startup cursor. */ InitCursorInfo (); #ifdef WSM InitWmDisplayEnv (); #endif ShowWaitState (TRUE); /* * Initialize support for BMenu virtual mouse binding */ InitMouseBinding(); /* * Set up the _MOTIF_BINDINGS property on the root window * of screen 0. Must do this before we create shells. */ ProcessMotifBindings (); #ifndef NO_HP_KEY_REMAP /* VirtKeys4DIN deals with a shortcoming in the OSF/Motif * mechanism for selecting a virtual key binding table. * When a client connects to a display, code inside of libXm * gets the vendor identifier from the server and uses this * identifier to select a default virtual key binding table * from an internal list of possible tables (provided to * OSF by vendors). A virtual key binding table maps OSF * virtual keysyms to an "appropriate" set of X keysyms for * a particular server vendor. The problem with this * mechanism is that it only allows for a _single_ default * virtual key binding table per server vendor. If a * hardware vendor ships more than one distinct keyboard, * then the single virtual key binding table selected for * that server might not be appropriate for all keyboards. * The HP migration from the "ITF" keyboard to the "PC-style" * keyboard causes this problem to be exposed for Motif * clients. The default HP virtual key binding table maps * osfInsert and osfDelete to hpInsertChar and hpDeleteChar, * respectively. But since hpInsertChar and hpDeleteChar * are absent from the PC-style keyboard, HP servers with * this keyboard do not generate key events that map to the * important osfInsert and osfDelete virtual keys. * The Motif 1.2 version of libXm installs (one or two) * properties on the root window, these properties exporting * the virtual key binding table to be used by all (subsequently * connected) Motif clients. The VirtKeys4DIN routine attempts * to ensure that the virtual key binding table exported by * those properties does not include dependencies on keysyms * that are not available in the server's current modmap. * The routine accomplishes this by searching the keyboard * mapping of the display for the absence of known problematic * keysyms. For those keysyms that are missing from the * keyboard map, the corresponding dependencies in the * virtual key binding table are altered to use pre-determined * substitutes (which are generic X keysyms that are present * on the PC-style keyboard mapping). * The side-effects of this routine are that if there are no * key binding properties on the root window when this routine * is called, there will be a property installed (this occurs * with all Motif 1.2 clients anyway). Since the virtual key * binding table is only altered if it contains a keysym that * is missing from the server's keyboard mapping, there is * little chance of deleterious effects. */ VirtKeys4DIN(DISPLAY); #endif /* NO_HP_KEY_REMAP */ argnum = 0; XtSetArg (args[argnum], XtNgeometry, NULL); argnum++; XtSetArg (args[argnum], XtNx, 10000); argnum++; XtSetArg (args[argnum], XtNy, 0); argnum++; XtSetArg (args[argnum], XtNwidth, 10); argnum++; XtSetArg (args[argnum], XtNheight, 10); argnum++; XtSetArg (args[argnum], XtNmappedWhenManaged, False); argnum++; XtSetArg (args[argnum], XtNjoinSession, True); argnum++; #ifdef WSM XtSetArg (args[argnum], XtNrestartStyle, SmRestartNever); argnum++; #else XtSetArg (args[argnum], XtNrestartStyle, SmRestartIfRunning); argnum++; #endif XtSetArg (args[argnum], XtNargc, savedArgc); argnum++; XtSetArg (args[argnum], XtNargv, wmGD.argv); argnum++; /* create topmost shell (application shell) */ wmGD.topLevelW = XtAppCreateShell (NULL, res_class, sessionShellWidgetClass, DISPLAY, args, argnum); #ifdef __osf__ _XmColorObjCreate ( wmGD.topLevelW, NULL, NULL); _XmColorObjCreate ( wmGD.topLevelW, NULL, NULL); #endif XtAddEventHandler(wmGD.topLevelW, NoEventMask, True, MappingEventHandler, NULL); /* Add callbacks used for communication with Session Manager. */ AddSMCallbacks (); /* allocate namespace for screens */ InitScreenNames(); /* * Determine the screen management policy (all or none) * Process command line arguments that we handle * This could change the number of screens we manage */ ProcessGlobalScreenResources (); ProcessCommandLine (argc, argv); #ifdef WSM /* * Make sure backdrops are in our icon search path. * This call MUST occur before ANY icons are looked up either * explicitly or through resource processing!!! * Uses variables set by ProcessGlobalScreenResources and * ProcessCommandLine. */ { int sNum; Boolean useMaskRtn; Boolean useMultiColorIcons; Boolean useIconFileCacheRtn; String sBdPath; sNum = (wmGD.numScreens == 1) ? DefaultScreen(DISPLAY) : 0; XmeGetIconControlInfo(ScreenOfDisplay(DISPLAY, sNum), &useMaskRtn, &useMultiColorIcons, &useIconFileCacheRtn); sBdPath = wmGD.backdropDirs; InsureDefaultBackdropDir ((char **) &sBdPath); _DtWsmSetBackdropSearchPath(XScreenOfDisplay(DISPLAY, sNum), sBdPath, useMultiColorIcons); XtFree(sBdPath); } #endif /* WSM */ /* * Allocate data and initialize for screens we manage: */ if (!(wmGD.Screens = (WmScreenData *) XtCalloc (wmGD.numScreens, sizeof(WmScreenData)))) { ShowWaitState (FALSE); Warning (((char *)GETMESSAGE(40, 2, "Insufficient memory for Screen data"))); ExitWM (WM_ERROR_EXIT_VALUE); } else { sAttributes.event_mask = SubstructureRedirectMask; for (scr=0; scrmanaged) { #ifdef WSM if (XDefaultScreen (wmGD.display) == pSD->screen) { wmGD.commandWindow = wmGD.Screens[scr].wmWorkspaceWin; } #endif /* WSM */ /* * Initialize workspace colormap data. */ InitWorkspaceColormap (pSD); /* * Process the window manager resource description file (.mwmrc): */ #ifdef PANELIST ProcessWmFile (pSD, False /* not nested */); #else /* PANELIST */ ProcessWmFile (pSD); #endif /* PANELIST */ /* * Setup default resources for the system menu and key bindings: */ SetupDefaultResources (pSD); /* * Make global window manager facilities: */ if(pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) { /* create active icon window */ CreateActiveIconTextWindow(pSD); } /* * Make menus and other resources that are used by window manager * functions that are activated by menus, buttons and keys. */ MakeWmFunctionResources (pSD); } #ifdef WSM /* * * Set root cursor to be a pointer for dtwm * */ # ifdef __osf__ /* Fixes problem on multiscreen where cursor is only * set on primary screen. */ if (DtwmBehavior) { XDefineCursor (DISPLAY, RootWindow (DISPLAY, scr), wmGD.workspaceCursor); } # endif #endif /* WSM */ } #ifdef PANELIST /* * Remove any temp config file we created if we needed to * convert DT 2.0 syntax to DT 3.0 */ DeleteTempConfigFileIfAny(); #endif /* PANELIST */ #ifdef WSM /* * Point second display's resource data base * to the first display's resource data base * so dtwm "clients" change colors dynamically. * * NEW LOCATION */ wmGD.display1->db = wmGD.display->db; #endif /* WSM */ /* * Realize the top level widget, make the window override * redirect so we don't manage it, and then move it out of the way */ XtRealizeWidget (wmGD.topLevelW); #ifdef WSM XtRealizeWidget (wmGD.topLevelW1); /* * Initialize the message handling. * (This must be done after the realize because a window * is required for ICCCM-style messaging). */ dtInitializeMessaging (wmGD.topLevelW); #endif /* WSM */ sAttributes.override_redirect = True; XChangeWindowAttributes (DISPLAY, XtWindow (wmGD.topLevelW), CWOverrideRedirect, &sAttributes); /* setup window manager inter-client communications conventions handling */ SetupWmICCC (); /* * Use the WM_SAVE_YOURSELF protocol * for notification of when to save ourself */ #ifdef WSM SetMwmSaveSessionInfo(wmGD.commandWindow); #endif /* * Initialize window manager event handling: */ InitEventHandling (); /* * Initialize frame component graphics */ { for (scr = 0; scr < wmGD.numScreens; scr++) { pSD = &(wmGD.Screens[scr]); if (pSD->managed) { InitClientDecoration (pSD); /* * Make an icon box if specificed: */ if (pSD->useIconBox) { InitIconBox (pSD); } /* * Adopt client windows that exist before wm startup: */ AdoptInitialClients (pSD); /* * Setup initial keyboard focus and colormap focus: */ InitColormapFocus (pSD); } } for (scr = 0; scr < wmGD.numScreens; scr++) { #ifdef WSM int iws; #endif /* WSM */ pSD = &(wmGD.Screens[scr]); if (pSD->managed) { ACTIVE_PSD = &wmGD.Screens[scr]; #ifdef WSM MapIconBoxes (pSD->pActiveWS); ChangeBackdrop (pSD->pActiveWS); #ifdef HP_VUE UpdateWorkspaceInfoProperty (pSD); /* backward compatible */ #endif /* HP_VUE */ SetCurrentWorkspaceProperty (pSD); SetWorkspaceListProperty (pSD); for (iws=0; iws < pSD->numWorkspaces; iws++) { SetWorkspaceInfoProperty (&(pSD->pWS[iws])); } XFlush (DISPLAY); /* MapWorkspaceBox (); */ #ifdef PANELIST /* * Allocate front panel widgets */ if (wmGD.useFrontPanel && (pSD == wmGD.dtSD)) { Pixmap iconBitmap; Arg al[5]; int ac; Widget wFpShell; WmPanelistObject pPanelist; wmGD.dtSD->wPanelist = WmPanelistAllocate(pSD->screenTopLevelW1, (XtPointer) &wmGD, (XtPointer) pSD); pPanelist = (WmPanelistObject) pSD->wPanelist; if (pPanelist != NULL && O_Shell(pPanelist)) { /* * Make a default front panel icon image. */ iconBitmap = XCreateBitmapFromData (DISPLAY, pSD->rootWindow, (char *) fntpl_i_bm_bits, fntpl_i_bm_width, fntpl_i_bm_height); ac = 0; XtSetArg (al[ac], XmNiconPixmap, iconBitmap); ac++; XtSetValues (O_Shell(pPanelist), al, ac); } } if (wmGD.useFrontPanel && pSD->wPanelist && (pSD == wmGD.dtSD)) { /* * Make the front panel visible */ WmPanelistShow (pSD->wPanelist); /* * Find special clients associated with the * front panel. This needs to be done after * WmPanelistShow where the data is set up. */ ScanForPushRecallClients (pSD); ScanForEmbeddedClients (pSD); } #endif /* PANELIST */ RestoreHelpDialogs(pSD); #else /* WSM */ MapIconBoxes (pSD->pActiveWS); #endif /* WSM */ } } firstTime = 0; } InitKeyboardFocus (); #ifndef WSM InitWmDisplayEnv (); #endif ShowWaitState (FALSE); #ifdef WSM /* * Tell the rest of DT that we're up */ dtReadyNotification(); #endif /* WSM */ #ifdef DEBUG_RESOURCE_DATABASE XrmPutFileDatabase(wmGD.display->db, "/tmp/dtwm.resDB"); #endif /* DEBUG_RESOURCE_DATABASE */ } /* END OF FUNCTION InitWmGlobal */ /******************************<->************************************* * * InitWmScreen * * * Description: * ----------- * This function initializes a screen data block. * * Inputs: * ------- * pSD = pointer to preallocated screen data block * sNum = screen number for this screen * * Outputs: * ------- *************************************<->***********************************/ void InitWmScreen (WmScreenData *pSD, int sNum) { Arg args[12]; int argnum; #ifdef WSM int wsnum; WmWorkspaceData *pwsI; int buf_size; int i; static int dupnum = 0; int iwsx; #endif /* WSM */ char *pDisplayName; #define LENCBUFFER 256 char buffer[LENCBUFFER]; /* screen name & display name! */ char displayName[LENCBUFFER]; char *token1, *token2; /* * Set screen data values */ pSD->rootWindow = RootWindow (DISPLAY, sNum); pSD->clientCounter = 0; pSD->defaultSystemMenuUseBuiltin = TRUE; pSD->displayString = NULL; pSD->acceleratorMenuCount = 0; pSD->activeIconTextWin = (Window)NULL; pSD->focusPriority = 0; pSD->inputScreenWindow = (Window)NULL; pSD->colormapFocus = NULL; pSD->keySpecs = NULL; pSD->screen = sNum; pSD->confirmboxW[DEFAULT_BEHAVIOR_ACTION] = NULL; pSD->confirmboxW[CUSTOM_BEHAVIOR_ACTION] = NULL; pSD->confirmboxW[RESTART_ACTION] = NULL; pSD->confirmboxW[QUIT_MWM_ACTION] = NULL; pSD->feedbackWin = (Window)NULL; pSD->fbStyle = FB_OFF; pSD->fbWinWidth = 0; pSD->fbWinHeight = 0; pSD->fbLocation[0] = '\0'; pSD->fbSize[0] = '\0'; pSD->fbLocX = 0; pSD->fbLocY = 0; pSD->fbSizeX = 0; pSD->fbSizeY = 0; pSD->fbLastX = -1; pSD->fbLastY = -1; pSD->fbLastWidth = -1; pSD->fbLastHeight = -1; pSD->fbTop = NULL; pSD->fbBottom = NULL; pSD->actionNbr = -1; pSD->clientList = NULL; pSD->lastClient = NULL; pSD->lastInstalledColormap = (Colormap)NULL; pSD->shrinkWrapGC = NULL; pSD->bitmapCache = NULL; pSD->bitmapCacheSize = 0; pSD->bitmapCacheCount = 0; pSD->dataType = SCREEN_DATA_TYPE; pSD->managed = False; #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) pSD->cciTree = NULL; #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ #ifdef WSM pSD->initialWorkspace=NULL; pSD->presence.shellW = NULL; pSD->presence.onScreen = False; pSD->presence.userDismissed = True; pSD->workspaceList = NULL; pSD->numWorkspaces = 0; pSD->numWsDataAllocated = 0; pSD->lastBackdropWin = NULL; pSD->pDtSessionItems = NULL; pSD->totalSessionItems = 0; pSD->remainingSessionItems = 0; pSD->cachedHelp = NULL; pSD->dtHelp.shell = (Widget)NULL; pSD->dtHelp.dialog = (Widget)NULL; pSD->dtHelp.errorDialog = (Widget)NULL; pSD->dtHelp.xPos = 0; pSD->dtHelp.yPos = 0; pSD->dtHelp.restored = False; pSD->dtHelp.onScreen = False; pSD->dtHelp.userDismissed = False; pSD->dtHelp.pCDforClient= NULL; pSD->helpResources=NULL; pSD->bMarqueeSelectionInitialized = False; pSD->woN = (Window) 0L; pSD->woS = (Window) 0L; pSD->woE = (Window) 0L; pSD->woW = (Window) 0L; #endif /* WSM */ #ifdef PANELIST pSD->wPanelist = NULL; pSD->pECD = NULL; pSD->numPushRecallClients = 0; pSD->numEmbeddedClients = 0; pSD->pPRCD = NULL; pSD->iconBoxControl = False; #endif /* PANELIST */ #ifdef WSM pSD->displayResolutionType = _DtGetDisplayResolution(DISPLAY, sNum); /* * We've got display resolution type--now, let's get color * characteristics. */ ProcessWmColors (pSD); if (!(strcmp ((char *)wmGD.screenNames[sNum], UNSPECIFIED_SCREEN_NAME))) { sprintf (buffer, "%d", sNum); buf_size = strlen(buffer) + 1; if ((wmGD.screenNames[sNum] = (unsigned char *)XtRealloc (wmGD.screenNames[sNum], buf_size)) == NULL) { Warning (((char *)GETMESSAGE(40, 7, "Cannot create enough memory for the screen names"))); ExitWM (WM_ERROR_EXIT_VALUE); } else { strcpy((char *)wmGD.screenNames[sNum], buffer); } } /* if wmGD.screenNames[sNum] == UNSPECIFIED_SCREEN_NAME */ #endif /* WSM */ /* * Save screen context */ XSaveContext (DISPLAY, pSD->rootWindow, wmGD.screenContextType, (caddr_t)pSD); /* * Create shell widget for screen resource hierarchy */ argnum = 0; XtSetArg (args[argnum], XtNgeometry, NULL); argnum++; XtSetArg (args[argnum], XtNx, 10000); argnum++; XtSetArg (args[argnum], XtNy, 10000); argnum++; XtSetArg (args[argnum], XtNwidth, 10); argnum++; XtSetArg (args[argnum], XtNheight, 10); argnum++; XtSetArg (args[argnum], XtNoverrideRedirect, True); argnum++; XtSetArg (args[argnum], XtNdepth, DefaultDepth(DISPLAY, sNum)); argnum++; XtSetArg (args[argnum], XtNscreen, ScreenOfDisplay(DISPLAY, sNum)); argnum++; XtSetArg (args[argnum], XtNcolormap, DefaultColormap(DISPLAY, sNum)); argnum++; pSD->screenTopLevelW = XtCreatePopupShell ((String) wmGD.screenNames[sNum], vendorShellWidgetClass, wmGD.topLevelW, args, argnum); #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL)) /* Create a DrawingArea as a child of the popupShell. This will be used * to handle UTM traffic relating to cci. We need this * particular widget to get the callbacks from conversion requests made * against Mwm and the requests Mwm makes against other clients. */ pSD->utmShell = XmCreateDrawingArea(pSD->screenTopLevelW, "UTM_Shell", NULL, 0); XtManageChild(pSD->utmShell); /* * Setup the destinationCallback handler to handle conversion * requests made by Mwm against other clients. */ XtAddCallback(pSD->utmShell, XmNdestinationCallback, UTMDestinationProc, NULL); /* Must realize to own WM_i if unmapped, causes mwm to freeze when menu is displayed. */ XtPopup(pSD->screenTopLevelW, XtGrabNone); #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */ #ifdef WSM argnum = 0; XtSetArg (args[argnum], XtNgeometry, NULL); argnum++; XtSetArg (args[argnum], XtNx, 10000); argnum++; XtSetArg (args[argnum], XtNy, 10000); argnum++; XtSetArg (args[argnum], XtNwidth, 10); argnum++; XtSetArg (args[argnum], XtNheight, 10); argnum++; XtSetArg (args[argnum], XtNoverrideRedirect, True); argnum++; XtSetArg (args[argnum], XtNmappedWhenManaged, False); argnum++; XtSetArg (args[argnum], XtNdepth, DefaultDepth(DISPLAY1, sNum)); argnum++; XtSetArg (args[argnum], XtNscreen, ScreenOfDisplay(DISPLAY1, sNum)); argnum++; XtSetArg (args[argnum], XtNcolormap, DefaultColormap(DISPLAY1, sNum)); argnum++; pSD->screenTopLevelW1 = XtCreatePopupShell ((String) wmGD.screenNames[sNum], vendorShellWidgetClass, wmGD.topLevelW1, args, argnum); XtRealizeWidget (pSD->screenTopLevelW1); #endif /* WSM */ /* * Fetch screen based resources */ ProcessScreenResources (pSD, wmGD.screenNames[sNum]); /* * Initialize other screen resources and parameters */ MakeXorGC (pSD); InitIconSize(pSD); #ifdef WSM /* * Complete initialization of workspace structures */ for (wsnum = 0, pwsI = pSD->pWS; wsnum < pSD->numWorkspaces; wsnum++, pwsI++) { /* * Set up workspace for this screen */ InitWmWorkspace (pwsI, pSD); } if (pSD->initialWorkspace) { /* * restore to the last initialWorkspace saved from * Quit, Restart, OR save session */ /* * Compare initialWorkspace against workspace name, * NOT workspace title. */ for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++) { if (!strcmp(pSD->pWS[iwsx].name, pSD->initialWorkspace)) { break; } } /* check bounds */ if (iwsx >= pSD->numWorkspaces) { /* make first workspace in list the active one to start with */ pSD->pActiveWS = pSD->pWS; } else { pSD->pActiveWS = &pSD->pWS[iwsx]; } } else { /* make first workspace in list the active one to start with */ pSD->pActiveWS = pSD->pWS; } #else /* WSM */ /* * Allocate and initialize a workspace structure */ if (!(pSD->pWS = (WmWorkspaceData *) XtMalloc (sizeof(WmWorkspaceData)))) { ShowWaitState (FALSE); Warning (((char *)GETMESSAGE(40, 8, "Insufficient memory for Workspace data"))); ExitWM (WM_ERROR_EXIT_VALUE); } /* * Set up workspace for this screen */ InitWmWorkspace (pSD->pWS, pSD); pSD->pActiveWS = pSD->pWS; #endif /* WSM */ pDisplayName = DisplayString (DISPLAY); /* * Construct displayString for this string. * * NOTE: The variable buffer is reused here. It was * used earlier to generate a screen name. */ strcpy(displayName, pDisplayName); token1 = (char*)strtok(displayName, ":"); /* parse of hostname */ if((token2 = (char*)strtok(NULL, ".")) || /* parse off dpy & scr # */ (token2 = (char*)strtok(NULL, "")) || (displayName[0] == ':')) { if (displayName[0] == ':') /* local dpy (special case) */ { if ((token2 = (char*)strtok(token1, ".")) != NULL) /* parse dpy# */ sprintf(buffer, "DISPLAY=:%s.%d", token2, sNum); } else { /* otherwise process normally */ sprintf(buffer, "DISPLAY=%s:%s.%d", token1, token2, sNum); } /* * Allocate space for the display string */ if ((pSD->displayString = (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL) { Warning (((char *)GETMESSAGE(40, 9, "Insufficient memory for displayString"))); } else { strcpy(pSD->displayString, buffer); } } } /* END OF FUNCTION InitWmScreen */ /*************************************<->************************************* * * InitWmWorkspace * * * Description: * ----------- * This function initializes a workspace data block. * * Inputs: * ------- * pWS = pointer to preallocated workspace data block * pSD = ptr to parent screen data block * * Outputs: * ------- *************************************<->***********************************/ void InitWmWorkspace (WmWorkspaceData *pWS, WmScreenData *pSD) { Arg args[10]; int argnum; #ifndef WSM #define DEFAULT_WS_NAME "workspace" #endif /* not WSM */ pWS->pSD = pSD; pWS->pIconBox = NULL; pWS->dataType = WORKSPACE_DATA_TYPE; #ifdef WSM pWS->backdrop.window = 0; pWS->backdrop.nameAtom = 0; pWS->backdrop.image = NULL; pWS->numClients = 0; pWS->sizeClientList = 0; pWS->ppClients = 0; pWS->buttonW = NULL; #else /* WSM */ if ((pWS->name = (char *) XtMalloc ((1+strlen(DEFAULT_WS_NAME)) * sizeof (char))) == NULL) { ShowWaitState (FALSE); ExitWM (WM_ERROR_EXIT_VALUE); } strcpy (pWS->name, DEFAULT_WS_NAME); #endif /* WSM */ /* * Create widget for workspace resource hierarchy */ argnum = 0; XtSetArg (args[argnum], XtNdepth, DefaultDepth(DISPLAY, pSD->screen)); argnum++; XtSetArg (args[argnum], XtNscreen, ScreenOfDisplay(DISPLAY, pSD->screen)); argnum++; XtSetArg (args[argnum], XtNcolormap, DefaultColormap(DISPLAY, pSD->screen)); argnum++; XtSetArg (args[argnum], XtNwidth, 5); argnum++; XtSetArg (args[argnum], XtNheight, 5); argnum++; pWS->workspaceTopLevelW = XtCreateWidget ( pWS->name, xmPrimitiveWidgetClass, pSD->screenTopLevelW, args, argnum); #ifdef WSM /* internalize the workspace name */ pWS->id = XInternAtom (DISPLAY, pWS->name, False); #endif /* WSM */ /* * Process workspace based resources */ ProcessWorkspaceResources (pWS); /* setup icon placement */ if (wmGD.iconAutoPlace) { InitIconPlacement (pWS); } } /* END OF FUNCTION InitWmWorkspace */ #ifdef WSM /******************************<->************************************* * * InsureDefaultBackdropDir(char **ppchBackdropDirs) * * * Description: * ----------- * This function checks and edits a directory path to insure * that the system backdrop directroy (/usr/dt/backdrops) is in the * path. If not it adds it to the end. Further, it always adds the user's * backdrop directory ($HOME/.dt/backdrops) to the beginning of the path * and the system admin directory (/etc/dt/backdrops) before the system * directory. * * Inputs: * ------- * ppchBackdropDirs - Pointer to a pointer to a directory path * (must be allocated memory) * * Outputs: * ------- * *ppchBackdropDirs - Directory path may be modified, path * pointer may be realloc'ed. * * Comments: * -------- * Assumes that the default directory does not start with a * multi-byte character. * ******************************<->***********************************/ static void InsureDefaultBackdropDir(char **ppchBackdropDirs) { int len; Boolean bFound = False; char *pch, *pchEnd, *pch2, *tmpptr; char *pchD = DEFAULT_BACKDROP_DIR; unsigned int chlen; char * homeDir; /* * Set up initial stuff */ pch = *ppchBackdropDirs; len = strlen (pchD); pchEnd = pch + strlen(pch); while (!bFound && (pch != NULL) && (*pch != NULL)) { if (strncmp (pch, pchD, len) == 0) { /* found partial match, confirm complete match ... * complete match if char off end of partial match * is a NULL or a colon */ pch2 = pch + len; if ((pch2 <= pchEnd) && ((*pch2 == NULL) || (((mblen (pch2, MB_CUR_MAX) == 1) && (*pch2 == ':'))))) { bFound = True; } } else { /* find next path component */ pch = strchr (pch, (int) ':'); if ((pch != NULL) && (*pch != NULL)) { /* skip path separator */ chlen = mblen (pch, MB_CUR_MAX); pch += chlen; } } } /* * Always add the user's home directory to the beginning of the string */ homeDir = (char *) XmeGetHomeDirName(); /* * If found add the user's home directory ($HOME/.dt/backdrops) and the * admin directory /etc/dt/backdrops to the beginning of the string */ if (bFound) { len = strlen (homeDir) + strlen("/.dt/backdrops") + strlen (*ppchBackdropDirs) + strlen("/etc/dt/backdrops") + 3; tmpptr = XtMalloc (len * sizeof (char *)); strcpy (tmpptr, homeDir); strcat (tmpptr, "/.dt/backdrops"); strcat (tmpptr, ":"); strcat (tmpptr, "/etc/dt/backdrops"); strcat (tmpptr, ":"); strcat (tmpptr, *ppchBackdropDirs); *ppchBackdropDirs = tmpptr; } else /* * If string not found, then add home directory to the beginning of * string and the admin directory and system directory to the end. */ { len = strlen (homeDir) + strlen("/.dt/backdrops") + strlen (*ppchBackdropDirs) + strlen(pchD) + strlen("/etc/dt/backdrops") + 4; tmpptr = XtMalloc (len * sizeof (char *)); strcpy (tmpptr, homeDir); strcat (tmpptr, "/.dt/backdrops"); strcat (tmpptr, ":"); strcat (tmpptr, *ppchBackdropDirs); strcat (tmpptr, ":"); strcat (tmpptr, "/etc/dt/backdrops"); strcat (tmpptr, ":"); strcat (tmpptr, pchD); *ppchBackdropDirs = tmpptr; } } /* END OF FUNCTION InsureDefaultBackdropDirs */ #endif /* WSM */ /*************************************<->************************************* * * ProcessMotifWmInfo (rootWindowOfScreen) * * * Description: * ----------- * This function is used retrieve and save the information in the * _MOTIF_WM_INFO property. If the property does not exist then * the start / restart state is set to initial startup with the * user specified (not standard) configuration. * * * Outputs: * ------- * wmGD.useStandardBehavior = True if set indicated in property * * wmGD.wmRestarted = True if the window manager was restarted * *************************************<->***********************************/ void ProcessMotifWmInfo (Window rootWindowOfScreen) { MwmInfo *pMwmInfo; wmGD.xa_MWM_INFO = XInternAtom (DISPLAY, _XA_MWM_INFO, False); if ((pMwmInfo = (MotifWmInfo *)GetMwmInfo (rootWindowOfScreen)) != NULL) { wmGD.useStandardBehavior = (pMwmInfo->flags & MWM_INFO_STARTUP_STANDARD) ? True : False; wmGD.wmRestarted = True; XFree ((char *)pMwmInfo); } else { wmGD.useStandardBehavior = False; wmGD.wmRestarted = False; } } /* END OF FUNCTION ProcessMotifWmInfo */ /*************************************<->************************************* * * SetupWmWorkspaceWindows () * * * Description: * ----------- * This function is used to setup a window that can be used in doing window * management functions. This window is not visible on the screen. * * * Outputs: * ------- * pSD->wmWorkspaceWin = window that is used to hold wm properties * *************************************<->***********************************/ void SetupWmWorkspaceWindows (void) { int scr; WmScreenData *pSD; XSetWindowAttributes sAttributes; for (scr = 0; scr < wmGD.numScreens; scr++) { pSD = &(wmGD.Screens[scr]); if (pSD->managed) { sAttributes.override_redirect = True; sAttributes.event_mask = FocusChangeMask | PropertyChangeMask; pSD->wmWorkspaceWin = XCreateWindow (DISPLAY, pSD->rootWindow, -100, -100, 10, 10, 0, 0, InputOnly, CopyFromParent, (CWOverrideRedirect |CWEventMask), &sAttributes); XMapWindow (DISPLAY, pSD->wmWorkspaceWin); SetMwmInfo (pSD->rootWindow, (long) ((wmGD.useStandardBehavior) ? MWM_INFO_STARTUP_STANDARD : MWM_INFO_STARTUP_CUSTOM), pSD->wmWorkspaceWin); #ifdef WSM XSaveContext (DISPLAY, pSD->wmWorkspaceWin, wmGD.mwmWindowContextType, (caddr_t)pSD); #endif /* WSM */ } } } /* END OF FUNCTION SetupWmWorkspaceWindow */ /*************************************<->************************************* * * MakeWorkspaceCursors () * * * Description: * ----------- * This function makes the cursors that the window manager uses. * * * Inputs: * ------ * XXinput = ... * * XXinput = ... * * * Outputs: * ------- * wmGD = (stretchCursors ...) * *************************************<->***********************************/ void MakeWorkspaceCursors (void) { wmGD.workspaceCursor = XCreateFontCursor (DISPLAY, XC_left_ptr); wmGD.stretchCursors[STRETCH_NORTH_WEST] = XCreateFontCursor (DISPLAY, XC_top_left_corner); wmGD.stretchCursors[STRETCH_NORTH] = XCreateFontCursor (DISPLAY, XC_top_side); wmGD.stretchCursors[STRETCH_NORTH_EAST] = XCreateFontCursor (DISPLAY, XC_top_right_corner); wmGD.stretchCursors[STRETCH_EAST] = XCreateFontCursor (DISPLAY, XC_right_side); wmGD.stretchCursors[STRETCH_SOUTH_EAST] = XCreateFontCursor (DISPLAY, XC_bottom_right_corner); wmGD.stretchCursors[STRETCH_SOUTH] = XCreateFontCursor (DISPLAY, XC_bottom_side); wmGD.stretchCursors[STRETCH_SOUTH_WEST] = XCreateFontCursor (DISPLAY, XC_bottom_left_corner); wmGD.stretchCursors[STRETCH_WEST] = XCreateFontCursor (DISPLAY, XC_left_side); wmGD.configCursor = XCreateFontCursor (DISPLAY, XC_fleur); wmGD.movePlacementCursor = XCreateFontCursor (DISPLAY, XC_ul_angle); wmGD.sizePlacementCursor = XCreateFontCursor (DISPLAY, XC_lr_angle); } /* END OF FUNCTION MakeWorkspaceCursors */ /*************************************<->************************************* * * MakeWmFunctionResources (pSD) * * * Description: * ----------- * This function makes menus and other resources that are used by window * manager functions. * * * Inputs: * ------ * wmGD = (menuSpecs, keySpecs, buttonSpecs) * * * Outputs: * ------- * wmGD (menuSpecs) = new menu panes, protocol atoms * *************************************<->***********************************/ void MakeWmFunctionResources (WmScreenData *pSD) { ButtonSpec *buttonSpec; KeySpec *keySpec; MenuSpec *menuSpec; Context menuContext; /* * Scan through the menu specifications and make wm protocol atoms. */ /* * Scan through the button binding specifications making menus if the * f.menu function is invoked. */ buttonSpec = pSD->buttonSpecs; while (buttonSpec) { if (buttonSpec->wmFunction == F_Menu) { if (buttonSpec->context & F_CONTEXT_WINDOW) { menuContext = F_CONTEXT_WINDOW; } else if (buttonSpec->context & F_CONTEXT_ICON) { menuContext = F_CONTEXT_ICON; } else { menuContext = F_CONTEXT_ROOT; } menuSpec = MAKE_MENU (pSD, NULL, buttonSpec->wmFuncArgs, menuContext, buttonSpec->context, (MenuItem *) NULL, FALSE); if (menuSpec) /* * If successful, save in pSD->acceleratorMenuSpecs * Note: these accelerators have nonzero contexts. */ { SaveMenuAccelerators (pSD, menuSpec); } else { buttonSpec->wmFunction = F_Nop; } } buttonSpec = buttonSpec->nextButtonSpec; } /* * Scan through the key binding specifications making menus if the * f.menu function is invoked. */ keySpec = pSD->keySpecs; while (keySpec) { if (keySpec->wmFunction == F_Menu) { if (keySpec->context & F_CONTEXT_WINDOW) { menuContext = F_CONTEXT_WINDOW; } else if (keySpec->context & F_CONTEXT_ICON) { menuContext = F_CONTEXT_ICON; } else { menuContext = F_CONTEXT_ROOT; } menuSpec = MAKE_MENU (pSD, NULL, keySpec->wmFuncArgs, menuContext, keySpec->context, (MenuItem *) NULL, FALSE); if (menuSpec) /* * If successful, save in pSD->acceleratorMenuSpecs * Note: these accelerators have nonzero contexts. */ { SaveMenuAccelerators (pSD, menuSpec); } else { keySpec->wmFunction = F_Nop; } } keySpec = keySpec->nextKeySpec; } } /* END OF FUNCTION MakeWmFunctionResources */ /*************************************<->************************************* * * MakeXorGC (pSD) * * * Description: * ----------- * Make an XOR graphic context for resizing and moving * * * Inputs: * ------ * pSD = pointer to screen data * * Outputs: * ------- * Modifies global data * * Comments: * -------- * * *************************************<->***********************************/ void MakeXorGC (WmScreenData *pSD) { XGCValues gcv; XtGCMask mask; mask = GCFunction | GCLineWidth | GCSubwindowMode | GCCapStyle; gcv.function = GXinvert; gcv.line_width = 0; gcv.cap_style = CapNotLast; gcv.subwindow_mode = IncludeInferiors; /* Fix so that the rubberbanding for resize and move will * have more contrasting colors. */ gcv.plane_mask = BlackPixelOfScreen( DefaultScreenOfDisplay( DISPLAY )) ^ WhitePixelOfScreen( DefaultScreenOfDisplay( DISPLAY )); mask = mask | GCPlaneMask; pSD->xorGC = XCreateGC (DISPLAY, pSD->rootWindow, mask, &gcv); } /* END OF FUNCTION MakeXorGC */ /*************************************<->************************************* * * CopyArgv (argc, argv) * * * Description: * ----------- * This function makes a copy of the window manager's argv for use by * the f.restart function. A copy must be kept because XtInitialize * changes argv. * * * Inputs: * ------ * argc = the number of strings in argv * * argv = window manager parameters * * * Outputs: * ------- * Return = a copy of argv * *************************************<->***********************************/ void CopyArgv (int argc, char *argv []) { int i; if ((wmGD.argv = (char **)XtMalloc ((argc + 1) * sizeof (char *))) == NULL) { Warning (((char *)GETMESSAGE(40, 10, "Insufficient memory for window manager data"))); wmGD.argv = argv; #ifdef WSM dpy2Argv = argv; #endif /* WSM */ } else { for (i = 0; i < argc; i++) { wmGD.argv[i] = argv[i]; } wmGD.argv[i] = NULL; #ifdef WSM if ((dpy2Argv = (char **)XtMalloc((argc + 1) * sizeof(char *))) == NULL) { Warning (((char *)GETMESSAGE(40, 11, "Insufficient memory for window manager data"))); dpy2Argv = argv; } else { for (i = 0; i < argc; i++) { dpy2Argv[i] = argv[i]; } dpy2Argc = argc; dpy2Argv[i] = NULL; } #endif /* WSM */ } } /* END OF FUNCTION CopyArgv */ /*************************************<->************************************* * * InitScreenNames () * * * Description: * ----------- * Initializes the name space for screen names * * Outputs: * ------- * Modifies global data * + screenNames * * Comments: * -------- * Initializes screenNames to contain a numeric name for each screen * *************************************<->***********************************/ void InitScreenNames (void) { int num, numScreens; numScreens = ScreenCount (wmGD.display); if (!(wmGD.screenNames = (unsigned char **) XtMalloc (numScreens * sizeof(char *)))) { ShowWaitState (FALSE); Warning (((char *)GETMESSAGE(40, 12, "Insufficient memory for screen names"))); ExitWM (WM_ERROR_EXIT_VALUE); } for (num=0; num************************************* * * InitWmDisplayEnv * * * Description: * ----------- * This function saves the display string for putenv in F_Exec. * * Inputs: * ------- * * Outputs: * ------- *************************************<->***********************************/ void InitWmDisplayEnv (void) { char *pDisplayName; char buffer[256]; char displayName[256]; pDisplayName = DisplayString (DISPLAY); /* * Construct displayString for this string. */ strcpy(displayName, pDisplayName); sprintf(buffer, "DISPLAY=%s",displayName); /* * Allocate space for the display string */ if ((wmGD.displayString = (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL) { wmGD.displayString = NULL; Warning (((char *)GETMESSAGE(40, 9, "Insufficient memory for displayString"))); } else { strcpy(wmGD.displayString, buffer); #ifdef WSM putenv(wmGD.displayString); #endif /* WSM */ } } /* END OF FUNCTION InitWmDisplayEnv */ #ifndef NO_HP_KEY_REMAP static str_xref GetReplacementList( Display *dsp, str_xref std_xref, int count) { int min_kc ; int max_kc ; int ks_per_kc ; int kc_count ; KeySym *key_map ; unsigned i ; str_xref xref_rtn = NULL ; unsigned num_xref = 0 ; XDisplayKeycodes( dsp, &min_kc, &max_kc) ; kc_count = max_kc + 1 - min_kc ; key_map = XGetKeyboardMapping( dsp, min_kc, kc_count, &ks_per_kc) ; if( key_map == NULL ) { return NULL ; } kc_count *= ks_per_kc ; i = 0 ; while( i < count ) { KeySym ks = XStringToKeysym( std_xref[i].default_name) ; unsigned j = 0 ; while( j < kc_count ) { if( key_map[j] == ks ) { /* Found keysym used in virtkey table in keymap, * so break -> j != kc_count */ break ; } ++j ; } if( j == kc_count ) { /* Didn't find keysym of virtkey table, so add record to * returned list which will later cause replacement in * virtkeys table. */ xref_rtn = (str_xref) XtRealloc( (char *) xref_rtn, sizeof( str_xref_rec) * (num_xref + 2)) ; xref_rtn[num_xref++] = std_xref[i] ; xref_rtn[num_xref].default_name = NULL ; } ++i ; } XFree( (char *) key_map) ; return xref_rtn ; } static Boolean GetBindingsProperty( Display *dsp, Atom property, String *binding) { Atom actual_type ; int actual_format ; unsigned long num_items ; unsigned long bytes_after ; unsigned char *prop = NULL ; XGetWindowProperty( dsp, RootWindow( dsp, 0), property, 0, 1000000L, FALSE, XA_STRING, &actual_type, &actual_format, &num_items, &bytes_after, &prop) ; if( (actual_type != XA_STRING) || (actual_format != 8) || (num_items == 0) ) { if( prop != NULL ) { XFree( prop) ; } return FALSE ; } *binding = (String) prop ; return TRUE ; } static void SetBindingsProperty( Display *dsp, Atom property, String binding) { XChangeProperty( dsp, RootWindow( dsp, 0), property, XA_STRING, 8, PropModeReplace, (unsigned char *) binding, strlen( binding)) ; } static String FixupBindingsString( String bindingsString, str_xref repl_xref) { String fixed_str = XtNewString( bindingsString) ; String ptr_next = fixed_str ; while( repl_xref->default_name != NULL ) { String ks_ptr = strstr( ptr_next, repl_xref->default_name) ; unsigned orig_len = strlen( repl_xref->default_name) ; if( ks_ptr == NULL ) { /* Only increment to next replacement when no other instances * are found in fixed_str. */ ++repl_xref ; ptr_next = fixed_str ; continue ; } if( (strpbrk( (ks_ptr - 1), " \t>") == (ks_ptr - 1)) && (strpbrk( ks_ptr, " \t\n") == (ks_ptr + orig_len)) ) { unsigned new_len = strlen( repl_xref->new_name) ; unsigned suffix_len = strlen( ks_ptr + orig_len) ; if( new_len > orig_len ) { unsigned new_ttl_len = strlen( fixed_str) + new_len - orig_len ; unsigned prefix_len ; *ks_ptr = '\0' ; prefix_len = strlen( fixed_str) ; fixed_str = XtRealloc( fixed_str, (new_ttl_len + 1)) ; ks_ptr = fixed_str + prefix_len ; } memmove( (ks_ptr + new_len), (ks_ptr + orig_len), (suffix_len + 1)) ; memcpy( ks_ptr, repl_xref->new_name, new_len) ; ptr_next = ks_ptr + new_len ; } else { ptr_next = ks_ptr + 1 ; } } return fixed_str ; } Boolean VirtKeys4DIN( Display *dsp) { /* This routine examines the X server's key map table to determine * if certain HP-specific keysyms are missing. If they are, then * the Motif virtual binding table properties are updated to utilize * generic X keysyms instead of the missing HP vendor keysyms. * In particular, this fixes the Motif virtual key binding table for * correct operation on HP systems using the AT2/DIN style keyboard. */ static char *prop_names[] = { "_MOTIF_BINDINGS", "_MOTIF_DEFAULT_BINDINGS" } ; static str_xref_rec std_xref[] = { { "hpInsertChar", "Insert" }, { "hpDeleteChar", "Delete" }, { "End", "F7" }, } ; Boolean PropChanged4DIN = FALSE ; unsigned i ; char *bindingsString ; unsigned prop_existed ; Atom *prop_atoms ; str_xref vkeysym_xref ; unsigned num_props = XtNumber( prop_names) ; vkeysym_xref = GetReplacementList( dsp, std_xref, XtNumber(std_xref)) ; if( vkeysym_xref == NULL ) { return PropChanged4DIN ; } prop_atoms = (Atom *) XtMalloc( sizeof( Atom) * num_props) ; XInternAtoms(dsp, prop_names, num_props, FALSE, prop_atoms); prop_existed = FALSE ; i = 0 ; while( i < num_props ) { if( GetBindingsProperty( dsp, prop_atoms[i], &bindingsString) ) { String new_bstring = FixupBindingsString( bindingsString, vkeysym_xref) ; prop_existed = TRUE ; XFree( bindingsString) ; if( new_bstring != NULL ) { SetBindingsProperty( dsp, prop_atoms[i], new_bstring) ; XtFree( new_bstring) ; } } ++i ; } if( !prop_existed ) { bindingsString = NULL ; _XmVirtKeysLoadFallbackBindings( dsp, &bindingsString) ; XtFree( bindingsString) ; i = 0 ; while( i < num_props ) { if( GetBindingsProperty( dsp, prop_atoms[i], &bindingsString) ) { String new_bstring = FixupBindingsString( bindingsString, vkeysym_xref) ; XtFree( bindingsString) ; if( new_bstring != NULL ) { PropChanged4DIN = TRUE ; SetBindingsProperty( dsp, prop_atoms[i], new_bstring) ; XtFree( new_bstring) ; } XFree( bindingsString) ; } ++i ; } } XtFree( (char *) vkeysym_xref) ; XtFree( (char *) prop_atoms) ; return PropChanged4DIN ; } #endif /* NO_HP_KEY_REMAP */ #ifdef WSM /**************************** eof ***************************/ #endif /* WSM */