source: trunk/third/mwm/WmInitWs.c @ 9757

Revision 9757, 29.3 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9756, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
3 * ALL RIGHTS RESERVED
4*/
5/*
6 * Motif Release 1.2.3
7*/
8#ifdef REV_INFO
9#ifndef lint
10static char rcsid[] = "$RCSfile: WmInitWs.c,v $ $Revision: 1.1.1.1 $ $Date: 1997-03-25 09:12:21 $"
11#endif
12#endif
13/*
14 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
15
16/*
17 * Included Files:
18 */
19
20#include "WmGlobal.h"
21#include "WmResNames.h"
22#include "WmICCC.h"
23#include <X11/Xos.h>
24#include <X11/cursorfont.h>
25#include <Xm/Xm.h>
26#include <Xm/XmP.h>     /* just for XmRegisterConverters decl */
27#include <X11/Shell.h>
28#include <X11/Core.h>
29
30/*
31 * include extern functions
32 */
33#include "WmCDInfo.h"
34#include "WmColormap.h"
35#include "WmError.h"
36#include "WmEvent.h"
37#include "WmFeedback.h"
38#include "WmFunction.h"
39#include "WmIDecor.h"
40#include "WmIPlace.h"
41#include "WmIconBox.h"
42#include "WmKeyFocus.h"
43#include "WmManage.h"
44#include "WmMenu.h"
45#include "WmProperty.h"
46#include "WmResCvt.h"
47#include "WmResource.h"
48#include "WmSignal.h"
49#include "WmProtocol.h"
50#include "WmCDecor.h"
51#include "stdio.h"
52#include "WmResParse.h"
53
54/*
55 * Function Declarations:
56 */
57
58#ifdef _NO_PROTO
59void CopyArgv ();
60void InitWmDisplayEnv ();
61void InitWmGlobal ();
62void InitWmScreen ();
63void InitScreenNames ();
64void InitWmWorkspace ();
65void ProcessMotifWmInfo ();
66void SetupWmWorkspaceWindows ();
67void MakeWmFunctionResources ();
68void MakeWorkspaceCursors ();
69void MakeXorGC ();
70#else /* _NO_PROTO */
71void InitWmDisplayEnv (void);
72void InitWmGlobal (int argc, char *argv [], char *environ []);
73void InitWmScreen (WmScreenData *pSD, int sNum);
74void InitWmWorkspace (WmWorkspaceData *pWS, WmScreenData *pSD);
75void ProcessMotifWmInfo (Window rootWindowOfScreen);
76void SetupWmWorkspaceWindows (void);
77void MakeWorkspaceCursors (void);
78void MakeWmFunctionResources (WmScreenData *pSD);
79void MakeXorGC (WmScreenData *pSD);
80void CopyArgv (int argc, char *argv []);
81void InitScreenNames (void);
82#endif /* _NO_PROTO */
83
84/*
85 * Global Variables:
86 */
87extern int firstTime;
88
89
90/******************************<->*************************************
91 *
92 *  InitWmGlobal (argc, argv, environ)
93 *
94 *
95 *  Description:
96 *  -----------
97 *  This function initializes the workspace manager.
98 *
99 *
100 *  Inputs:
101 *  ------
102 *  argc = number of command line arguments (+1)
103 *
104 *  argv = window manager command line arguments
105 *
106 *  environ = window manager environment
107 *
108 *
109 *  Outputs:
110 *  -------
111 *  wmGD = (initialize the global data structure)
112 *
113 *************************************<->***********************************/
114
115#ifdef _NO_PROTO
116void InitWmGlobal (argc, argv, environ)
117    int argc;
118    char *argv[];
119    char *environ[];
120
121#else /* _NO_PROTO */
122void InitWmGlobal (int argc, char *argv [], char *environ [])
123#endif /* _NO_PROTO */
124{
125    XSetWindowAttributes sAttributes;
126    int scr;
127    int managed = 0;
128    char pch[80];
129    Boolean activeSet = False;
130    Boolean processedGlobalResources = False;
131    WmScreenData *pSD;
132    Arg args[11];
133    int argnum;
134    char *res_class;
135    wmGD.errorFlag = False;
136
137#ifdef _NO_PROTO
138    SetupWmSignalHandlers ();
139#else
140    SetupWmSignalHandlers (0); /* dummy paramater */
141#endif
142
143
144    /*
145     * Do (pre-toolkit) initialization:
146     */
147
148    wmGD.windowContextType = XUniqueContext ();
149    wmGD.screenContextType = XUniqueContext ();
150
151    /* copy argv (the XtInititalize changes the original) for use in restart */
152    CopyArgv (argc, argv);
153
154    wmGD.environ = environ;
155
156
157
158
159    /* set our name */
160    if ((wmGD.mwmName = (char*)strrchr (wmGD.argv[0], '/')) != NULL)
161    {
162        wmGD.mwmName++;
163    }
164    else
165    {
166        wmGD.mwmName = wmGD.argv[0];
167    }
168    res_class = WM_RESOURCE_CLASS;
169
170    wmGD.display = NULL;
171
172
173    /*
174     * Do X Tookit initialization:
175     *
176     */   
177
178    XtToolkitInitialize();
179
180    XmRegisterConverters ();
181
182    wmGD.mwmAppContext = XtCreateApplicationContext();
183    wmGD.display = XtOpenDisplay (wmGD.mwmAppContext,
184                                  NULL,
185                                  wmGD.mwmName,
186                                  res_class,
187                                  NULL,
188                                  0,
189                                  &argc, /* R5 changed from Cardinal to int*/
190                                  argv);
191   
192    if (!wmGD.display)
193    {
194        Warning("Could not open display.");
195        exit (WM_ERROR_EXIT_VALUE);
196    }
197
198    /*
199     * Setup error handling:
200     */
201
202    WmInitErrorHandler(wmGD.display);
203
204    /*
205     * Initialize cursor size info and
206     * display the startup cursor.
207     */
208   
209    InitCursorInfo ();
210    ShowWaitState (TRUE);
211
212    /*
213     * Set up the _MOTIF_BINDINGS property on the root window
214     * of screen 0.  Must do this before we create shells.
215     */
216   
217    ProcessMotifBindings ();
218   
219    argnum = 0;
220    XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
221    XtSetArg (args[argnum], XtNx, 10000);       argnum++;
222    XtSetArg (args[argnum], XtNy, 0);           argnum++;
223    XtSetArg (args[argnum], XtNwidth, 10);      argnum++;
224    XtSetArg (args[argnum], XtNheight, 10);     argnum++;
225
226    /* create topmost shell (application shell) */
227    wmGD.topLevelW = XtAppCreateShell (NULL,
228                              res_class,
229                              applicationShellWidgetClass,
230                              DISPLAY,
231                              args,
232                              argnum);
233   
234    /* allocate namespace for screens */
235    InitScreenNames();
236   
237    /*
238     * Determine the screen management policy (all or none)
239     * Process command line arguments that we handle
240     * This could change the number of screens we manage
241     */
242    ProcessGlobalScreenResources ();
243    ProcessCommandLine (argc, argv);
244
245
246    /*
247     * Allocate data and initialize for screens we manage:
248     */
249
250    if (!(wmGD.Screens = (WmScreenData *)
251            XtMalloc (wmGD.numScreens * sizeof(WmScreenData))))
252    {
253        ShowWaitState (FALSE);
254        Warning ("Insufficient memory for Screen data");
255        exit (WM_ERROR_EXIT_VALUE);
256    }
257    else
258    {
259
260        sAttributes.event_mask = SubstructureRedirectMask;
261
262        for (scr=0; scr<wmGD.numScreens; scr++)
263        {
264            int sNum;
265           
266            /*
267             * Gain control of the root windows of each screen:
268             */
269
270            sNum = (wmGD.numScreens == 1) ? DefaultScreen(DISPLAY) : scr;
271            wmGD.errorFlag = False;
272
273            XChangeWindowAttributes (DISPLAY, RootWindow (DISPLAY, sNum),
274                CWEventMask, &sAttributes);
275            /*
276             * Do XSync to force server action and catch errors
277             * immediately.
278             */
279            XSync (DISPLAY, False /* do not discard events */);
280
281            if (wmGD.errorFlag)
282            {
283                sprintf(pch,
284                    "Another window manager is running on screen %d", sNum);
285                Warning ((char *) &pch[0]);
286                wmGD.Screens[scr].managed = False;
287            }
288            else
289            {
290                if (!processedGlobalResources)
291                {
292
293#ifndef NO_SHAPE
294                    wmGD.hasShape = XShapeQueryExtension (DISPLAY,
295                                                          &wmGD.shapeEventBase,
296                                                          &wmGD.shapeErrorBase);
297#endif /*  NO_SHAPE  */
298
299                    wmGD.menuActive = NULL;
300                    wmGD.menuUnpostKeySpec = NULL;
301                    wmGD.F_NextKeySpec = NULL;
302                    wmGD.F_PrevKeySpec = NULL;
303                    wmGD.passKeysActive = False;
304                    wmGD.passKeysKeySpec = NULL;
305                    wmGD.checkHotspot = False;
306                    wmGD.configAction = NO_ACTION;
307                    wmGD.configPart = FRAME_NONE;
308                    wmGD.configSet = False;
309                    wmGD.preMove = False;
310                    wmGD.gadgetClient = NULL;
311                    wmGD.wmTimers = NULL;
312                    wmGD.clientDefaultTitle =
313                        XmStringCreateLtoR(DEFAULT_CLIENT_TITLE,
314                                           XmFONTLIST_DEFAULT_TAG);
315                    wmGD.iconDefaultTitle =
316                        XmStringCreateLtoR(DEFAULT_ICON_TITLE,
317                                           XmFONTLIST_DEFAULT_TAG);
318                    wmGD.attributesWindow = (Window)NULL;
319                    wmGD.clickData.pCD = NULL;
320                    wmGD.clickData.clickPending = False;
321                    wmGD.clickData.doubleClickPending = False;
322                    wmGD.systemModalActive = False;
323                    wmGD.activeIconTextDisplayed = False;
324                    wmGD.movingIcon = False;
325                    wmGD.queryScreen = True;
326                    wmGD.dataType = GLOBAL_DATA_TYPE;
327                   
328
329                    /*
330                     * if this is the first screen we can manage,
331                     * process global.
332                     */
333                   
334                    processedGlobalResources = True;
335
336                    /*
337                     * Get the _MOTIF_WM_INFO property and determine
338                     * the startup / restart state.
339                     */
340                   
341                    ProcessMotifWmInfo (RootWindow (DISPLAY, sNum));
342                   
343                    /*
344                     * Process global window manager resources:
345                     */
346                   
347                    AddWmResourceConverters ();
348                    ProcessWmResources ();
349
350                }
351               
352                InitWmScreen (&(wmGD.Screens[scr]), sNum);
353                wmGD.Screens[scr].managed = True;
354                managed++;
355
356                if (!activeSet)
357                {
358                    activeSet = True;
359                    ACTIVE_PSD = &wmGD.Screens[scr];
360                }
361            }
362        }
363
364        if (managed == 0)
365        {
366            /*
367             * No screens for me to manage, give up.
368             */
369            ShowWaitState (FALSE);
370            Warning ("Unable to manage any screens on display.");
371            exit (WM_ERROR_EXIT_VALUE);
372        }
373    }
374   
375
376    /*
377     * Prepare to have child processes (e.g., exec'ed commands).
378     * The X connection should not be passed on to child processes
379     * (it should be automatically closed when a fork is done).
380     */
381
382    if (fcntl (ConnectionNumber (DISPLAY), F_SETFD, 1) == -1)
383    {
384        ShowWaitState (FALSE);
385        Warning ("Cannot configure X connection");
386        exit (WM_ERROR_EXIT_VALUE);
387    }
388
389
390    /*
391     * Make the window manager workspace window.
392     * Setup the _MOTIF_WM_INFO property on the root window.
393     */
394
395    SetupWmWorkspaceWindows ();
396
397
398    /* make the cursors that the window manager uses */
399    MakeWorkspaceCursors ();
400
401
402    /* Sync the table used by Mwm's modifier parser to actual modMasks used */
403    SyncModifierStrings();
404
405    /*
406     * Setup screen data and resources (after processing Wm resources.
407     */
408    for (scr = 0; scr < wmGD.numScreens; scr++)
409    {
410        pSD = &(wmGD.Screens[scr]);
411
412        if (pSD->managed)
413        {
414            /*
415             * Initialize workspace colormap data.
416             */
417
418            InitWorkspaceColormap (pSD);
419
420            /*
421             * Process the window manager resource description file (.mwmrc):
422             */
423
424            ProcessWmFile (pSD);
425
426
427            /*
428             * Setup default resources for the system menu and key bindings:
429             */
430
431            SetupDefaultResources (pSD);
432
433
434            /*
435             * Make global window manager facilities:
436             */
437
438            if(pSD->iconDecoration & ICON_ACTIVE_LABEL_PART)
439            {
440                /* create active icon window */
441                CreateActiveIconTextWindow(pSD);
442            }
443
444
445            /*
446             * Make menus and other resources that are used by window manager
447             * functions that are activated by menus, buttons and keys.
448             */
449
450            MakeWmFunctionResources (pSD);
451        }
452
453
454    }
455
456    /*
457     * Realize the top level widget, make the window override
458     * redirect so we don't manage it, and then move it out of the way
459     */
460
461    XtRealizeWidget (wmGD.topLevelW);
462
463    sAttributes.override_redirect = True;
464    XChangeWindowAttributes (DISPLAY, XtWindow (wmGD.topLevelW),
465                CWOverrideRedirect, &sAttributes);
466
467
468    /* setup window manager inter-client communications conventions handling */
469    SetupWmICCC ();
470
471
472    /*
473     * Initialize window manager event handling:
474     */
475
476    InitEventHandling ();
477
478
479
480    /*
481     * Initialize frame component graphics
482     */
483    {
484        for (scr = 0; scr < wmGD.numScreens; scr++)
485        {
486            pSD = &(wmGD.Screens[scr]);
487
488            if (pSD->managed)
489            {
490                InitClientDecoration (pSD);
491
492                /*
493                 * Make an icon box if specificed:
494                 */
495                if (pSD->useIconBox)
496                {
497                    InitIconBox (pSD);
498                }
499
500                /*
501                 * Adopt client windows that exist before wm startup:
502                 */
503
504                AdoptInitialClients (pSD);
505
506                /*
507                 * Setup initial keyboard focus and colormap focus:
508                 */
509
510                InitColormapFocus (pSD);
511
512            }
513        }
514
515        for (scr = 0; scr < wmGD.numScreens; scr++)
516        {
517            pSD = &(wmGD.Screens[scr]);
518           
519            if (pSD->managed)
520            {
521                ACTIVE_PSD = &wmGD.Screens[scr];
522                MapIconBoxes (pSD->pActiveWS);
523            }
524        }
525        firstTime = 0;
526    }
527   
528    InitKeyboardFocus ();
529
530    InitWmDisplayEnv ();
531    ShowWaitState (FALSE);
532
533#ifdef AUTOMATION
534        AutoInitByteOrderChar();
535#endif
536
537
538} /* END OF FUNCTION InitWmGlobal */
539
540
541
542/******************************<->*************************************
543 *
544 *  InitWmScreen
545 *
546 *
547 *  Description:
548 *  -----------
549 *  This function initializes a screen data block.
550 *
551 *  Inputs:
552 *  -------
553 *  pSD = pointer to preallocated screen data block
554 *  sNum = screen number for this screen
555 *
556 *  Outputs:
557 *  -------
558 *************************************<->***********************************/
559
560#ifdef _NO_PROTO
561void
562InitWmScreen (pSD, sNum)
563    WmScreenData *pSD;
564    int sNum;
565#else /* _NO_PROTO */
566void
567InitWmScreen (WmScreenData *pSD, int sNum)
568#endif /* _NO_PROTO */
569{
570    Arg args[12];
571    int argnum;
572
573
574    char *pDisplayName;
575    char buffer[256];
576    char displayName[256];
577    char *token1, *token2;
578
579
580   /*
581    * Set screen data values
582    */
583
584    pSD->rootWindow = RootWindow (DISPLAY, sNum);
585    pSD->clientCounter = 0;
586    pSD->defaultSystemMenuUseBuiltin = TRUE;
587    pSD->displayString = NULL;
588    pSD->acceleratorMenuCount = 0;
589    pSD->activeIconTextWin = (Window)NULL;
590    pSD->focusPriority = 0;
591    pSD->inputScreenWindow = (Window)NULL;
592    pSD->colormapFocus = NULL;
593    pSD->keySpecs = NULL;
594    pSD->screen = sNum;
595    pSD->confirmboxW[DEFAULT_BEHAVIOR_ACTION] = NULL;
596    pSD->confirmboxW[CUSTOM_BEHAVIOR_ACTION] = NULL;
597    pSD->confirmboxW[RESTART_ACTION] = NULL;
598    pSD->confirmboxW[QUIT_MWM_ACTION] = NULL;
599    pSD->feedbackWin = (Window)NULL;
600    pSD->fbStyle = FB_OFF;
601    pSD->fbWinWidth = 0;
602    pSD->fbWinHeight = 0;
603    pSD->fbLocation[0] = '\0';
604    pSD->fbSize[0] = '\0';
605    pSD->fbLocX = 0;
606    pSD->fbLocY = 0;
607    pSD->fbSizeX = 0;
608    pSD->fbSizeY = 0;
609    pSD->fbLastX = -1;
610    pSD->fbLastY = -1;
611    pSD->fbLastWidth = -1;
612    pSD->fbLastHeight = -1;
613    pSD->fbTop = NULL;
614    pSD->fbBottom = NULL;
615    pSD->actionNbr = -1;
616    pSD->clientList = NULL;
617    pSD->lastClient = NULL;
618    pSD->lastInstalledColormap = (Colormap)NULL;
619    pSD->shrinkWrapGC = NULL;
620    pSD->bitmapCache = NULL;
621    pSD->bitmapCacheSize = 0;
622    pSD->bitmapCacheCount = 0;
623    pSD->dataType = SCREEN_DATA_TYPE;
624    /*
625     * Save screen context
626     */
627    XSaveContext (DISPLAY, pSD->rootWindow, wmGD.screenContextType,
628        (caddr_t)pSD);
629    /*
630     * Create shell widget for screen resource hierarchy
631     */
632
633    argnum = 0;
634    XtSetArg (args[argnum], XtNgeometry, NULL); argnum++;
635    XtSetArg (args[argnum], XtNx, 10000);       argnum++;
636    XtSetArg (args[argnum], XtNy, 10000);       argnum++;
637    XtSetArg (args[argnum], XtNwidth, 10);      argnum++;
638    XtSetArg (args[argnum], XtNheight, 10);     argnum++;
639    XtSetArg (args[argnum], XtNoverrideRedirect, True); argnum++;
640
641    XtSetArg (args[argnum], XtNdepth,
642            DefaultDepth(DISPLAY, sNum));       argnum++;
643    XtSetArg (args[argnum], XtNscreen,
644            ScreenOfDisplay(DISPLAY, sNum));    argnum++;
645    XtSetArg (args[argnum], XtNcolormap,
646            DefaultColormap(DISPLAY, sNum));    argnum++;
647
648    pSD->screenTopLevelW = XtCreatePopupShell ((String) wmGD.screenNames[sNum],
649                                               vendorShellWidgetClass,
650                                               wmGD.topLevelW,
651                                               args,
652                                               argnum);
653    /*
654     * Fetch screen based resources
655     */
656    ProcessScreenResources (pSD, wmGD.screenNames[sNum]);
657
658    /*
659     * Initialize other screen resources and parameters
660     */
661    MakeXorGC (pSD);
662    InitIconSize(pSD);
663
664    /*
665     *  Allocate and initialize a workspace structure
666     */
667   
668    if (!(pSD->pWS = (WmWorkspaceData *) XtMalloc (sizeof(WmWorkspaceData))))
669    {
670        ShowWaitState (FALSE);
671        Warning ("Insufficient memory for Workspace data");
672        exit (WM_ERROR_EXIT_VALUE);
673    }
674
675    /*
676     * Set up workspace for this screen
677     */
678    InitWmWorkspace (pSD->pWS, pSD);
679    pSD->pActiveWS = pSD->pWS;
680
681
682    pDisplayName = DisplayString (DISPLAY);
683
684    /*
685     * Construct displayString for this string. 
686     */
687
688    strcpy(displayName, pDisplayName);
689
690    token1 = (char*)strtok(displayName, ":");           /* parse of hostname */
691
692    if((token2 = (char*)strtok(NULL, ".")) ||           /* parse off dpy & scr # */
693       (token2 = (char*)strtok(NULL, "")) ||
694       (displayName[0] == ':'))
695    {
696        if (displayName[0] == ':')              /* local dpy (special case) */
697        {
698            if ((token2 = (char*)strtok(token1, ".")) != NULL)  /* parse dpy# */
699                sprintf(buffer, "DISPLAY=:%s.%d",
700                        token2, sNum);
701        } else {                                /* otherwise process normally */
702            sprintf(buffer, "DISPLAY=%s:%s.%d",
703                    token1, token2, sNum);
704        }
705
706        /*             
707         * Allocate space for the display string
708         */
709   
710        if ((pSD->displayString =
711             (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL)
712        {
713            Warning ("Insufficient memory for displayString");
714        }
715        else
716        {
717            strcpy(pSD->displayString, buffer);
718        }
719
720    }
721
722
723
724} /* END OF FUNCTION  InitWmScreen */
725
726
727/*************************************<->*************************************
728 *
729 *  InitWmWorkspace
730 *
731 *
732 *  Description:
733 *  -----------
734 *  This function initializes a workspace data block.
735 *
736 *  Inputs:
737 *  -------
738 *  pWS = pointer to preallocated workspace data block
739 *  pSD = ptr to parent screen data block
740 *
741 *  Outputs:
742 *  -------
743 *************************************<->***********************************/
744
745#ifdef _NO_PROTO
746void InitWmWorkspace (pWS, pSD)
747    WmWorkspaceData *pWS;
748    WmScreenData *pSD;
749
750#else /* _NO_PROTO */
751void InitWmWorkspace (WmWorkspaceData *pWS, WmScreenData *pSD)
752#endif /* _NO_PROTO */
753{
754    Arg args[10];
755    int argnum;
756
757#define DEFAULT_WS_NAME "workspace"
758
759    pWS->pSD = pSD;
760    pWS->pIconBox = NULL;
761    pWS->dataType = WORKSPACE_DATA_TYPE;
762
763    if ((pWS->name = (char *)
764            XtMalloc ((1+strlen(DEFAULT_WS_NAME)) * sizeof (char))) == NULL)
765    {
766        ShowWaitState (FALSE);
767        exit (WM_ERROR_EXIT_VALUE);
768    }
769    strcpy (pWS->name, DEFAULT_WS_NAME);
770
771    /*
772     * Create widget for workspace resource hierarchy
773     */
774    argnum = 0;
775    XtSetArg (args[argnum], XtNdepth,
776            DefaultDepth(DISPLAY, pSD->screen));        argnum++;
777    XtSetArg (args[argnum], XtNscreen,
778            ScreenOfDisplay(DISPLAY, pSD->screen));     argnum++;
779    XtSetArg (args[argnum], XtNcolormap,
780            DefaultColormap(DISPLAY, pSD->screen));     argnum++;
781    XtSetArg (args[argnum], XtNwidth,  5);              argnum++;
782    XtSetArg (args[argnum], XtNheight,  5);             argnum++;
783
784    pWS->workspaceTopLevelW = XtCreateWidget (  pWS->name,
785                                                xmPrimitiveWidgetClass,
786                                                pSD->screenTopLevelW,
787                                                args,
788                                                argnum);
789
790
791    /*
792     * Process workspace based resources
793     */
794    ProcessWorkspaceResources (pWS);   
795
796    /* setup icon placement */
797    if (wmGD.iconAutoPlace)
798    {
799        InitIconPlacement (pWS);
800    }
801
802} /* END OF FUNCTION  InitWmWorkspace */
803
804
805
806/*************************************<->*************************************
807 *
808 *  ProcessMotifWmInfo (rootWindowOfScreen)
809 *
810 *
811 *  Description:
812 *  -----------
813 *  This function is used retrieve and save the information in the
814 *  _MOTIF_WM_INFO property.  If the property does not exist then
815 *  the start / restart state is set to initial startup with the
816 *  user specified (not standard) configuration.
817 *
818 *
819 *  Outputs:
820 *  -------
821 *  wmGD.useStandardBehavior = True if set indicated in property
822 *
823 *  wmGD.wmRestarted = True if the window manager was restarted
824 *
825 *************************************<->***********************************/
826
827#ifdef _NO_PROTO
828void ProcessMotifWmInfo (rootWindowOfScreen)
829    Window rootWindowOfScreen;
830#else /* _NO_PROTO */
831void ProcessMotifWmInfo (Window rootWindowOfScreen)
832#endif /* _NO_PROTO */
833{
834    MwmInfo *pMwmInfo;
835
836    wmGD.xa_MWM_INFO = XInternAtom (DISPLAY, _XA_MWM_INFO, False);
837    if ((pMwmInfo = (MotifWmInfo *)GetMwmInfo (rootWindowOfScreen)) != NULL)
838    {
839        wmGD.useStandardBehavior =
840                (pMwmInfo->flags & MWM_INFO_STARTUP_STANDARD) ? True : False;
841        wmGD.wmRestarted = True;
842        XFree ((char *)pMwmInfo);
843    }
844    else
845    {
846        wmGD.useStandardBehavior = False;
847        wmGD.wmRestarted = False;
848    }
849
850} /* END OF FUNCTION ProcessMotifWmInfo */
851
852
853
854/*************************************<->*************************************
855 *
856 *  SetupWmWorkspaceWindows ()
857 *
858 *
859 *  Description:
860 *  -----------
861 *  This function is used to setup a window that can be used in doing window
862 *  management functions.  This window is not visible on the screen.
863 *
864 *
865 *  Outputs:
866 *  -------
867 *  pSD->wmWorkspaceWin = window that is used to hold wm properties
868 *
869 *************************************<->***********************************/
870
871#ifdef _NO_PROTO
872void SetupWmWorkspaceWindows ()
873
874#else /* _NO_PROTO */
875void SetupWmWorkspaceWindows (void)
876#endif /* _NO_PROTO */
877{
878    int scr;
879    WmScreenData *pSD;
880    XSetWindowAttributes sAttributes;
881
882    for (scr = 0; scr < wmGD.numScreens; scr++)
883    {
884        pSD = &(wmGD.Screens[scr]);
885        if (pSD->managed)
886        {
887            sAttributes.override_redirect = True;
888            sAttributes.event_mask = FocusChangeMask;
889            pSD->wmWorkspaceWin = XCreateWindow (DISPLAY, pSD->rootWindow,
890                                      -100, -100, 10, 10, 0, 0,
891                                      InputOnly, CopyFromParent,
892                                      (CWOverrideRedirect |CWEventMask),
893                                      &sAttributes);
894
895            XMapWindow (DISPLAY, pSD->wmWorkspaceWin);
896
897            SetMwmInfo (pSD->rootWindow,
898                        (long) ((wmGD.useStandardBehavior) ?
899                        MWM_INFO_STARTUP_STANDARD : MWM_INFO_STARTUP_CUSTOM),
900                        pSD->wmWorkspaceWin);
901        }
902    }
903
904} /* END OF FUNCTION SetupWmWorkspaceWindow */
905
906
907
908/*************************************<->*************************************
909 *
910 *  MakeWorkspaceCursors ()
911 *
912 *
913 *  Description:
914 *  -----------
915 *  This function makes the cursors that the window manager uses.
916 *
917 *
918 *  Inputs:
919 *  ------
920 *  XXinput = ...
921 *
922 *  XXinput = ...
923 *
924 *
925 *  Outputs:
926 *  -------
927 *  wmGD = (stretchCursors ...)
928 *
929 *************************************<->***********************************/
930
931#ifdef _NO_PROTO
932void MakeWorkspaceCursors ()
933
934#else /* _NO_PROTO */
935void MakeWorkspaceCursors (void)
936#endif /* _NO_PROTO */
937{
938    wmGD.workspaceCursor = XCreateFontCursor (DISPLAY, XC_left_ptr);
939
940    wmGD.stretchCursors[STRETCH_NORTH_WEST] =
941        XCreateFontCursor (DISPLAY, XC_top_left_corner);
942    wmGD.stretchCursors[STRETCH_NORTH] =
943        XCreateFontCursor (DISPLAY, XC_top_side);
944    wmGD.stretchCursors[STRETCH_NORTH_EAST] =
945        XCreateFontCursor (DISPLAY, XC_top_right_corner);
946    wmGD.stretchCursors[STRETCH_EAST] =
947        XCreateFontCursor (DISPLAY, XC_right_side);
948    wmGD.stretchCursors[STRETCH_SOUTH_EAST] =
949        XCreateFontCursor (DISPLAY, XC_bottom_right_corner);
950    wmGD.stretchCursors[STRETCH_SOUTH] =
951        XCreateFontCursor (DISPLAY, XC_bottom_side);
952    wmGD.stretchCursors[STRETCH_SOUTH_WEST] =
953        XCreateFontCursor (DISPLAY, XC_bottom_left_corner);
954    wmGD.stretchCursors[STRETCH_WEST] =
955        XCreateFontCursor (DISPLAY, XC_left_side);
956
957    wmGD.configCursor = XCreateFontCursor (DISPLAY, XC_fleur);
958
959    wmGD.movePlacementCursor = XCreateFontCursor (DISPLAY, XC_ul_angle);
960    wmGD.sizePlacementCursor = XCreateFontCursor (DISPLAY, XC_lr_angle);
961
962
963} /* END OF FUNCTION MakeWorkspaceCursors */
964
965
966
967/*************************************<->*************************************
968 *
969 *  MakeWmFunctionResources (pSD)
970 *
971 *
972 *  Description:
973 *  -----------
974 *  This function makes menus and other resources that are used by window
975 *  manager functions.
976 *
977 *
978 *  Inputs:
979 *  ------
980 *  wmGD  = (menuSpecs, keySpecs, buttonSpecs)
981 *
982 *
983 *  Outputs:
984 *  -------
985 *  wmGD (menuSpecs) = new menu panes, protocol atoms
986 *
987 *************************************<->***********************************/
988
989#ifdef _NO_PROTO
990void MakeWmFunctionResources (pSD)
991
992    WmScreenData *pSD;
993
994#else /* _NO_PROTO */
995void MakeWmFunctionResources (WmScreenData *pSD)
996#endif /* _NO_PROTO */
997{
998    ButtonSpec *buttonSpec;
999    KeySpec    *keySpec;
1000    MenuSpec   *menuSpec;
1001    Context     menuContext;
1002
1003
1004    /*
1005     * Scan through the menu specifications and make wm protocol atoms.
1006     */
1007
1008
1009    /*
1010     * Scan through the button binding specifications making menus if the
1011     * f.menu function is invoked.
1012     */
1013
1014    buttonSpec = pSD->buttonSpecs;
1015    while (buttonSpec)
1016    {
1017        if (buttonSpec->wmFunction == F_Menu)
1018        {
1019            if (buttonSpec->context & F_CONTEXT_WINDOW)
1020            {
1021                menuContext = F_CONTEXT_WINDOW;
1022            }
1023            else if (buttonSpec->context & F_CONTEXT_ICON)
1024            {
1025                menuContext = F_CONTEXT_ICON;
1026            }
1027            else
1028            {
1029                menuContext = F_CONTEXT_ROOT;
1030            }
1031
1032            menuSpec = MakeMenu (pSD, buttonSpec->wmFuncArgs, menuContext,
1033                                 buttonSpec->context,
1034                                 (MenuItem *) NULL, FALSE);
1035
1036            if (menuSpec)
1037            /*
1038             * If successful, save in pSD->acceleratorMenuSpecs
1039             * Note: these accelerators have nonzero contexts.
1040             */
1041            {
1042                SaveMenuAccelerators (pSD, menuSpec);
1043            }
1044            else
1045            {
1046                buttonSpec->wmFunction = F_Nop;
1047            }
1048        }
1049        buttonSpec = buttonSpec->nextButtonSpec;
1050    }
1051
1052
1053    /*
1054     * Scan through the key binding specifications making menus if the
1055     * f.menu function is invoked.
1056     */
1057
1058    keySpec = pSD->keySpecs;
1059    while (keySpec)
1060    {
1061        if (keySpec->wmFunction == F_Menu)
1062        {
1063            if (keySpec->context & F_CONTEXT_WINDOW)
1064            {
1065                menuContext = F_CONTEXT_WINDOW;
1066            }
1067            else if (keySpec->context & F_CONTEXT_ICON)
1068            {
1069                menuContext = F_CONTEXT_ICON;
1070            }
1071            else
1072            {
1073                menuContext = F_CONTEXT_ROOT;
1074            }
1075
1076            menuSpec = MakeMenu (pSD, keySpec->wmFuncArgs, menuContext,
1077                                 keySpec->context,
1078                                 (MenuItem *) NULL, FALSE);
1079
1080            if (menuSpec)
1081            /*
1082             * If successful, save in pSD->acceleratorMenuSpecs
1083             * Note: these accelerators have nonzero contexts.
1084             */
1085            {
1086                SaveMenuAccelerators (pSD, menuSpec);
1087            }
1088            else
1089            {
1090                keySpec->wmFunction = F_Nop;
1091            }
1092        }
1093        keySpec = keySpec->nextKeySpec;
1094    }
1095
1096
1097} /* END OF FUNCTION MakeWmFunctionResources */
1098
1099
1100
1101/*************************************<->*************************************
1102 *
1103 *  MakeXorGC (pSD)
1104 *
1105 *
1106 *  Description:
1107 *  -----------
1108 *  Make an XOR graphic context for resizing and moving
1109 *
1110 *
1111 *  Inputs:
1112 *  ------
1113 *  pSD = pointer to screen data
1114 *
1115 *  Outputs:
1116 *  -------
1117 *  Modifies global data
1118 *
1119 *  Comments:
1120 *  --------
1121 * 
1122 *
1123 *************************************<->***********************************/
1124
1125#ifdef _NO_PROTO
1126void MakeXorGC (pSD)
1127
1128    WmScreenData *pSD;
1129#else /* _NO_PROTO */
1130void MakeXorGC (WmScreenData *pSD)
1131#endif /* _NO_PROTO */
1132{
1133    XGCValues gcv;
1134    XtGCMask  mask;
1135
1136    mask = GCFunction | GCLineWidth | GCSubwindowMode | GCCapStyle;
1137    gcv.function = GXinvert;
1138    gcv.line_width = 0;
1139    gcv.cap_style = CapNotLast;
1140    gcv.subwindow_mode = IncludeInferiors;
1141
1142    /* Fix so that the rubberbanding for resize and move will
1143     *  have more contrasting colors.
1144     */
1145
1146    gcv.plane_mask = BlackPixelOfScreen( DefaultScreenOfDisplay( DISPLAY )) ^
1147                     WhitePixelOfScreen( DefaultScreenOfDisplay( DISPLAY ));
1148    mask = mask | GCPlaneMask;
1149
1150    pSD->xorGC = XCreateGC (DISPLAY, pSD->rootWindow, mask, &gcv);
1151
1152
1153} /* END OF FUNCTION MakeXorGC */
1154
1155
1156
1157/*************************************<->*************************************
1158 *
1159 *  CopyArgv (argc, argv)
1160 *
1161 *
1162 *  Description:
1163 *  -----------
1164 *  This function makes a copy of the window manager's argv for use by
1165 *  the f.restart function.  A copy must be kept because XtInitialize
1166 *  changes argv.
1167 *
1168 *
1169 *  Inputs:
1170 *  ------
1171 *  argc = the number of strings in argv
1172 *
1173 *  argv = window manager parameters
1174 *
1175 *
1176 *  Outputs:
1177 *  -------
1178 *  Return = a copy of argv
1179 *
1180 *************************************<->***********************************/
1181
1182
1183#ifdef _NO_PROTO
1184void CopyArgv (argc, argv)
1185    int argc;
1186    char *argv[];
1187
1188#else /* _NO_PROTO */
1189void CopyArgv (int argc, char *argv [])
1190#endif /* _NO_PROTO */
1191{
1192    int i;
1193
1194
1195    if ((wmGD.argv = (char **)XtMalloc ((argc + 1) * sizeof (char *))) == NULL)
1196    {
1197        Warning ("Insufficient memory for window manager data");
1198        wmGD.argv = argv;
1199    }
1200    else
1201    {
1202        for (i = 0; i < argc; i++)
1203        {
1204            wmGD.argv[i] = argv[i];
1205        }
1206        wmGD.argv[i] = NULL;
1207    }
1208   
1209} /* END OF FUNCTION CopyArgv */
1210
1211
1212/*************************************<->*************************************
1213 *
1214 *  InitScreenNames ()
1215 *
1216 *
1217 *  Description:
1218 *  -----------
1219 *  Initializes the name space for screen names
1220 *
1221 *  Outputs:
1222 *  -------
1223 *  Modifies global data
1224 *    + screenNames
1225 *
1226 *  Comments:
1227 *  --------
1228 *  Initializes screenNames to contain a numeric name for each screen
1229 *
1230 *************************************<->***********************************/
1231
1232#ifdef _NO_PROTO
1233void InitScreenNames ()
1234
1235#else /* _NO_PROTO */
1236void InitScreenNames (void)
1237#endif /* _NO_PROTO */
1238{
1239    int num, numScreens;
1240   
1241    numScreens = ScreenCount (wmGD.display);
1242   
1243    if (!(wmGD.screenNames =
1244          (unsigned char **) XtMalloc (numScreens * sizeof(char *))))
1245    {
1246        ShowWaitState (FALSE);
1247        Warning ("Insufficient memory for screen names");
1248        exit (WM_ERROR_EXIT_VALUE);
1249    }
1250   
1251    for (num=0; num<numScreens; num++)
1252    {
1253        if (!(wmGD.screenNames[num] =
1254              (unsigned char *) XtMalloc (4*sizeof(char))))
1255        {
1256            ShowWaitState (FALSE);
1257            Warning ("Insufficient memory for screen names");
1258            exit (WM_ERROR_EXIT_VALUE);
1259        }
1260        /* default name is left justified, 3-chars max, zero terminated */
1261        sprintf((char *)wmGD.screenNames[num],"%d",num%1000);
1262    }
1263}
1264
1265
1266
1267/******************************<->*************************************
1268 *
1269 *  InitWmDisplayEnv
1270 *
1271 *
1272 *  Description:
1273 *  -----------
1274 *  This function saves the display string for putenv in F_Exec.
1275 *
1276 *  Inputs:
1277 *  -------
1278 *
1279 *  Outputs:
1280 *  -------
1281 *************************************<->***********************************/
1282
1283#ifdef _NO_PROTO
1284void
1285InitWmDisplayEnv ()
1286#else /* _NO_PROTO */
1287void
1288InitWmDisplayEnv (void)
1289#endif /* _NO_PROTO */
1290{
1291    char *pDisplayName;
1292    char buffer[256];
1293    char displayName[256];
1294
1295    pDisplayName = DisplayString (DISPLAY);
1296   
1297    /*
1298     * Construct displayString for this string. 
1299     */
1300    strcpy(displayName, pDisplayName);
1301    sprintf(buffer, "DISPLAY=%s",displayName);
1302   
1303    /*         
1304     * Allocate space for the display string
1305     */
1306    if ((wmGD.displayString =
1307         (String)XtMalloc ((unsigned int) (strlen(buffer) + 1))) == NULL)
1308    {
1309        wmGD.displayString = NULL;
1310        Warning ("Insufficient memory for displayString");
1311    }
1312    else
1313    {
1314        strcpy(wmGD.displayString, buffer);
1315    }
1316   
1317} /* END OF FUNCTION  InitWmDisplayEnv */
Note: See TracBrowser for help on using the repository browser.