chiark / gitweb /
debian/changelog: start -4~
[vtwm.git] / twm.c
1 /*****************************************************************************/
2 /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
3 /**                          Salt Lake City, Utah                           **/
4 /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
5 /**                        Cambridge, Massachusetts                         **/
6 /**                                                                         **/
7 /**                           All Rights Reserved                           **/
8 /**                                                                         **/
9 /**    Permission to use, copy, modify, and distribute this software and    **/
10 /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
11 /**    granted, provided that the above copyright notice appear  in  all    **/
12 /**    copies and that both  that  copyright  notice  and  this  permis-    **/
13 /**    sion  notice appear in supporting  documentation,  and  that  the    **/
14 /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
15 /**    in publicity pertaining to distribution of the  software  without    **/
16 /**    specific, written prior permission.                                  **/
17 /**                                                                         **/
18 /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
19 /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
20 /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
21 /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
22 /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
23 /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
24 /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
25 /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
26 /*****************************************************************************/
27
28
29 /***********************************************************************
30  *
31  * $XConsortium: twm.c,v 1.124 91/05/08 11:01:54 dave Exp $
32  *
33  * twm - "Tom's Window Manager"
34  *
35  * 27-Oct-87 Thomas E. LaStrange        File created
36  * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
37  ***********************************************************************/
38
39 #include <sys/stat.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h> /* for sleep() */
43 #include <signal.h>
44 #include <fcntl.h>
45 #include "twm.h"
46 #include "add_window.h"
47 #include "gc.h"
48 #include "parse.h"
49 #include "version.h"
50 #include "menus.h"
51 #include "events.h"
52 #include "util.h"
53 #include "gram.h"
54 #include "screen.h"
55 #include "iconmgr.h"
56 #include "desktop.h"
57 /* djhjr - 6/22/01 */
58 #ifndef NO_SOUND_SUPPORT
59 #include "sound.h"
60 #endif
61 #include <X11/Xresource.h>
62 #include <X11/Xproto.h>
63 #include <X11/Xatom.h>
64 #include <X11/Xmu/Error.h>
65 /* djhjr - 9/14/03 */
66 #ifndef NO_I18N_SUPPORT
67 #include <X11/Xlocale.h>
68 #endif
69
70 Display *dpy;                   /* which display are we talking to */
71 Window ResizeWindow;            /* the window we are resizing */
72
73 int MultiScreen = TRUE;         /* try for more than one screen? */
74 int NumScreens;                 /* number of screens in ScreenList */
75 int HasShape;                   /* server supports shape extension? */
76 int ShapeEventBase, ShapeErrorBase;
77 ScreenInfo **ScreenList;        /* structures for each screen */
78 ScreenInfo *Scr = NULL;         /* the cur and prev screens */
79 int PreviousScreen;             /* last screen that we were on */
80 int FirstScreen;                /* TRUE ==> first screen of display */
81 Bool PrintPID = False;          /* controls PID file - djhjr - 12/2/01 */
82 Bool PrintErrorMessages = False;        /* controls error messages */
83 static int RedirectError;       /* TRUE ==> another window manager running */
84 static int CatchRedirectError();        /* for settting RedirectError */
85 static int TwmErrorHandler();   /* for everything else */
86 void InitVariables();
87 void InternUsefulAtoms();
88
89 char Info[INFO_LINES][INFO_SIZE];               /* info strings to print */
90 int InfoLines;
91
92 char *InitFile = NULL;
93 int parseInitFile = TRUE;       /* djhjr - 10/7/02 */
94
95 Cursor UpperLeftCursor;         /* upper Left corner cursor */
96 Cursor RightButt;
97 Cursor MiddleButt;
98 Cursor LeftButt;
99
100 XContext TwmContext;            /* context for twm windows */
101 XContext MenuContext;           /* context for all menu windows */
102 XContext IconManagerContext;    /* context for all window list windows */
103 XContext VirtualContext;        /* context for all desktop display windows */
104 XContext ScreenContext;         /* context to get screen data */
105 XContext ColormapContext;       /* context for colormap operations */
106 XContext DoorContext;           /* context for doors */
107
108 XClassHint NoClass;             /* for applications with no class */
109
110 XGCValues Gcv;
111
112 char *Home;                     /* the HOME environment variable */
113 int HomeLen;                    /* length of Home */
114 int ParseError;                 /* error parsing the .twmrc file */
115
116 int HandlingEvents = FALSE;     /* are we handling events yet? */
117
118 Window JunkRoot;                /* junk window */
119 Window JunkChild;               /* junk window */
120 int JunkX;                      /* junk variable */
121 int JunkY;                      /* junk variable */
122 unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;
123
124 char *ProgramName, *PidName = "vtwm.pid"; /* PID file - djhjr - 12/2/01 */
125 int Argc;
126 char **Argv;
127 char **Environ;
128
129 Bool RestartPreviousState = False;      /* try to restart in previous state */
130
131 unsigned long black, white;
132
133 /* djhjr - 9/14/03 */
134 #ifndef NO_I18N_SUPPORT
135 Bool use_fontset;
136 #endif
137
138 extern void assign_var_savecolor();
139
140 /* djhjr - 4/26/99 */
141 extern void FreeRegions();
142
143 /***********************************************************************
144  *
145  *  Procedure:
146  *      main - start of twm
147  *
148  ***********************************************************************
149  */
150
151 /* Changes for m4 pre-processing submitted by Jason Gloudon */
152 int
153 main(argc, argv, environ)
154     int argc;
155     char **argv;
156     char **environ;
157 {
158     Window root, parent, *children;
159     unsigned int nchildren;
160     int i, j;
161     char *def, *display_name = NULL;
162     unsigned long valuemask;    /* mask for create windows */
163     XSetWindowAttributes attributes;    /* attributes for create windows */
164     int numManaged, firstscrn, lastscrn, scrnum;
165     extern ColormapWindow *CreateColormapWindow();
166 #ifndef NO_M4_SUPPORT
167     int m4_preprocess = False;  /* filter the *twmrc file through m4 */
168     char *m4_option = NULL; /* pass these options to m4 - djhjr - 2/20/98 */
169 #endif
170 /* djhjr - 6/22/01 */
171 #ifndef NO_SOUND_SUPPORT
172     int sound_state = 0;
173 #endif
174     extern char *defTwmrc[];    /* djhjr - 10/7/02 */
175 /* djhjr - 9/14/03 */
176 #ifndef NO_I18N_SUPPORT
177     char *loc;
178 #endif
179
180     /* djhjr - 7/21/98 */
181     SIGNAL_T QueueRestartVtwm();
182     
183         if ((ProgramName = strrchr(argv[0], '/')))
184                 ProgramName++;
185         else
186                 ProgramName = argv[0];
187     Argc = argc;
188     Argv = argv;
189     Environ = environ;
190
191     for (i = 1; i < argc; i++) {
192         if (argv[i][0] == '-') {
193             switch (argv[i][1]) {
194               case 'd':                         /* -display display */
195                 if (++i >= argc) goto usage;
196                 display_name = argv[i];
197                 continue;
198               case 'f':                         /* -file [initfile] */
199                 /* this isn't really right, but hey... - djhjr - 10/7/02 */
200                 if (i + 1 < argc &&
201                                 (argv[i + 1][0] != '-' ||
202                                 (argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1]))))
203                         InitFile = argv[++i];
204                 else
205                         parseInitFile = FALSE;
206                 continue;
207 #ifndef NO_M4_SUPPORT
208               case 'm':                         /* -m4 [options] */
209                 m4_preprocess = True;
210                 /* this isn't really right, but hey... - djhjr - 2/20/98 */
211                 if (i + 1 < argc &&
212                                 (argv[i + 1][0] != '-' ||
213                                 (argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1]))))
214                         m4_option = argv[++i];
215                 continue;
216 #endif
217               case 'p':                         /* -pidfile - djhjr - 12/2/01 */
218                 PrintPID = True;
219                 continue;
220               case 's':                         /* -single */
221                 MultiScreen = FALSE;
222                 continue;
223               case 'v':                         /* -verbose */
224                 PrintErrorMessages = True;
225                 continue;
226 #ifdef NEVER /* djhjr - 2/20/99 */
227               case 'q':                         /* -quiet */
228                 PrintErrorMessages = False;
229                 continue;
230 #endif
231             }
232         }
233       usage:
234         fprintf (stderr,
235 #ifndef NO_M4_SUPPORT
236                  "usage:  %s [-d display] [-f [initfile]] [-m [options]] [-p] [-s] [-v]\n",
237 #else
238                  "usage:  %s [-d display] [-f [initfile]] [-p] [-s] [-v]\n",
239 #endif
240                  ProgramName);
241         exit (1);
242     }
243
244 /* djhjr - 9/14/03 */
245 #ifndef NO_I18N_SUPPORT
246     loc = setlocale(LC_ALL, "");
247     if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") ||
248                 !XSupportsLocale())
249         use_fontset = False;
250     else
251         use_fontset = True;
252
253     if (PrintErrorMessages)
254         fprintf(stderr, "%s: I18N supported, L10N %sabled\n",
255                 ProgramName, (use_fontset) ? "en" : "dis");
256 #endif
257
258 /* djhjr - 6/22/01 */
259 #ifndef NO_SOUND_SUPPORT
260 #define sounddonehandler(sig) \
261     if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, PlaySoundDone)
262 #else
263 #define sounddonehandler(sig) \
264     if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
265 #endif
266 #define donehandler(sig) \
267     if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
268
269     sounddonehandler (SIGINT);
270     sounddonehandler (SIGHUP);
271     sounddonehandler (SIGQUIT);
272     sounddonehandler (SIGTERM);
273
274     /* djhjr - 12/2/01 */
275     donehandler (SIGABRT);
276     donehandler (SIGFPE);
277     donehandler (SIGSEGV);
278     donehandler (SIGILL);
279     donehandler (SIGTSTP);
280     donehandler (SIGPIPE);
281 #undef sounddonehandler
282 #undef donehandler
283
284     /* djhjr - 7/31/98 */
285     signal (SIGUSR1, QueueRestartVtwm);
286
287     Home = getenv("HOME");
288     if (Home == NULL)
289         Home = "./";
290
291     HomeLen = strlen(Home);
292
293     NoClass.res_name = NoName;
294     NoClass.res_class = NoName;
295
296     if (!(dpy = XOpenDisplay(display_name))) {
297         fprintf (stderr, "%s:  unable to open display \"%s\"\n",
298                  ProgramName, XDisplayName(display_name));
299         exit (1);
300     }
301
302     if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) {
303         fprintf (stderr,
304                  "%s:  unable to mark display connection as close-on-exec\n",
305                  ProgramName);
306         exit (1);
307     }
308
309     HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase);
310     TwmContext = XUniqueContext();
311     MenuContext = XUniqueContext();
312     IconManagerContext = XUniqueContext();
313     VirtualContext = XUniqueContext();
314     ScreenContext = XUniqueContext();
315     ColormapContext = XUniqueContext();
316     DoorContext = XUniqueContext();
317
318     InternUsefulAtoms ();
319
320
321     /* Set up the per-screen global information. */
322
323     NumScreens = ScreenCount(dpy);
324
325     if (MultiScreen)
326     {
327         firstscrn = 0;
328         lastscrn = NumScreens - 1;
329     }
330     else
331     {
332         firstscrn = lastscrn = DefaultScreen(dpy);
333     }
334
335     InfoLines = 0;
336
337     /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */
338     ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *));
339     if (ScreenList == NULL)
340     {
341         fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
342                  ProgramName);
343         exit (1);
344     }
345     numManaged = 0;
346     PreviousScreen = DefaultScreen(dpy);
347     FirstScreen = TRUE;
348     for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++)
349     {
350         /* Make sure property priority colors is empty */
351         XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS,
352                          XA_CARDINAL, 32, PropModeReplace, NULL, 0);
353         RedirectError = FALSE;
354         XSetErrorHandler(CatchRedirectError);
355         XSelectInput(dpy, RootWindow (dpy, scrnum),
356             ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
357             SubstructureRedirectMask | KeyPressMask |
358             ButtonPressMask | ButtonReleaseMask);
359         XSync(dpy, 0);
360         XSetErrorHandler(TwmErrorHandler);
361
362         if (RedirectError)
363         {
364             fprintf (stderr, "%s:  another window manager is already running",
365                      ProgramName);
366             if (MultiScreen && NumScreens > 0)
367                 fprintf(stderr, " on screen %d?\n", scrnum);
368             else
369                 fprintf(stderr, "?\n");
370             continue;
371         }
372
373         numManaged ++;
374
375         /* Note:  ScreenInfo struct is calloc'ed to initialize to zero. */
376         Scr = ScreenList[scrnum] =
377             (ScreenInfo *) calloc(1, sizeof(ScreenInfo));
378         if (Scr == NULL)
379         {
380             fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n",
381                      ProgramName, scrnum);
382             continue;
383         }
384
385         /* initialize list pointers, remember to put an initialization
386          * in InitVariables also
387          */
388         Scr->BorderColorL = NULL;
389         Scr->IconBorderColorL = NULL;
390         Scr->BorderTileForegroundL = NULL;
391         Scr->BorderTileBackgroundL = NULL;
392         Scr->TitleForegroundL = NULL;
393         Scr->TitleBackgroundL = NULL;
394         Scr->IconForegroundL = NULL;
395         Scr->IconBackgroundL = NULL;
396         Scr->NoTitle = NULL;
397         Scr->MakeTitle = NULL;
398         Scr->AutoRaise = NULL;
399         Scr->IconNames = NULL;
400         Scr->NoHighlight = NULL;
401         Scr->NoStackModeL = NULL;
402         Scr->NoTitleHighlight = NULL;
403         Scr->DontIconify = NULL;
404         Scr->IconMgrNoShow = NULL;
405         Scr->IconMgrShow = NULL;
406         Scr->IconifyByUn = NULL;
407         Scr->IconManagerFL = NULL;
408         Scr->IconManagerBL = NULL;
409         Scr->IconMgrs = NULL;
410         Scr->StartIconified = NULL;
411         Scr->SqueezeTitleL = NULL;
412         Scr->DontSqueezeTitleL = NULL;
413         Scr->WindowRingL = NULL;
414
415         /* submitted by Jonathan Paisley - 10/27/02 */
416         Scr->NoWindowRingL = NULL;
417
418         Scr->WarpCursorL = NULL;
419
420         /* djhjr - 4/22/96 */
421         Scr->ImageCache = NULL;
422
423         /* djhjr - 4/7/98 */
424         Scr->OpaqueMoveL = NULL;
425         Scr->NoOpaqueMoveL = NULL;
426         Scr->OpaqueResizeL = NULL;
427         Scr->NoOpaqueResizeL = NULL;
428
429         /* djhjr - 5/2/98 */
430         Scr->NoBorder = NULL;
431
432         /* djhjr - 9/24/02 */
433         Scr->UsePPositionL = NULL;
434
435         /* remember to put an initialization in InitVariables also
436          */
437
438         Scr->screen = scrnum;
439         Scr->d_depth = DefaultDepth(dpy, scrnum);
440         Scr->d_visual = DefaultVisual(dpy, scrnum);
441         Scr->Root = RootWindow(dpy, scrnum);
442         XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr);
443
444         /* djhjr - 1/31/99 */
445         if ((def = XGetDefault(dpy, "*", "bitmapFilePath")))
446                 Scr->BitmapFilePath = strdup(def);
447         else
448                 Scr->BitmapFilePath = NULL;
449
450         Scr->TwmRoot.cmaps.number_cwins = 1;
451         Scr->TwmRoot.cmaps.cwins =
452                 (ColormapWindow **) malloc(sizeof(ColormapWindow *));
453         Scr->TwmRoot.cmaps.cwins[0] =
454                 CreateColormapWindow(Scr->Root, True, False);
455         Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured;
456
457         Scr->cmapInfo.cmaps = NULL;
458         Scr->cmapInfo.maxCmaps =
459                 MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen));
460         Scr->cmapInfo.root_pushes = 0;
461         InstallWindowColormaps(0, &Scr->TwmRoot);
462
463         Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail =
464           Scr->StdCmapInfo.mru = NULL;
465         Scr->StdCmapInfo.mruindex = 0;
466         LocateStandardColormaps();
467
468         Scr->TBInfo.nleft = Scr->TBInfo.nright = 0;
469         Scr->TBInfo.head = NULL;
470
471 /* djhjr - 4/19/96
472         Scr->TBInfo.border = 1;
473 */
474         Scr->TBInfo.border = -100;
475
476         Scr->TBInfo.width = 0;
477         Scr->TBInfo.leftx = 0;
478         Scr->TBInfo.titlex = 0;
479
480         Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum);
481         Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum);
482         Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth;
483         Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight;
484
485         Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;
486
487         if (DisplayCells(dpy, scrnum) < 3)
488             Scr->Monochrome = MONOCHROME;
489         else
490             Scr->Monochrome = COLOR;
491
492         /* setup default colors */
493         Scr->FirstTime = TRUE;
494         GetColor(Scr->Monochrome, &black, "black");
495         Scr->Black = black;
496         GetColor(Scr->Monochrome, &white, "white");
497         Scr->White = white;
498
499         if (FirstScreen)
500         {
501             SetFocus ((TwmWindow *)NULL, CurrentTime);
502
503             /* define cursors */
504
505             NewFontCursor(&UpperLeftCursor, "top_left_corner");
506             NewFontCursor(&RightButt, "rightbutton");
507             NewFontCursor(&LeftButt, "leftbutton");
508             NewFontCursor(&MiddleButt, "middlebutton");
509         }
510
511         Scr->iconmgr.x = 0;
512         Scr->iconmgr.y = 0;
513         Scr->iconmgr.width = 150;
514         Scr->iconmgr.height = 5;
515         Scr->iconmgr.next = NULL;
516         Scr->iconmgr.prev = NULL;
517         Scr->iconmgr.lasti = &(Scr->iconmgr);
518         Scr->iconmgr.first = NULL;
519         Scr->iconmgr.last = NULL;
520         Scr->iconmgr.active = NULL;
521         Scr->iconmgr.scr = Scr;
522         Scr->iconmgr.columns = 1;
523         Scr->iconmgr.count = 0;
524         Scr->iconmgr.name = "VTWM";
525         Scr->iconmgr.icon_name = "Icons";
526
527         Scr->IconDirectory = NULL;
528
529         /* djhjr - 10/30/02 */
530         Scr->hiliteName = NULL;
531         Scr->menuIconName = TBPM_MENU;
532         Scr->iconMgrIconName = TBPM_XLOGO;
533
534 /* djhjr - 10/30/02
535         Scr->siconifyPm = NULL;
536         Scr->pullPm = NULL;
537 */
538
539 /* djhjr - 5/17/98 */
540 #ifdef ORIGINAL_PIXMAPS
541         Scr->hilitePm = None;
542         Scr->virtualPm = None; /* RFB PIXMAP */
543         Scr->RealScreenPm = None; /* RFB PIXMAP */
544 #else /* ORIGINAL_PIXMAPS */
545         /* djhjr - 10/25/02 */
546         Scr->hiliteName = NULL;
547
548         Scr->hilitePm = NULL;
549         Scr->virtualPm = NULL;
550         Scr->realscreenPm = NULL;
551 #endif /* ORIGINAL_PIXMAPS */
552
553         if ( Scr->FirstTime )
554         {       /* retain max size on restart. */
555                 Scr->VirtualDesktopMaxWidth = 0;
556                 Scr->VirtualDesktopMaxHeight = 0;
557         }
558
559         InitVariables();
560         InitMenus();
561
562         /* added this 'if (...) else' - djhjr - 10/7/02 */
563         if (!parseInitFile)
564                 ParseStringList(defTwmrc);
565         else
566         {
567                 /* Parse it once for each screen. */
568 #ifndef NO_M4_SUPPORT
569                 /* added 'm4_option' - djhjr - 2/20/99 */
570                 ParseTwmrc(InitFile, display_name, m4_preprocess, m4_option);
571 #else
572                 ParseTwmrc(InitFile);
573 #endif
574         }
575
576 /* djhjr - 6/22/01 */
577 #ifndef NO_SOUND_SUPPORT
578         OpenSound();
579
580         if (PlaySound(S_START))
581         {
582                 /*
583                  * Save setting from resource file, and turn sound off
584                  */
585                 sound_state = ToggleSounds();
586                 sound_state ^= 1;
587                 if (sound_state == 0) ToggleSounds();
588         }
589 #endif
590
591         assign_var_savecolor(); /* storeing pixels for twmrc "entities" */
592
593 /* djhjr - 10/17/02 */
594 #if 0
595         /* djhjr - 4/19/96 */
596         /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
597         if (Scr->TitleBevelWidth > 0) {
598 /* djhjr - 10/17/02
599             if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 0;
600 */
601
602 /* djhjr - 3/12/97
603             if (Scr->ButtonIndent  == -100) Scr->ButtonIndent  = 0;
604             if (Scr->FramePadding  == -100) Scr->FramePadding  = 0;
605             if (Scr->TitlePadding  == -100) Scr->TitlePadding  = 0;
606 */
607             Scr->ButtonIndent  = 0;
608             Scr->FramePadding  = 0;
609             Scr->TitlePadding  = 0;
610
611 /* djhjr - 4/3/98
612                 * djhjr - 4/26/96 *
613                 if (Scr->SunkFocusWindowTitle) Scr->TitleHighlight = FALSE;
614 */
615         }
616         else {
617                 /* djhjr - 4/5/98 */
618                 Scr->SunkFocusWindowTitle = FALSE;
619         }
620 #endif
621
622         /* was only if Scr->TitleBevelWidth == 0 - djhjr - 10/17/02 */
623         if (Scr->FramePadding  == -100) Scr->FramePadding  = 2; /* values that look */
624         if (Scr->TitlePadding  == -100) Scr->TitlePadding  = 8; /* "nice" on */
625         if (Scr->ButtonIndent  == -100) Scr->ButtonIndent  = 1; /* 75 and 100dpi displays */
626         if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 1;
627
628         /* was 'Scr->use3D*' - djhjr - 8/11/98 */
629         /* rem'd 'Scr->*BevelWidth > 0' - djhjr - 10/30/02 */
630         if (/*Scr->TitleBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->TitleC);
631         if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuC);
632         if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuTitleC);
633         if (Scr->BorderBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->BorderColorC);
634
635         /* djhjr - 2/7/99 */
636         if (Scr->DoorBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->DoorC);
637         if (Scr->VirtualDesktopBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->VirtualC);
638
639 /* djhjr - 8/11/98
640         * was 'Scr->use3Dborders' - djhjr - 8/11/98 *
641         if (Scr->BorderBevelWidth == 0)
642                 Scr->ThreeDBorderWidth = 0;
643         else
644 */
645         {
646 /* djhjr - 8/11/98
647                 * djhjr - 4/29/98 *
648                 if (2 * Scr->BorderBevelWidth > Scr->ThreeDBorderWidth)
649                         Scr->ThreeDBorderWidth = 2 * Scr->BorderBevelWidth;
650 */
651                 if (2 * Scr->BorderBevelWidth > Scr->BorderWidth)
652                         Scr->BorderWidth = 2 * Scr->BorderBevelWidth;
653
654         if (!Scr->BeNiceToColormap)
655                         GetShadeColors(&Scr->DefaultC);
656         }
657
658         /* djhjr - 5/5/98 */
659         /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */
660         if (Scr->IconBevelWidth > 0)
661                 Scr->IconBorderWidth = 0;
662
663         if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE;
664         if (!Scr->HaveFonts) CreateFonts();
665         CreateGCs();
666         MakeMenus();
667
668 /* djhjr - 10/18/02 */
669 #if 0
670         /*
671          * Set titlebar height from font height and padding,
672          * then adjust to titlebutton height - djhjr - 12/10/98
673          */
674         Scr->TitleBarFont.y += Scr->FramePadding;
675         i = Scr->TitleBarFont.height;
676         do
677         {
678                 Scr->TitleBarFont.y += (i - Scr->TitleBarFont.height) / 2;
679                 Scr->TitleHeight = i + Scr->FramePadding * 2;
680
681 /* djhjr - 4/29/98
682                 * djhjr - 4/19/96 *
683                 if (Scr->use3Dtitles) Scr->TitleHeight += 4;
684 */
685 /* djhjr - 10/18/02
686                 * was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
687                 if (Scr->TitleBevelWidth > 0)
688                         Scr->TitleHeight += 2 * Scr->TitleBevelWidth + 2;
689 */
690
691                 /* make title height be odd so buttons look nice and centered */
692                 if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
693         } while ((i = InitTitlebarButtons()) > Scr->TitleHeight - Scr->FramePadding * 2);
694 #else
695         /* set titlebar height to font height plus frame padding */
696         Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
697         if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
698
699         i = InitTitlebarButtons();      /* returns the button height */
700         
701         /* adjust titlebar height to button height */
702         if (i > Scr->TitleHeight) Scr->TitleHeight = i + Scr->FramePadding * 2;
703         if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
704
705         /* adjust font baseline */
706         Scr->TitleBarFont.y += ((Scr->TitleHeight - Scr->TitleBarFont.height) / 2);
707 #endif
708
709         XGrabServer(dpy);
710         XSync(dpy, 0);
711
712         JunkX = 0;
713         JunkY = 0;
714
715         XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren);
716         CreateIconManagers();
717         if (!Scr->NoIconManagers)
718             Scr->iconmgr.twm_win->icon = TRUE;
719
720         if (Scr->VirtualDesktopWidth > 0)
721                 CreateDesktopDisplay();
722
723         /* create all of the door windows */
724         door_open_all();
725
726         /*
727          * weed out icon windows
728          */
729         for (i = 0; i < nchildren; i++) {
730             if (children[i]) {
731                 XWMHints *wmhintsp = XGetWMHints (dpy, children[i]);
732
733                 if (wmhintsp) {
734                     if (wmhintsp->flags & IconWindowHint) {
735                         for (j = 0; j < nchildren; j++) {
736                             if (children[j] == wmhintsp->icon_window) {
737                                 children[j] = None;
738                                 break;
739                             }
740                         }
741                     }
742                     XFree ((char *) wmhintsp);
743                 }
744             }
745         }
746
747         /*
748          * map all of the non-override windows
749          */
750         for (i = 0; i < nchildren; i++)
751         {
752             if (children[i] && MappedNotOverride(children[i]))
753             {
754                 XUnmapWindow(dpy, children[i]);
755                 SimulateMapRequest(children[i]);
756             }
757         }
758
759         if (Scr->ShowIconManager && !Scr->NoIconManagers)
760         {
761             Scr->iconmgr.twm_win->icon = FALSE;
762             if (Scr->iconmgr.count)
763             {
764                 SetMapStateProp (Scr->iconmgr.twm_win, NormalState);
765                 XMapWindow(dpy, Scr->iconmgr.w);
766                 XMapWindow(dpy, Scr->iconmgr.twm_win->frame);
767             }
768         }
769
770         /* djhjr - 5/9/96 */
771         /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
772         if (!Scr->BorderBevelWidth > 0)
773                 attributes.border_pixel = Scr->DefaultC.fore;
774
775         attributes.background_pixel = Scr->DefaultC.back;
776         attributes.event_mask = (ExposureMask | ButtonPressMask |
777                                  KeyPressMask | ButtonReleaseMask);
778         attributes.backing_store = NotUseful;
779
780 #ifdef ORIGINAL_INFOCURSOR
781         attributes.cursor = XCreateFontCursor (dpy, Scr->WaitCursor);
782
783         /* djhjr - 5/9/96 */
784         /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
785         if (!Scr->BorderBevelWidth > 0)
786                 valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
787                              CWBackingStore | CWCursor);
788         else
789                 valuemask = (CWBackPixel | CWEventMask | CWBackingStore | CWCursor);
790 #else
791
792         /* djhjr - 5/9/96 */
793         /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
794         if (!Scr->BorderBevelWidth > 0)
795                 valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
796                              CWBackingStore);
797         else
798                 valuemask = (CWBackPixel | CWEventMask | CWBackingStore);
799 #endif
800
801         Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
802                                          (unsigned int) 5, (unsigned int) 5,
803
804                                          /* djhjr - 5/9/96 */
805                                          /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
806                                          (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0,
807
808                                          (unsigned int) CopyFromParent,
809                                          (Visual *) CopyFromParent,
810                                          valuemask, &attributes);
811
812 /* djhjr - 9/14/03 */
813 #ifndef NO_I18N_SUPPORT
814         Scr->SizeStringWidth = MyFont_TextWidth (&Scr->SizeFont,
815 #else
816         Scr->SizeStringWidth = XTextWidth (Scr->SizeFont.font,
817 #endif
818 /* djhjr - 5/9/96
819                                            " 8888 x 8888 ", 13);
820 */
821 /* djhjr - 4/29/98
822                                            "nnnnnnnnnnnnn", 13);
823 */
824                                            /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
825                                            "nnnnnnnnnnnnn", 13) + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0);
826
827         /* djhjr - 5/9/96 */
828         /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
829         if (!Scr->InfoBevelWidth > 0)
830                 valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
831         else
832                 valuemask = (CWBackPixel | CWBitGravity);
833
834         /* djhjr - 5/15/96 */
835         switch (Scr->ResizeX)
836         {
837                 case R_NORTHWEST:
838                         Scr->ResizeX = 20;
839                         Scr->ResizeY = 20;
840                         break;
841                 case R_NORTHEAST:
842                         Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20;
843                         Scr->ResizeY = 20;
844                         break;
845                 case R_SOUTHWEST:
846                         Scr->ResizeX = 20;
847                         Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20;
848                         break;
849                 case R_SOUTHEAST:
850                         Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20;
851                         Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20;
852                         break;
853                 case R_CENTERED:
854                         Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) / 2;
855                         Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) / 2;
856                         break;
857         }
858
859         attributes.bit_gravity = NorthWestGravity;
860         Scr->SizeWindow = XCreateWindow (dpy, Scr->Root,
861
862 /* djhjr - 5/15/96
863                                          0,0,
864 */
865                                          Scr->ResizeX, Scr->ResizeY,
866
867                                          (unsigned int) Scr->SizeStringWidth,
868
869 /* djhjr - 4/29/98
870                                          (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2),
871 */
872                                          /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
873                                          (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) +
874                                                 ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0),
875
876                                          /* djhjr - 5/9/96 */
877                                          /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
878                                          (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0,
879
880                                          (unsigned int) CopyFromParent,
881                                          (Visual *) CopyFromParent,
882                                          valuemask, &attributes);
883
884         XUngrabServer(dpy);
885
886         FirstScreen = FALSE;
887         Scr->FirstTime = FALSE;
888     } /* for */
889
890     if (numManaged == 0) {
891         if (MultiScreen && NumScreens > 0)
892           fprintf (stderr, "%s:  unable to find any unmanaged screens\n",
893                    ProgramName);
894         exit (1);
895         
896     }
897
898     RestartPreviousState = False;
899     HandlingEvents = TRUE;
900
901         RaiseStickyAbove(); /* DSE */    
902     RaiseAutoPan(); /* autopan windows should have been raised
903                        after [re]starting vtwm -- DSE */
904
905     InitEvents();
906
907         /* profile function stuff by DSE */
908 #define VTWM_PROFILE "VTWM Profile"
909         if (FindMenuRoot (VTWM_PROFILE)) {
910                 ExecuteFunction (F_FUNCTION, VTWM_PROFILE, Event.xany.window,
911                         &Scr->TwmRoot, &Event, C_NO_CONTEXT, FALSE);
912         }
913
914 /* djhjr - 6/22/01 */
915 #ifndef NO_SOUND_SUPPORT
916         /* restore setting from resource file */
917         if (sound_state == 1) ToggleSounds();
918 #endif
919
920     
921     /* write out a PID file - djhjr - 12/2/01 */
922     if (PrintPID)
923     {
924         int fd, err = 0;
925         char buf[10], *fn = malloc(HomeLen + strlen(PidName) + 2);
926
927         /* removed group and other permissions - djhjr - 10/20/02 */
928         sprintf(fn, "%s/%s", Home, PidName);
929         if ((fd = open(fn,
930                 O_WRONLY|O_EXCL|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) != -1)
931         {
932             sprintf(buf, "%d\n", getpid());
933             err = write(fd, buf, strlen(buf));
934             close(fd);
935         }
936
937         if (fd == -1 || err == -1)
938         {
939             fprintf(stderr, "%s: cannot write to %s\n", ProgramName, fn);
940             DoAudible();
941         }
942
943         free(fn);
944     }
945
946     HandleEvents();
947
948         return (0);
949 }
950
951 /***********************************************************************
952  *
953  *  Procedure:
954  *      InitVariables - initialize twm variables
955  *
956  ***********************************************************************
957  */
958
959 void InitVariables()
960 {
961     FreeList(&Scr->BorderColorL);
962     FreeList(&Scr->IconBorderColorL);
963     FreeList(&Scr->BorderTileForegroundL);
964     FreeList(&Scr->BorderTileBackgroundL);
965     FreeList(&Scr->TitleForegroundL);
966     FreeList(&Scr->TitleBackgroundL);
967     FreeList(&Scr->IconForegroundL);
968     FreeList(&Scr->IconBackgroundL);
969     FreeList(&Scr->IconManagerFL);
970     FreeList(&Scr->IconManagerBL);
971     FreeList(&Scr->IconMgrs);
972     FreeList(&Scr->NoTitle);
973     FreeList(&Scr->MakeTitle);
974     FreeList(&Scr->AutoRaise);
975     FreeList(&Scr->IconNames);
976     FreeList(&Scr->NoHighlight);
977     FreeList(&Scr->NoStackModeL);
978     FreeList(&Scr->NoTitleHighlight);
979     FreeList(&Scr->DontIconify);
980     FreeList(&Scr->IconMgrNoShow);
981     FreeList(&Scr->IconMgrShow);
982     FreeList(&Scr->IconifyByUn);
983     FreeList(&Scr->StartIconified);
984     FreeList(&Scr->IconManagerHighlightL);
985     FreeList(&Scr->SqueezeTitleL);
986     FreeList(&Scr->DontSqueezeTitleL);
987     FreeList(&Scr->WindowRingL);
988
989     /* submitted by Jonathan Paisley - 10/27/02 */
990     FreeList(&Scr->NoWindowRingL);
991
992     FreeList(&Scr->WarpCursorL);
993     FreeList(&Scr->NailedDown);
994     FreeList(&Scr->VirtualDesktopColorFL);
995     FreeList(&Scr->VirtualDesktopColorBL);
996     FreeList(&Scr->VirtualDesktopColorBoL);
997     FreeList(&Scr->DontShowInDisplay);
998
999         /* Submitted by Erik Agsjo <erik.agsjo@aktiedirekt.com> */
1000     FreeList(&Scr->DontShowInTWMWindows);
1001
1002     FreeList(&Scr->DoorForegroundL);
1003     FreeList(&Scr->DoorBackgroundL);
1004
1005         /* djhjr - 4/22/96 */
1006         FreeList(&Scr->ImageCache);
1007
1008         /* djhjr - 4/7/98 */
1009         FreeList(&Scr->OpaqueMoveL);
1010         FreeList(&Scr->NoOpaqueMoveL);
1011         FreeList(&Scr->OpaqueResizeL);
1012         FreeList(&Scr->NoOpaqueResizeL);
1013
1014         /* djhjr - 5/2/98 */
1015         FreeList(&Scr->NoBorder);
1016
1017         /* djhjr - 9/24/02 */
1018         FreeList(&Scr->UsePPositionL);
1019
1020     NewFontCursor(&Scr->FrameCursor, "top_left_arrow");
1021     NewFontCursor(&Scr->TitleCursor, "top_left_arrow");
1022     NewFontCursor(&Scr->IconCursor, "top_left_arrow");
1023     NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow");
1024     NewFontCursor(&Scr->MoveCursor, "fleur");
1025     NewFontCursor(&Scr->ResizeCursor, "fleur");
1026     NewFontCursor(&Scr->MenuCursor, "sb_left_arrow");
1027     NewFontCursor(&Scr->ButtonCursor, "hand2");
1028     NewFontCursor(&Scr->WaitCursor, "watch");
1029     NewFontCursor(&Scr->SelectCursor, "dot");
1030     NewFontCursor(&Scr->DestroyCursor, "pirate");
1031     NewFontCursor(&Scr->DoorCursor, "exchange");/*RFBCURSOR*/
1032     NewFontCursor(&Scr->VirtualCursor, "rtl_logo");/*RFBCURSOR*/
1033     NewFontCursor(&Scr->DesktopCursor, "dotbox");/*RFBCURSOR*/
1034     Scr->NoCursor = NoCursor();
1035
1036     Scr->Ring = NULL;
1037     Scr->RingLeader = NULL;
1038
1039     Scr->DefaultC.fore = black;
1040     Scr->DefaultC.back = white;
1041     Scr->BorderColor = black;
1042     Scr->BorderTileC.fore = black;
1043     Scr->BorderTileC.back = white;
1044     Scr->TitleC.fore = black;
1045     Scr->TitleC.back = white;
1046     Scr->MenuC.fore = black;
1047     Scr->MenuC.back = white;
1048     Scr->MenuTitleC.fore = black;
1049     Scr->MenuTitleC.back = white;
1050     Scr->MenuShadowColor = black;
1051     Scr->IconC.fore = black;
1052     Scr->IconC.back = white;
1053     Scr->IconBorderColor = black;
1054     Scr->IconManagerC.fore = black;
1055     Scr->IconManagerC.back = white;
1056     Scr->IconManagerHighlight = black;
1057
1058         /* djhjr - 4/19/96 */
1059     Scr->FramePadding = -100;
1060     Scr->TitlePadding = -100;
1061     Scr->ButtonIndent = -100;
1062
1063 /* djhjr - 8/11/98
1064     Scr->ThreeDBorderWidth = 6;
1065 */
1066
1067         /* djhjr - 5/15/96 */
1068         Scr->ResizeX = Scr->ResizeY = 0;
1069
1070     Scr->VirtualC.fore = black;/*RFB VCOLOR*/
1071     Scr->VirtualC.back = white;/*RFB VCOLOR*/
1072         Scr->RealScreenC.back = black;/*RFB 4/92 */
1073         Scr->RealScreenC.fore = white;/*RFB 4/92 */
1074     Scr->VirtualDesktopDisplayC.fore = black;
1075     Scr->VirtualDesktopDisplayC.back = white;
1076     Scr->VirtualDesktopDisplayBorder = black;
1077     Scr->DoorC.fore = black;
1078     Scr->DoorC.back = white;
1079
1080         Scr->AutoRaiseDefault = FALSE;/*RAISEDELAY*/
1081     Scr->FramePadding = 2;              /* values that look "nice" on */
1082     Scr->TitlePadding = 8;              /* 75 and 100dpi displays */
1083     Scr->ButtonIndent = 1;
1084     Scr->SizeStringOffset = 0;
1085     Scr->BorderWidth = BW;
1086     Scr->IconBorderWidth = BW;
1087
1088 /* djhjr - 8/13/98 */
1089 #ifdef ORIGINAL_PIXMAPS
1090     Scr->UnknownWidth = 0;
1091     Scr->UnknownHeight = 0;
1092 #else
1093     Scr->unknownName = NULL;
1094 #endif
1095
1096     Scr->NumAutoRaises = 0;
1097 /*  Scr->NoDefaults = FALSE;  */
1098         Scr->NoDefaultMouseOrKeyboardBindings = FALSE; /* DSE */
1099         Scr->NoDefaultTitleButtons = FALSE; /* DSE */
1100     Scr->UsePPosition = PPOS_OFF;
1101     Scr->FocusRoot = TRUE;
1102     Scr->Newest = NULL; /* PF */
1103     Scr->Focus = NULL;
1104
1105     /* djhjr - 9/10/03 */
1106     Scr->IgnoreModifiers = 0;
1107
1108     /* djhjr - 10/16/02 */
1109     Scr->WarpCentered = WARPC_OFF;
1110
1111     Scr->WarpCursor = FALSE;
1112     Scr->ForceIcon = FALSE;
1113     Scr->NoGrabServer = FALSE;
1114     Scr->NoRaiseMove = FALSE;
1115     Scr->NoRaiseResize = FALSE;
1116     Scr->NoRaiseDeicon = FALSE;
1117     Scr->NoRaiseWarp = FALSE;
1118     Scr->DontMoveOff = FALSE;
1119     Scr->DoZoom = FALSE;
1120     Scr->TitleFocus = TRUE;
1121
1122     /* djhjr - 5/27/98 */
1123     Scr->IconManagerFocus = TRUE;
1124
1125     /* djhjr - 12/14/98 */
1126     Scr->StaticIconPositions = FALSE;
1127
1128     /* djhjr - 10/2/01 */
1129     Scr->StrictIconManager = FALSE;
1130
1131     /* djhjr - 8/23/02 */
1132     Scr->NoBorders = FALSE;
1133
1134     Scr->NoTitlebar = FALSE;
1135     Scr->DecorateTransients = FALSE;
1136     Scr->IconifyByUnmapping = FALSE;
1137     Scr->ShowIconManager = FALSE;
1138     Scr->IconManagerDontShow =FALSE;
1139     Scr->BackingStore = TRUE;
1140     Scr->SaveUnder = TRUE;
1141     Scr->RandomPlacement = FALSE;
1142     Scr->PointerPlacement = FALSE;
1143     Scr->OpaqueMove = FALSE;
1144
1145         /* djhjr - 4/6/98 */
1146         Scr->OpaqueResize = FALSE;
1147
1148     Scr->Highlight = TRUE;
1149
1150         /* djhjr - 1/27/98 */
1151     Scr->IconMgrHighlight = TRUE;
1152
1153     Scr->StackMode = TRUE;
1154     Scr->TitleHighlight = TRUE;
1155     Scr->MoveDelta = 1;         /* so that f.deltastop will work */
1156     Scr->ZoomCount = 8;
1157     Scr->SortIconMgr = FALSE;
1158     Scr->Shadow = TRUE;
1159     Scr->InterpolateMenuColors = FALSE;
1160     Scr->NoIconManagers = FALSE;
1161     Scr->NoIconifyIconManagers = FALSE; /* PF */
1162     Scr->ClientBorderWidth = FALSE;
1163     Scr->SqueezeTitle = -1;
1164
1165 /* djhjr - 4/26/99
1166     Scr->FirstIconRegion = NULL;
1167     Scr->LastIconRegion = NULL;
1168 */
1169     FreeRegions(Scr->FirstIconRegion, Scr->LastIconRegion);
1170
1171         /* djhjr - 4/26/99 */
1172     FreeRegions(Scr->FirstAppletRegion, Scr->LastAppletRegion);
1173
1174     Scr->FirstTime = TRUE;
1175     Scr->HaveFonts = FALSE;             /* i.e. not loaded yet */
1176     Scr->CaseSensitive = TRUE;
1177     Scr->WarpUnmapped = FALSE;
1178     Scr->DeIconifyToScreen = FALSE;
1179     Scr->WarpWindows = FALSE;
1180     Scr->WarpToTransients = FALSE; /* PF */
1181
1182         /* djhjr - 6/25/96 */
1183     Scr->ShallowReliefWindowButton = 2;
1184
1185 /* obsoleted by the *BevelWidth resources - djhjr - 8/11/98
1186         * djhjr - 4/19/96 *
1187     Scr->use3Diconmanagers = FALSE;
1188     Scr->use3Dmenus = FALSE;
1189     Scr->use3Dtitles = FALSE;
1190     Scr->use3Dborders = FALSE;
1191 */
1192
1193     Scr->ClearBevelContrast = 50;
1194     Scr->DarkBevelContrast  = 40;
1195     Scr->BeNiceToColormap = FALSE;
1196
1197 /* obsoleted by the *BevelWidth resources - djhjr - 8/11/98
1198         * djhjr - 5/5/98 *
1199     Scr->use3Dicons = FALSE;
1200 */
1201
1202 /* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02
1203         * djhjr - 4/26/96 *
1204     Scr->SunkFocusWindowTitle = FALSE;
1205 */
1206
1207         /* for rader - djhjr - 2/9/99 */
1208         Scr->NoPrettyTitles = FALSE;
1209
1210         /* djhjr - 9/21/96 */
1211     Scr->ButtonColorIsFrame = FALSE;
1212
1213     Scr->snapRealScreen = FALSE;
1214         Scr->OldFashionedTwmWindowsMenu = FALSE;
1215     Scr->GeometriesAreVirtual = TRUE;
1216         Scr->UseWindowRing = FALSE;
1217
1218     /* setup default fonts; overridden by defaults from system.twmrc */
1219 #define DEFAULT_NICE_FONT "variable"
1220 #define DEFAULT_FAST_FONT "fixed"
1221 #define DEFAULT_SMALL_FONT "5x8"
1222
1223     Scr->TitleBarFont.font = NULL;
1224     Scr->TitleBarFont.name = DEFAULT_NICE_FONT;
1225     Scr->MenuFont.font = NULL;
1226     Scr->MenuFont.name = DEFAULT_NICE_FONT;
1227     Scr->MenuTitleFont.font = NULL; /* DSE */
1228     Scr->MenuTitleFont.name = NULL; /* uses MenuFont unless set -- DSE */
1229     Scr->IconFont.font = NULL;
1230     Scr->IconFont.name = DEFAULT_NICE_FONT;
1231     Scr->SizeFont.font = NULL;
1232     Scr->SizeFont.name = DEFAULT_FAST_FONT;
1233
1234         /* djhjr - 5/10/96 */
1235     Scr->InfoFont.font = NULL;
1236     Scr->InfoFont.name = DEFAULT_FAST_FONT;
1237
1238     Scr->IconManagerFont.font = NULL;
1239     Scr->IconManagerFont.name = DEFAULT_NICE_FONT;
1240     Scr->VirtualFont.font = NULL;
1241     Scr->VirtualFont.name = DEFAULT_SMALL_FONT;
1242     Scr->DoorFont.font = NULL;
1243     Scr->DoorFont.name = DEFAULT_NICE_FONT;
1244     Scr->DefaultFont.font = NULL;
1245     Scr->DefaultFont.name = DEFAULT_FAST_FONT;
1246
1247     /* no names unless they say so */
1248     Scr->NamesInVirtualDesktop = FALSE;
1249
1250     /* by default we emulate the old twm - ie. no virtual desktop */
1251     Scr->Virtual = FALSE;
1252
1253     /* this makes some of the algorithms for checking if windows
1254      * are on the screen simpler */
1255     Scr->VirtualDesktopWidth = Scr->MyDisplayWidth;
1256     Scr->VirtualDesktopHeight = Scr->MyDisplayHeight;
1257
1258     /* start at the top left of the virtual desktop */
1259     Scr->VirtualDesktopX = 0;
1260     Scr->VirtualDesktopY = 0;
1261
1262     /* pan defaults to half screen size */
1263     Scr->VirtualDesktopPanDistanceX = 50;
1264     Scr->VirtualDesktopPanDistanceY = 50;
1265
1266         /* djhjr - 9/8/98 */
1267         Scr->VirtualDesktopPanResistance = 0;
1268
1269     /* default scale is 1:25 */
1270     Scr->VirtualDesktopDScale = 25;
1271
1272     /* and the display should appear at 0, 0 */
1273     Scr->VirtualDesktopDX = 0;
1274     Scr->VirtualDesktopDY = 0;
1275
1276     /* by default no autopan */
1277     Scr->AutoPanX = 0;
1278     Scr->StayUpMenus = FALSE;
1279     Scr->StayUpOptionalMenus = FALSE; /* PF */
1280
1281         Scr->AutoPanWarpWithRespectToRealScreen = 0;   /* DSE */
1282         Scr->AutoPanBorderWidth = 5;                   /* DSE */
1283         Scr->AutoPanExtraWarp = 2;                     /* DSE */
1284         Scr->EnhancedExecResources = FALSE;            /* DSE */
1285         Scr->RightHandSidePulldownMenus = FALSE;       /* DSE */
1286
1287         /* was '2' for when UseRealScreenBorderWidth existed - djhjr - 2/15/99 */
1288         Scr->RealScreenBorderWidth = 0;                /* DSE */
1289
1290         /* djhjr - 10/11/01 */
1291         Scr->ZoomZoom = FALSE;
1292
1293         Scr->LessRandomZoomZoom = FALSE;               /* DSE */
1294         Scr->PrettyZoom = FALSE;                       /* DSE */
1295         Scr->StickyAbove = FALSE;                      /* DSE */
1296         Scr->DontInterpolateTitles = FALSE;            /* DSE */
1297
1298         /* djhjr - 1/6/98 */
1299         Scr->FixManagedVirtualGeometries = FALSE;
1300
1301         Scr->FixTransientVirtualGeometries = FALSE;    /* DSE */
1302         Scr->WarpSnug = FALSE;                         /* DSE */
1303
1304         /* djhjr - 4/17/98 */
1305         Scr->VirtualReceivesMotionEvents = FALSE;
1306         Scr->VirtualSendsMotionEvents = FALSE;
1307
1308         /* djhjr - 5/2/98 */
1309         Scr->BorderBevelWidth = 0;
1310         Scr->TitleBevelWidth = 0;
1311         Scr->MenuBevelWidth = 0;
1312         Scr->IconMgrBevelWidth = 0;
1313         Scr->InfoBevelWidth = 0;
1314
1315         /* djhjr - 8/11/98 */
1316         Scr->IconBevelWidth = 0;
1317         Scr->ButtonBevelWidth = 0;
1318
1319         /* djhjr - 2/7/99 */
1320         Scr->DoorBevelWidth = 0;
1321         Scr->VirtualDesktopBevelWidth = 0;
1322
1323         /* djhjr - 5/22/00 */
1324         Scr->MenuScrollBorderWidth = 2;
1325         Scr->MenuScrollJump = 3;
1326
1327         /* djhjr - 6/22/99 */
1328         Scr->DontDeiconifyTransients = FALSE;
1329
1330         /* submitted by Ugen Antsilevitch - 5/28/00 */
1331         Scr->WarpVisible = FALSE;
1332
1333         /* djhjr - 6/22/01 */
1334         Scr->PauseOnExit = 0;
1335         Scr->PauseOnQuit = 0;
1336
1337         /* djhjr - 11/3/03 */
1338         Scr->RaiseOnStart = FALSE;
1339 }
1340
1341
1342 void CreateFonts ()
1343 {
1344     GetFont(&Scr->TitleBarFont);
1345     GetFont(&Scr->MenuFont);
1346     GetFont(&Scr->IconFont);
1347     GetFont(&Scr->SizeFont);
1348
1349         /* djhjr - 5/10/96 */
1350     GetFont(&Scr->InfoFont);
1351
1352     GetFont(&Scr->IconManagerFont);
1353     GetFont(&Scr->VirtualFont);
1354     GetFont(&Scr->DoorFont);
1355     GetFont(&Scr->DefaultFont);
1356     GetFont(&Scr->MenuTitleFont); /* DSE */
1357     Scr->HaveFonts = TRUE;
1358 }
1359
1360
1361 void RestoreWithdrawnLocation (tmp)
1362     TwmWindow *tmp;
1363 {
1364     int gravx, gravy;
1365     unsigned int bw, mask;
1366     XWindowChanges xwc;
1367
1368     if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y,
1369                       &JunkWidth, &JunkHeight, &bw, &JunkDepth)) {
1370
1371         GetGravityOffsets (tmp, &gravx, &gravy);
1372         if (gravy < 0) xwc.y -= tmp->title_height;
1373
1374         /* djhjr - 4/19/96 */
1375         xwc.x += gravx * tmp->frame_bw3D;
1376         xwc.y += gravy * tmp->frame_bw3D;
1377
1378         if (bw != tmp->old_bw) {
1379             int xoff, yoff;
1380
1381             if (!Scr->ClientBorderWidth) {
1382                 xoff = gravx;
1383                 yoff = gravy;
1384             } else {
1385                 xoff = 0;
1386                 yoff = 0;
1387             }
1388
1389             xwc.x -= (xoff + 1) * tmp->old_bw;
1390             xwc.y -= (yoff + 1) * tmp->old_bw;
1391         }
1392         if (!Scr->ClientBorderWidth) {
1393             xwc.x += gravx * tmp->frame_bw;
1394             xwc.y += gravy * tmp->frame_bw;
1395         }
1396
1397         mask = (CWX | CWY);
1398         if (bw != tmp->old_bw) {
1399             xwc.border_width = tmp->old_bw;
1400             mask |= CWBorderWidth;
1401         }
1402
1403         XConfigureWindow (dpy, tmp->w, mask, &xwc);
1404
1405         if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) {
1406             XUnmapWindow (dpy, tmp->wmhints->icon_window);
1407         }
1408
1409     }
1410 }
1411
1412
1413 void Reborder (time)
1414 Time time;
1415 {
1416     TwmWindow *tmp;                     /* temp twm window structure */
1417     int scrnum;
1418
1419     /* put a border back around all windows */
1420
1421     XGrabServer (dpy);
1422     for (scrnum = 0; scrnum < NumScreens; scrnum++)
1423     {
1424         if ((Scr = ScreenList[scrnum]) == NULL)
1425             continue;
1426
1427         InstallWindowColormaps (0, &Scr->TwmRoot);      /* force reinstall */
1428         for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
1429         {
1430             RestoreWithdrawnLocation (tmp);
1431             XMapWindow (dpy, tmp->w);
1432         }
1433     }
1434
1435     XUngrabServer (dpy);
1436     SetFocus ((TwmWindow*)NULL, time);
1437 }
1438
1439 /* delete the PID file - djhjr - 12/2/01 */
1440 void delete_pidfile()
1441 {
1442     char *fn;
1443
1444     if (PrintPID)
1445     {    
1446         fn = malloc(HomeLen + strlen(PidName) + 2);
1447         sprintf(fn, "%s/%s", Home, PidName);
1448         unlink(fn);
1449         free(fn);
1450     }
1451 }
1452
1453
1454 /*
1455  * Exit handlers. Clean up and exit VTWM.
1456  *
1457  *    PlaySoundDone()
1458  *    Done()
1459  *    QueueRestartVtwm()
1460  */
1461
1462 /* djhjr - 6/22/01 */
1463 #ifndef NO_SOUND_SUPPORT
1464 SIGNAL_T PlaySoundDone()
1465 {
1466     if (PlaySound(S_STOP))
1467     {
1468         /* allow time to emit */
1469         if (Scr->PauseOnExit) sleep(Scr->PauseOnExit);
1470     }
1471
1472     Done();
1473     SIGNAL_RETURN;
1474 }
1475
1476 void Done()
1477 {
1478     CloseSound();
1479
1480     SetRealScreen(0,0);
1481     Reborder (CurrentTime);
1482     XCloseDisplay(dpy);
1483     
1484     delete_pidfile(); /* djhjr - 12/2/01 */
1485
1486     exit(0);
1487 }
1488 #else
1489 SIGNAL_T Done()
1490 {
1491     SetRealScreen(0,0);
1492     Reborder (CurrentTime);
1493     XCloseDisplay(dpy);
1494     
1495     delete_pidfile(); /* djhjr - 12/2/01 */
1496
1497     exit(0);
1498     SIGNAL_RETURN;
1499 }
1500 #endif
1501
1502 /* djhjr - 7/31/98 */
1503 SIGNAL_T
1504 QueueRestartVtwm()
1505 {
1506     XClientMessageEvent ev;
1507
1508     delete_pidfile(); /* djhjr - 12/2/01 */
1509
1510     ev.type = ClientMessage;
1511     ev.window = Scr->Root;
1512     ev.message_type = _XA_TWM_RESTART;
1513     ev.format = 32;
1514     ev.data.b[0] = (char)0;
1515
1516     XSendEvent (dpy, Scr->VirtualDesktopDisplay, False, 0L, (XEvent *) &ev);
1517     XFlush(dpy);
1518     SIGNAL_RETURN;
1519 }
1520
1521
1522 /*
1523  * Error Handlers.  If a client dies, we'll get a BadWindow error (except for
1524  * GetGeometry which returns BadDrawable) for most operations that we do before
1525  * manipulating the client's window.
1526  */
1527
1528 Bool ErrorOccurred = False;
1529 XErrorEvent LastErrorEvent;
1530
1531 static int TwmErrorHandler(dpy, event)
1532     Display *dpy;
1533     XErrorEvent *event;
1534 {
1535     LastErrorEvent = *event;
1536     ErrorOccurred = True;
1537
1538     if (PrintErrorMessages &&                   /* don't be too obnoxious */
1539         event->error_code != BadWindow &&       /* watch for dead puppies */
1540         (event->request_code != X_GetGeometry &&         /* of all styles */
1541          event->error_code != BadDrawable))
1542       XmuPrintDefaultErrorMessage (dpy, event, stderr);
1543     return 0;
1544 }
1545
1546
1547 /* ARGSUSED*/
1548 static int CatchRedirectError(dpy, event)
1549     Display *dpy;
1550     XErrorEvent *event;
1551 {
1552     RedirectError = TRUE;
1553     LastErrorEvent = *event;
1554     ErrorOccurred = True;
1555     return 0;
1556 }
1557
1558 Atom _XA_MIT_PRIORITY_COLORS;
1559 Atom _XA_WM_CHANGE_STATE;
1560 Atom _XA_WM_STATE;
1561 Atom _XA_WM_COLORMAP_WINDOWS;
1562 Atom _XA_WM_PROTOCOLS;
1563 Atom _XA_WM_TAKE_FOCUS;
1564 Atom _XA_WM_SAVE_YOURSELF;
1565 Atom _XA_WM_DELETE_WINDOW;
1566
1567 /* djhjr - 7/31/98 */
1568 Atom _XA_TWM_RESTART;
1569
1570 void InternUsefulAtoms ()
1571 {
1572     /*
1573      * Create priority colors if necessary.
1574      */
1575     _XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False);
1576     _XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False);
1577     _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False);
1578     _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False);
1579     _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
1580     _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False);
1581     _XA_WM_SAVE_YOURSELF = XInternAtom (dpy, "WM_SAVE_YOURSELF", False);
1582     _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
1583
1584     /* djhjr - 7/31/98 */
1585     _XA_TWM_RESTART = XInternAtom (dpy, "_TWM_RESTART", False);
1586 }