twm.c revision 3e747e6d
13e747e6dSmrg/*****************************************************************************/
23e747e6dSmrg/*
33e747e6dSmrg
43e747e6dSmrgCopyright 1989, 1998  The Open Group
53e747e6dSmrgCopyright 2005 Hitachi, Ltd.
63e747e6dSmrg
73e747e6dSmrgPermission to use, copy, modify, distribute, and sell this software and its
83e747e6dSmrgdocumentation for any purpose is hereby granted without fee, provided that
93e747e6dSmrgthe above copyright notice appear in all copies and that both that
103e747e6dSmrgcopyright notice and this permission notice appear in supporting
113e747e6dSmrgdocumentation.
123e747e6dSmrg
133e747e6dSmrgThe above copyright notice and this permission notice shall be included in
143e747e6dSmrgall copies or substantial portions of the Software.
153e747e6dSmrg
163e747e6dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
173e747e6dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
183e747e6dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
193e747e6dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
203e747e6dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213e747e6dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
223e747e6dSmrg
233e747e6dSmrgExcept as contained in this notice, the name of The Open Group shall not be
243e747e6dSmrgused in advertising or otherwise to promote the sale, use or other dealings
253e747e6dSmrgin this Software without prior written authorization from The Open Group.
263e747e6dSmrg
273e747e6dSmrg*/
283e747e6dSmrg/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
293e747e6dSmrg/**                          Salt Lake City, Utah                           **/
303e747e6dSmrg/**                        Cambridge, Massachusetts                         **/
313e747e6dSmrg/**                                                                         **/
323e747e6dSmrg/**                           All Rights Reserved                           **/
333e747e6dSmrg/**                                                                         **/
343e747e6dSmrg/**    Permission to use, copy, modify, and distribute this software and    **/
353e747e6dSmrg/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
363e747e6dSmrg/**    granted, provided that the above copyright notice appear  in  all    **/
373e747e6dSmrg/**    copies and that both  that  copyright  notice  and  this  permis-    **/
383e747e6dSmrg/**    sion  notice appear in supporting  documentation,  and  that  the    **/
393e747e6dSmrg/**    name of Evans & Sutherland not be used in advertising    **/
403e747e6dSmrg/**    in publicity pertaining to distribution of the  software  without    **/
413e747e6dSmrg/**    specific, written prior permission.                                  **/
423e747e6dSmrg/**                                                                         **/
433e747e6dSmrg/**    EVANS & SUTHERLAND DISCLAIMs ALL WARRANTIES WITH REGARD    **/
443e747e6dSmrg/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
453e747e6dSmrg/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND    **/
463e747e6dSmrg/**    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
473e747e6dSmrg/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
483e747e6dSmrg/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
493e747e6dSmrg/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
503e747e6dSmrg/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
513e747e6dSmrg/*****************************************************************************/
523e747e6dSmrg
533e747e6dSmrg
543e747e6dSmrg/***********************************************************************
553e747e6dSmrg *
563e747e6dSmrg * $Xorg: twm.c,v 1.5 2001/02/09 02:05:37 xorgcvs Exp $
573e747e6dSmrg *
583e747e6dSmrg * twm - "Tom's Window Manager"
593e747e6dSmrg *
603e747e6dSmrg * 27-Oct-1987 Thomas E. LaStrange    File created
613e747e6dSmrg * 10-Oct-1990 David M. Sternlicht    Storing saved colors on root
623e747e6dSmrg * 19-Feb-2005 Julien Lafon           Handle print screens for unified Xserver
633e747e6dSmrg ***********************************************************************/
643e747e6dSmrg/* $XFree86: xc/programs/twm/twm.c,v 3.13 2003/04/21 08:15:10 herrb Exp $ */
653e747e6dSmrg
663e747e6dSmrg#include <stdio.h>
673e747e6dSmrg#include <signal.h>
683e747e6dSmrg#include <fcntl.h>
693e747e6dSmrg#include "twm.h"
703e747e6dSmrg#include "iconmgr.h"
713e747e6dSmrg#include "add_window.h"
723e747e6dSmrg#include "gc.h"
733e747e6dSmrg#include "parse.h"
743e747e6dSmrg#include "version.h"
753e747e6dSmrg#include "menus.h"
763e747e6dSmrg#include "events.h"
773e747e6dSmrg#include "util.h"
783e747e6dSmrg#include "gram.h"
793e747e6dSmrg#include "screen.h"
803e747e6dSmrg#include "parse.h"
813e747e6dSmrg#include "session.h"
823e747e6dSmrg#include <X11/Xproto.h>
833e747e6dSmrg#include <X11/Xatom.h>
843e747e6dSmrg#include <X11/SM/SMlib.h>
853e747e6dSmrg#include <X11/Xmu/Error.h>
863e747e6dSmrg#include <X11/extensions/sync.h>
873e747e6dSmrg#include <X11/Xlocale.h>
883e747e6dSmrg#ifdef XPRINT
893e747e6dSmrg#include <X11/extensions/Print.h>
903e747e6dSmrg#endif /* XPRINT */
913e747e6dSmrg
923e747e6dSmrgXtAppContext appContext;	/* Xt application context */
933e747e6dSmrgXtSignalId si;
943e747e6dSmrg
953e747e6dSmrgDisplay *dpy = NULL;		/* which display are we talking to */
963e747e6dSmrgWindow ResizeWindow;		/* the window we are resizing */
973e747e6dSmrg
983e747e6dSmrgint MultiScreen = TRUE;		/* try for more than one screen? */
993e747e6dSmrgint NoPrintscreens = False;     /* ignore special handling of print screens? */
1003e747e6dSmrgint NumScreens;			/* number of screens in ScreenList */
1013e747e6dSmrgint HasShape;			/* server supports shape extension? */
1023e747e6dSmrgint ShapeEventBase, ShapeErrorBase;
1033e747e6dSmrgint HasSync;			/* server supports SYNC extension? */
1043e747e6dSmrgint SyncEventBase, SyncErrorBase;
1053e747e6dSmrgScreenInfo **ScreenList;	/* structures for each screen */
1063e747e6dSmrgScreenInfo *Scr = NULL;		/* the cur and prev screens */
1073e747e6dSmrgint PreviousScreen;		/* last screen that we were on */
1083e747e6dSmrgint FirstScreen;		/* TRUE ==> first screen of display */
1093e747e6dSmrgBool PrintErrorMessages = False;	/* controls error messages */
1103e747e6dSmrgstatic int RedirectError;	/* TRUE ==> another window manager running */
1113e747e6dSmrgstatic int TwmErrorHandler ( Display *dpy, XErrorEvent *event );	/* for settting RedirectError */
1123e747e6dSmrgstatic int CatchRedirectError ( Display *dpy, XErrorEvent *event );	/* for everything else */
1133e747e6dSmrgstatic SIGNAL_T sigHandler(int);
1143e747e6dSmrgchar Info[INFO_LINES][INFO_SIZE];		/* info strings to print */
1153e747e6dSmrgint InfoLines;
1163e747e6dSmrgchar *InitFile = NULL;
1173e747e6dSmrg
1183e747e6dSmrgCursor UpperLeftCursor;		/* upper Left corner cursor */
1193e747e6dSmrgCursor RightButt;
1203e747e6dSmrgCursor MiddleButt;
1213e747e6dSmrgCursor LeftButt;
1223e747e6dSmrg
1233e747e6dSmrgXContext TwmContext;		/* context for twm windows */
1243e747e6dSmrgXContext MenuContext;		/* context for all menu windows */
1253e747e6dSmrgXContext IconManagerContext;	/* context for all window list windows */
1263e747e6dSmrgXContext ScreenContext;		/* context to get screen data */
1273e747e6dSmrgXContext ColormapContext;	/* context for colormap operations */
1283e747e6dSmrg
1293e747e6dSmrgXClassHint NoClass;		/* for applications with no class */
1303e747e6dSmrg
1313e747e6dSmrgXGCValues Gcv;
1323e747e6dSmrg
1333e747e6dSmrgchar *Home;			/* the HOME environment variable */
1343e747e6dSmrgint HomeLen;			/* length of Home */
1353e747e6dSmrgint ParseError;			/* error parsing the .twmrc file */
1363e747e6dSmrg
1373e747e6dSmrgint HandlingEvents = FALSE;	/* are we handling events yet? */
1383e747e6dSmrg
1393e747e6dSmrgWindow JunkRoot;		/* junk window */
1403e747e6dSmrgWindow JunkChild;		/* junk window */
1413e747e6dSmrgint JunkX;			/* junk variable */
1423e747e6dSmrgint JunkY;			/* junk variable */
1433e747e6dSmrgunsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;
1443e747e6dSmrg
1453e747e6dSmrgchar *ProgramName;
1463e747e6dSmrgint Argc;
1473e747e6dSmrgchar **Argv;
1483e747e6dSmrg
1493e747e6dSmrgBool RestartPreviousState = False;	/* try to restart in previous state */
1503e747e6dSmrg
1513e747e6dSmrgunsigned long black, white;
1523e747e6dSmrg
1533e747e6dSmrgAtom TwmAtoms[11];
1543e747e6dSmrg
1553e747e6dSmrgBool use_fontset;		/* use XFontSet-related functions or not */
1563e747e6dSmrg
1573e747e6dSmrg/* don't change the order of these strings */
1583e747e6dSmrgstatic char* atom_names[11] = {
1593e747e6dSmrg    "_MIT_PRIORITY_COLORS",
1603e747e6dSmrg    "WM_CHANGE_STATE",
1613e747e6dSmrg    "WM_STATE",
1623e747e6dSmrg    "WM_COLORMAP_WINDOWS",
1633e747e6dSmrg    "WM_PROTOCOLS",
1643e747e6dSmrg    "WM_TAKE_FOCUS",
1653e747e6dSmrg    "WM_SAVE_YOURSELF",
1663e747e6dSmrg    "WM_DELETE_WINDOW",
1673e747e6dSmrg    "SM_CLIENT_ID",
1683e747e6dSmrg    "WM_CLIENT_LEADER",
1693e747e6dSmrg    "WM_WINDOW_ROLE"
1703e747e6dSmrg};
1713e747e6dSmrg
1723e747e6dSmrg#ifdef XPRINT
1733e747e6dSmrg/* |hasExtension()| and |IsPrintScreen()| have been stolen from
1743e747e6dSmrg * xc/programs/xdpyinfo/xdpyinfo.c */
1753e747e6dSmrgstatic
1763e747e6dSmrgBool hasExtension(Display *dpy, char *extname)
1773e747e6dSmrg{
1783e747e6dSmrg  int    num_extensions,
1793e747e6dSmrg         i;
1803e747e6dSmrg  char **extensions;
1813e747e6dSmrg  extensions = XListExtensions(dpy, &num_extensions);
1823e747e6dSmrg  for (i = 0; i < num_extensions &&
1833e747e6dSmrg         (strcmp(extensions[i], extname) != 0); i++);
1843e747e6dSmrg  XFreeExtensionList(extensions);
1853e747e6dSmrg  return i != num_extensions;
1863e747e6dSmrg}
1873e747e6dSmrg
1883e747e6dSmrgstatic
1893e747e6dSmrgBool IsPrintScreen(Screen *s)
1903e747e6dSmrg{
1913e747e6dSmrg    Display *dpy = XDisplayOfScreen(s);
1923e747e6dSmrg    int      i;
1933e747e6dSmrg
1943e747e6dSmrg    /* Check whether this is a screen of a print DDX */
1953e747e6dSmrg    if (hasExtension(dpy, XP_PRINTNAME)) {
1963e747e6dSmrg        Screen **pscreens;
1973e747e6dSmrg        int      pscrcount;
1983e747e6dSmrg
1993e747e6dSmrg        pscreens = XpQueryScreens(dpy, &pscrcount);
2003e747e6dSmrg        for( i = 0 ; (i < pscrcount) && pscreens ; i++ ) {
2013e747e6dSmrg            if (s == pscreens[i]) {
2023e747e6dSmrg                return True;
2033e747e6dSmrg            }
2043e747e6dSmrg        }
2053e747e6dSmrg        XFree(pscreens);
2063e747e6dSmrg    }
2073e747e6dSmrg    return False;
2083e747e6dSmrg}
2093e747e6dSmrg#endif /* XPRINT */
2103e747e6dSmrg
2113e747e6dSmrg/***********************************************************************
2123e747e6dSmrg *
2133e747e6dSmrg *  Procedure:
2143e747e6dSmrg *	main - start of twm
2153e747e6dSmrg *
2163e747e6dSmrg ***********************************************************************
2173e747e6dSmrg */
2183e747e6dSmrg
2193e747e6dSmrgint
2203e747e6dSmrgmain(int argc, char *argv[])
2213e747e6dSmrg{
2223e747e6dSmrg    Window root, parent, *children;
2233e747e6dSmrg    unsigned int nchildren;
2243e747e6dSmrg    int i, j;
2253e747e6dSmrg    char *display_name = NULL;
2263e747e6dSmrg    unsigned long valuemask;	/* mask for create windows */
2273e747e6dSmrg    XSetWindowAttributes attributes;	/* attributes for create windows */
2283e747e6dSmrg    int numManaged, firstscrn, lastscrn, scrnum;
2293e747e6dSmrg    int zero = 0;
2303e747e6dSmrg    char *restore_filename = NULL;
2313e747e6dSmrg    char *client_id = NULL;
2323e747e6dSmrg    char *loc;
2333e747e6dSmrg
2343e747e6dSmrg    ProgramName = argv[0];
2353e747e6dSmrg    Argc = argc;
2363e747e6dSmrg    Argv = argv;
2373e747e6dSmrg
2383e747e6dSmrg    for (i = 1; i < argc; i++) {
2393e747e6dSmrg	if (argv[i][0] == '-') {
2403e747e6dSmrg	    switch (argv[i][1]) {
2413e747e6dSmrg	      case 'd':				/* -display dpy */
2423e747e6dSmrg		if (strcmp(&argv[i][1], "display")) goto usage;
2433e747e6dSmrg		if (++i >= argc) goto usage;
2443e747e6dSmrg		display_name = argv[i];
2453e747e6dSmrg		continue;
2463e747e6dSmrg	      case 's':				/* -single */
2473e747e6dSmrg		MultiScreen = FALSE;
2483e747e6dSmrg		continue;
2493e747e6dSmrg#ifdef XPRINT
2503e747e6dSmrg	      case 'n':				/* -noprint */
2513e747e6dSmrg		if (strcmp(&argv[i][1], "noprint")) goto usage;
2523e747e6dSmrg		NoPrintscreens = True;
2533e747e6dSmrg		continue;
2543e747e6dSmrg#endif /* XPRINT */
2553e747e6dSmrg	      case 'f':				/* -file twmrcfilename */
2563e747e6dSmrg		if (++i >= argc) goto usage;
2573e747e6dSmrg		InitFile = argv[i];
2583e747e6dSmrg		continue;
2593e747e6dSmrg	      case 'v':				/* -verbose */
2603e747e6dSmrg		PrintErrorMessages = True;
2613e747e6dSmrg		continue;
2623e747e6dSmrg	      case 'c':				/* -clientId */
2633e747e6dSmrg		if (strcmp(&argv[i][1], "clientId")) goto usage;
2643e747e6dSmrg		if (++i >= argc) goto usage;
2653e747e6dSmrg		client_id = argv[i];
2663e747e6dSmrg		continue;
2673e747e6dSmrg	      case 'r':				/* -restore */
2683e747e6dSmrg		if (strcmp(&argv[i][1], "restore")) goto usage;
2693e747e6dSmrg		if (++i >= argc) goto usage;
2703e747e6dSmrg		restore_filename = argv[i];
2713e747e6dSmrg		continue;
2723e747e6dSmrg	      case 'q':				/* -quiet */
2733e747e6dSmrg		PrintErrorMessages = False;
2743e747e6dSmrg		continue;
2753e747e6dSmrg	    }
2763e747e6dSmrg	}
2773e747e6dSmrg      usage:
2783e747e6dSmrg	fprintf (stderr,
2793e747e6dSmrg		 "usage:  %s [-display dpy] [-f file] [-s] [-q] [-v]"
2803e747e6dSmrg#ifdef XPRINT
2813e747e6dSmrg                 " [-noprint]"
2823e747e6dSmrg#endif /* XPRINT */
2833e747e6dSmrg                 " [-clientId id] [-restore file]\n",
2843e747e6dSmrg		 ProgramName);
2853e747e6dSmrg	exit (1);
2863e747e6dSmrg    }
2873e747e6dSmrg
2883e747e6dSmrg    loc = setlocale(LC_ALL, "");
2893e747e6dSmrg    if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") ||
2903e747e6dSmrg	!XSupportsLocale()) {
2913e747e6dSmrg	 use_fontset = False;
2923e747e6dSmrg    } else {
2933e747e6dSmrg	 use_fontset = True;
2943e747e6dSmrg    }
2953e747e6dSmrg
2963e747e6dSmrg#define newhandler(sig) \
2973e747e6dSmrg    if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, sigHandler)
2983e747e6dSmrg
2993e747e6dSmrg
3003e747e6dSmrg    newhandler (SIGINT);
3013e747e6dSmrg    newhandler (SIGHUP);
3023e747e6dSmrg    newhandler (SIGQUIT);
3033e747e6dSmrg    newhandler (SIGTERM);
3043e747e6dSmrg
3053e747e6dSmrg#undef newhandler
3063e747e6dSmrg
3073e747e6dSmrg    Home = getenv("HOME");
3083e747e6dSmrg    if (Home != NULL) {
3093e747e6dSmrg    	char *temp_p;
3103e747e6dSmrg
3113e747e6dSmrg	/*
3123e747e6dSmrg	 * Make a copy of Home because the string returned by getenv() can be
3133e747e6dSmrg	 * overwritten by some POSIX.1 and ANSI-C implementations of getenv()
3143e747e6dSmrg	 * when further calls to getenv() are made
3153e747e6dSmrg	 */
3163e747e6dSmrg
3173e747e6dSmrg	temp_p = strdup(Home);
3183e747e6dSmrg	Home = temp_p;
3193e747e6dSmrg    }
3203e747e6dSmrg
3213e747e6dSmrg    if (Home == NULL)
3223e747e6dSmrg	Home = "./";
3233e747e6dSmrg
3243e747e6dSmrg    HomeLen = strlen(Home);
3253e747e6dSmrg
3263e747e6dSmrg    NoClass.res_name = NoName;
3273e747e6dSmrg    NoClass.res_class = NoName;
3283e747e6dSmrg
3293e747e6dSmrg    XtToolkitInitialize ();
3303e747e6dSmrg    appContext = XtCreateApplicationContext ();
3313e747e6dSmrg
3323e747e6dSmrg    si = XtAppAddSignal(appContext, Done, NULL);
3333e747e6dSmrg
3343e747e6dSmrg    if (!(dpy = XtOpenDisplay (appContext, display_name, "twm", "twm",
3353e747e6dSmrg	NULL, 0, &zero, NULL))) {
3363e747e6dSmrg	fprintf (stderr, "%s:  unable to open display \"%s\"\n",
3373e747e6dSmrg		 ProgramName, XDisplayName(display_name));
3383e747e6dSmrg	exit (1);
3393e747e6dSmrg    }
3403e747e6dSmrg
3413e747e6dSmrg    if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) {
3423e747e6dSmrg	fprintf (stderr,
3433e747e6dSmrg		 "%s:  unable to mark display connection as close-on-exec\n",
3443e747e6dSmrg		 ProgramName);
3453e747e6dSmrg	exit (1);
3463e747e6dSmrg    }
3473e747e6dSmrg
3483e747e6dSmrg    if (restore_filename)
3493e747e6dSmrg	ReadWinConfigFile (restore_filename);
3503e747e6dSmrg
3513e747e6dSmrg    HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase);
3523e747e6dSmrg    HasSync = XSyncQueryExtension(dpy,  &SyncEventBase, &SyncErrorBase);
3533e747e6dSmrg    TwmContext = XUniqueContext();
3543e747e6dSmrg    MenuContext = XUniqueContext();
3553e747e6dSmrg    IconManagerContext = XUniqueContext();
3563e747e6dSmrg    ScreenContext = XUniqueContext();
3573e747e6dSmrg    ColormapContext = XUniqueContext();
3583e747e6dSmrg
3593e747e6dSmrg    (void) XInternAtoms(dpy, atom_names, sizeof TwmAtoms / sizeof TwmAtoms[0],
3603e747e6dSmrg			False, TwmAtoms);
3613e747e6dSmrg
3623e747e6dSmrg    /* Set up the per-screen global information. */
3633e747e6dSmrg
3643e747e6dSmrg    NumScreens = ScreenCount(dpy);
3653e747e6dSmrg
3663e747e6dSmrg    if (MultiScreen)
3673e747e6dSmrg    {
3683e747e6dSmrg	firstscrn = 0;
3693e747e6dSmrg	lastscrn = NumScreens - 1;
3703e747e6dSmrg    }
3713e747e6dSmrg    else
3723e747e6dSmrg    {
3733e747e6dSmrg	firstscrn = lastscrn = DefaultScreen(dpy);
3743e747e6dSmrg    }
3753e747e6dSmrg
3763e747e6dSmrg    InfoLines = 0;
3773e747e6dSmrg
3783e747e6dSmrg    /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */
3793e747e6dSmrg    ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *));
3803e747e6dSmrg    if (ScreenList == NULL)
3813e747e6dSmrg    {
3823e747e6dSmrg	fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
3833e747e6dSmrg		 ProgramName);
3843e747e6dSmrg	exit (1);
3853e747e6dSmrg    }
3863e747e6dSmrg    numManaged = 0;
3873e747e6dSmrg    PreviousScreen = DefaultScreen(dpy);
3883e747e6dSmrg    FirstScreen = TRUE;
3893e747e6dSmrg    for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++)
3903e747e6dSmrg    {
3913e747e6dSmrg#ifdef XPRINT
3923e747e6dSmrg        /* Ignore print screens to avoid that users accidentally warp on a
3933e747e6dSmrg         * print screen (which are not visible on video displays) */
3943e747e6dSmrg        if ((!NoPrintscreens) && IsPrintScreen(XScreenOfDisplay(dpy, scrnum)))
3953e747e6dSmrg        {
3963e747e6dSmrg	    fprintf (stderr, "%s:  skipping print screen %d\n",
3973e747e6dSmrg		     ProgramName, scrnum);
3983e747e6dSmrg            continue;
3993e747e6dSmrg        }
4003e747e6dSmrg#endif /* XPRINT */
4013e747e6dSmrg
4023e747e6dSmrg        /* Make sure property priority colors is empty */
4033e747e6dSmrg        XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS,
4043e747e6dSmrg			 XA_CARDINAL, 32, PropModeReplace, NULL, 0);
4053e747e6dSmrg	RedirectError = FALSE;
4063e747e6dSmrg	XSetErrorHandler(CatchRedirectError);
4073e747e6dSmrg	XSelectInput(dpy, RootWindow (dpy, scrnum),
4083e747e6dSmrg	    ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
4093e747e6dSmrg	    SubstructureRedirectMask | KeyPressMask |
4103e747e6dSmrg	    ButtonPressMask | ButtonReleaseMask);
4113e747e6dSmrg	XSync(dpy, 0);
4123e747e6dSmrg	XSetErrorHandler(TwmErrorHandler);
4133e747e6dSmrg
4143e747e6dSmrg	if (RedirectError)
4153e747e6dSmrg	{
4163e747e6dSmrg	    fprintf (stderr, "%s:  another window manager is already running.",
4173e747e6dSmrg		     ProgramName);
4183e747e6dSmrg	    if (MultiScreen && NumScreens > 0)
4193e747e6dSmrg		fprintf(stderr, " on screen %d?\n", scrnum);
4203e747e6dSmrg	    else
4213e747e6dSmrg		fprintf(stderr, "?\n");
4223e747e6dSmrg	    continue;
4233e747e6dSmrg	}
4243e747e6dSmrg
4253e747e6dSmrg	numManaged ++;
4263e747e6dSmrg
4273e747e6dSmrg	/* Note:  ScreenInfo struct is calloc'ed to initialize to zero. */
4283e747e6dSmrg	Scr = ScreenList[scrnum] =
4293e747e6dSmrg	    (ScreenInfo *) calloc(1, sizeof(ScreenInfo));
4303e747e6dSmrg  	if (Scr == NULL)
4313e747e6dSmrg  	{
4323e747e6dSmrg  	    fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n",
4333e747e6dSmrg  		     ProgramName, scrnum);
4343e747e6dSmrg  	    continue;
4353e747e6dSmrg  	}
4363e747e6dSmrg
4373e747e6dSmrg	/* initialize list pointers, remember to put an initialization
4383e747e6dSmrg	 * in InitVariables also
4393e747e6dSmrg	 */
4403e747e6dSmrg	Scr->BorderColorL = NULL;
4413e747e6dSmrg	Scr->IconBorderColorL = NULL;
4423e747e6dSmrg	Scr->BorderTileForegroundL = NULL;
4433e747e6dSmrg	Scr->BorderTileBackgroundL = NULL;
4443e747e6dSmrg	Scr->TitleForegroundL = NULL;
4453e747e6dSmrg	Scr->TitleBackgroundL = NULL;
4463e747e6dSmrg	Scr->IconForegroundL = NULL;
4473e747e6dSmrg	Scr->IconBackgroundL = NULL;
4483e747e6dSmrg	Scr->NoTitle = NULL;
4493e747e6dSmrg	Scr->MakeTitle = NULL;
4503e747e6dSmrg	Scr->AutoRaise = NULL;
4513e747e6dSmrg	Scr->IconNames = NULL;
4523e747e6dSmrg	Scr->NoHighlight = NULL;
4533e747e6dSmrg	Scr->NoStackModeL = NULL;
4543e747e6dSmrg	Scr->NoTitleHighlight = NULL;
4553e747e6dSmrg	Scr->DontIconify = NULL;
4563e747e6dSmrg	Scr->IconMgrNoShow = NULL;
4573e747e6dSmrg	Scr->IconMgrShow = NULL;
4583e747e6dSmrg	Scr->IconifyByUn = NULL;
4593e747e6dSmrg	Scr->IconManagerFL = NULL;
4603e747e6dSmrg	Scr->IconManagerBL = NULL;
4613e747e6dSmrg	Scr->IconMgrs = NULL;
4623e747e6dSmrg	Scr->StartIconified = NULL;
4633e747e6dSmrg	Scr->SqueezeTitleL = NULL;
4643e747e6dSmrg	Scr->DontSqueezeTitleL = NULL;
4653e747e6dSmrg	Scr->WindowRingL = NULL;
4663e747e6dSmrg	Scr->WarpCursorL = NULL;
4673e747e6dSmrg	/* remember to put an initialization in InitVariables also
4683e747e6dSmrg	 */
4693e747e6dSmrg
4703e747e6dSmrg	Scr->screen = scrnum;
4713e747e6dSmrg	Scr->d_depth = DefaultDepth(dpy, scrnum);
4723e747e6dSmrg	Scr->d_visual = DefaultVisual(dpy, scrnum);
4733e747e6dSmrg	Scr->Root = RootWindow(dpy, scrnum);
4743e747e6dSmrg	XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr);
4753e747e6dSmrg
4763e747e6dSmrg	Scr->TwmRoot.cmaps.number_cwins = 1;
4773e747e6dSmrg	Scr->TwmRoot.cmaps.cwins =
4783e747e6dSmrg		(ColormapWindow **) malloc(sizeof(ColormapWindow *));
4793e747e6dSmrg	Scr->TwmRoot.cmaps.cwins[0] =
4803e747e6dSmrg		CreateColormapWindow(Scr->Root, True, False);
4813e747e6dSmrg	Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured;
4823e747e6dSmrg
4833e747e6dSmrg	Scr->cmapInfo.cmaps = NULL;
4843e747e6dSmrg	Scr->cmapInfo.maxCmaps =
4853e747e6dSmrg		MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen));
4863e747e6dSmrg	Scr->cmapInfo.root_pushes = 0;
4873e747e6dSmrg	InstallWindowColormaps(0, &Scr->TwmRoot);
4883e747e6dSmrg
4893e747e6dSmrg	Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail =
4903e747e6dSmrg	  Scr->StdCmapInfo.mru = NULL;
4913e747e6dSmrg	Scr->StdCmapInfo.mruindex = 0;
4923e747e6dSmrg	LocateStandardColormaps();
4933e747e6dSmrg
4943e747e6dSmrg	Scr->TBInfo.nleft = Scr->TBInfo.nright = 0;
4953e747e6dSmrg	Scr->TBInfo.head = NULL;
4963e747e6dSmrg	Scr->TBInfo.border = 1;
4973e747e6dSmrg	Scr->TBInfo.width = 0;
4983e747e6dSmrg	Scr->TBInfo.leftx = 0;
4993e747e6dSmrg	Scr->TBInfo.titlex = 0;
5003e747e6dSmrg
5013e747e6dSmrg	Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum);
5023e747e6dSmrg	Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum);
5033e747e6dSmrg	Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth;
5043e747e6dSmrg	Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight;
5053e747e6dSmrg
5063e747e6dSmrg	Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;
5073e747e6dSmrg
5083e747e6dSmrg	if (DisplayCells(dpy, scrnum) < 3)
5093e747e6dSmrg	    Scr->Monochrome = MONOCHROME;
5103e747e6dSmrg 	else if (DefaultVisual(dpy, scrnum)->class == GrayScale)
5113e747e6dSmrg 	    Scr->Monochrome = GRAYSCALE;
5123e747e6dSmrg	else
5133e747e6dSmrg	    Scr->Monochrome = COLOR;
5143e747e6dSmrg
5153e747e6dSmrg	/* setup default colors */
5163e747e6dSmrg	Scr->FirstTime = TRUE;
5173e747e6dSmrg	GetColor(Scr->Monochrome, &black, "black");
5183e747e6dSmrg	Scr->Black = black;
5193e747e6dSmrg	GetColor(Scr->Monochrome, &white, "white");
5203e747e6dSmrg	Scr->White = white;
5213e747e6dSmrg
5223e747e6dSmrg	if (FirstScreen)
5233e747e6dSmrg	{
5243e747e6dSmrg	    SetFocus ((TwmWindow *)NULL, CurrentTime);
5253e747e6dSmrg
5263e747e6dSmrg	    /* define cursors */
5273e747e6dSmrg
5283e747e6dSmrg	    NewFontCursor(&UpperLeftCursor, "top_left_corner");
5293e747e6dSmrg	    NewFontCursor(&RightButt, "rightbutton");
5303e747e6dSmrg	    NewFontCursor(&LeftButt, "leftbutton");
5313e747e6dSmrg	    NewFontCursor(&MiddleButt, "middlebutton");
5323e747e6dSmrg	}
5333e747e6dSmrg
5343e747e6dSmrg	Scr->iconmgr.x = 0;
5353e747e6dSmrg	Scr->iconmgr.y = 0;
5363e747e6dSmrg	Scr->iconmgr.width = 150;
5373e747e6dSmrg	Scr->iconmgr.height = 5;
5383e747e6dSmrg	Scr->iconmgr.next = NULL;
5393e747e6dSmrg	Scr->iconmgr.prev = NULL;
5403e747e6dSmrg	Scr->iconmgr.lasti = &(Scr->iconmgr);
5413e747e6dSmrg	Scr->iconmgr.first = NULL;
5423e747e6dSmrg	Scr->iconmgr.last = NULL;
5433e747e6dSmrg	Scr->iconmgr.active = NULL;
5443e747e6dSmrg	Scr->iconmgr.scr = Scr;
5453e747e6dSmrg	Scr->iconmgr.columns = 1;
5463e747e6dSmrg	Scr->iconmgr.count = 0;
5473e747e6dSmrg	Scr->iconmgr.name = "TWM";
5483e747e6dSmrg	Scr->iconmgr.icon_name = "Icons";
5493e747e6dSmrg
5503e747e6dSmrg	Scr->IconDirectory = NULL;
5513e747e6dSmrg
5523e747e6dSmrg	Scr->siconifyPm = None;
5533e747e6dSmrg	Scr->pullPm = None;
5543e747e6dSmrg	Scr->hilitePm = None;
5553e747e6dSmrg	Scr->tbpm.xlogo = None;
5563e747e6dSmrg	Scr->tbpm.resize = None;
5573e747e6dSmrg	Scr->tbpm.question = None;
5583e747e6dSmrg	Scr->tbpm.menu = None;
5593e747e6dSmrg	Scr->tbpm.delete = None;
5603e747e6dSmrg
5613e747e6dSmrg	InitVariables();
5623e747e6dSmrg	InitMenus();
5633e747e6dSmrg
5643e747e6dSmrg	/* Parse it once for each screen. */
5653e747e6dSmrg	ParseTwmrc(InitFile);
5663e747e6dSmrg	assign_var_savecolor(); /* storeing pixels for twmrc "entities" */
5673e747e6dSmrg	if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE;
5683e747e6dSmrg	if (!Scr->HaveFonts) CreateFonts();
5693e747e6dSmrg	CreateGCs();
5703e747e6dSmrg	MakeMenus();
5713e747e6dSmrg
5723e747e6dSmrg	Scr->TitleBarFont.y += Scr->FramePadding;
5733e747e6dSmrg	Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
5743e747e6dSmrg	/* make title height be odd so buttons look nice and centered */
5753e747e6dSmrg	if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
5763e747e6dSmrg
5773e747e6dSmrg	InitTitlebarButtons ();		/* menus are now loaded! */
5783e747e6dSmrg
5793e747e6dSmrg	XGrabServer(dpy);
5803e747e6dSmrg	XSync(dpy, 0);
5813e747e6dSmrg
5823e747e6dSmrg	JunkX = 0;
5833e747e6dSmrg	JunkY = 0;
5843e747e6dSmrg
5853e747e6dSmrg	XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren);
5863e747e6dSmrg	CreateIconManagers();
5873e747e6dSmrg	if (!Scr->NoIconManagers)
5883e747e6dSmrg	    Scr->iconmgr.twm_win->icon = TRUE;
5893e747e6dSmrg
5903e747e6dSmrg	/*
5913e747e6dSmrg	 * weed out icon windows
5923e747e6dSmrg	 */
5933e747e6dSmrg	for (i = 0; i < nchildren; i++) {
5943e747e6dSmrg	    if (children[i]) {
5953e747e6dSmrg		XWMHints *wmhintsp = XGetWMHints (dpy, children[i]);
5963e747e6dSmrg
5973e747e6dSmrg		if (wmhintsp) {
5983e747e6dSmrg		    if (wmhintsp->flags & IconWindowHint) {
5993e747e6dSmrg			for (j = 0; j < nchildren; j++) {
6003e747e6dSmrg			    if (children[j] == wmhintsp->icon_window) {
6013e747e6dSmrg				children[j] = None;
6023e747e6dSmrg				break;
6033e747e6dSmrg			    }
6043e747e6dSmrg			}
6053e747e6dSmrg		    }
6063e747e6dSmrg		    XFree ((char *) wmhintsp);
6073e747e6dSmrg		}
6083e747e6dSmrg	    }
6093e747e6dSmrg	}
6103e747e6dSmrg
6113e747e6dSmrg	/*
6123e747e6dSmrg	 * map all of the non-override windows
6133e747e6dSmrg	 */
6143e747e6dSmrg	for (i = 0; i < nchildren; i++)
6153e747e6dSmrg	{
6163e747e6dSmrg	    if (children[i] && MappedNotOverride(children[i]))
6173e747e6dSmrg	    {
6183e747e6dSmrg		XUnmapWindow(dpy, children[i]);
6193e747e6dSmrg		SimulateMapRequest(children[i]);
6203e747e6dSmrg	    }
6213e747e6dSmrg	}
6223e747e6dSmrg
6233e747e6dSmrg	if (Scr->ShowIconManager && !Scr->NoIconManagers)
6243e747e6dSmrg	{
6253e747e6dSmrg	    Scr->iconmgr.twm_win->icon = FALSE;
6263e747e6dSmrg	    if (Scr->iconmgr.count)
6273e747e6dSmrg	    {
6283e747e6dSmrg		SetMapStateProp (Scr->iconmgr.twm_win, NormalState);
6293e747e6dSmrg		XMapWindow(dpy, Scr->iconmgr.w);
6303e747e6dSmrg		XMapWindow(dpy, Scr->iconmgr.twm_win->frame);
6313e747e6dSmrg	    }
6323e747e6dSmrg	}
6333e747e6dSmrg
6343e747e6dSmrg
6353e747e6dSmrg	attributes.border_pixel = Scr->DefaultC.fore;
6363e747e6dSmrg	attributes.background_pixel = Scr->DefaultC.back;
6373e747e6dSmrg	attributes.event_mask = (ExposureMask | ButtonPressMask |
6383e747e6dSmrg				 KeyPressMask | ButtonReleaseMask);
6393e747e6dSmrg	attributes.backing_store = NotUseful;
6403e747e6dSmrg	attributes.cursor = XCreateFontCursor (dpy, XC_hand2);
6413e747e6dSmrg	valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
6423e747e6dSmrg		     CWBackingStore | CWCursor);
6433e747e6dSmrg	Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
6443e747e6dSmrg					 (unsigned int) 5, (unsigned int) 5,
6453e747e6dSmrg					 (unsigned int) BW, 0,
6463e747e6dSmrg					 (unsigned int) CopyFromParent,
6473e747e6dSmrg					 (Visual *) CopyFromParent,
6483e747e6dSmrg					 valuemask, &attributes);
6493e747e6dSmrg
6503e747e6dSmrg	Scr->SizeStringWidth = MyFont_TextWidth (&Scr->SizeFont,
6513e747e6dSmrg					   " 8888 x 8888 ", 13);
6523e747e6dSmrg	valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
6533e747e6dSmrg	attributes.bit_gravity = NorthWestGravity;
6543e747e6dSmrg	Scr->SizeWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
6553e747e6dSmrg					 (unsigned int) Scr->SizeStringWidth,
6563e747e6dSmrg					 (unsigned int) (Scr->SizeFont.height +
6573e747e6dSmrg							 SIZE_VINDENT*2),
6583e747e6dSmrg					 (unsigned int) BW, 0,
6593e747e6dSmrg					 (unsigned int) CopyFromParent,
6603e747e6dSmrg					 (Visual *) CopyFromParent,
6613e747e6dSmrg					 valuemask, &attributes);
6623e747e6dSmrg
6633e747e6dSmrg	XUngrabServer(dpy);
6643e747e6dSmrg
6653e747e6dSmrg	FirstScreen = FALSE;
6663e747e6dSmrg    	Scr->FirstTime = FALSE;
6673e747e6dSmrg    } /* for */
6683e747e6dSmrg
6693e747e6dSmrg    if (numManaged == 0) {
6703e747e6dSmrg	if (MultiScreen && NumScreens > 0)
6713e747e6dSmrg	  fprintf (stderr, "%s:  unable to find any unmanaged %sscreens.\n",
6723e747e6dSmrg		   ProgramName, NoPrintscreens?"":"video ");
6733e747e6dSmrg	exit (1);
6743e747e6dSmrg    }
6753e747e6dSmrg
6763e747e6dSmrg    (void) ConnectToSessionManager (client_id);
6773e747e6dSmrg
6783e747e6dSmrg    RestartPreviousState = False;
6793e747e6dSmrg    HandlingEvents = TRUE;
6803e747e6dSmrg    InitEvents();
6813e747e6dSmrg    HandleEvents();
6823e747e6dSmrg    exit(0);
6833e747e6dSmrg}
6843e747e6dSmrg
6853e747e6dSmrg/**
6863e747e6dSmrg * initialize twm variables
6873e747e6dSmrg */
6883e747e6dSmrgvoid
6893e747e6dSmrgInitVariables()
6903e747e6dSmrg{
6913e747e6dSmrg    FreeList(&Scr->BorderColorL);
6923e747e6dSmrg    FreeList(&Scr->IconBorderColorL);
6933e747e6dSmrg    FreeList(&Scr->BorderTileForegroundL);
6943e747e6dSmrg    FreeList(&Scr->BorderTileBackgroundL);
6953e747e6dSmrg    FreeList(&Scr->TitleForegroundL);
6963e747e6dSmrg    FreeList(&Scr->TitleBackgroundL);
6973e747e6dSmrg    FreeList(&Scr->IconForegroundL);
6983e747e6dSmrg    FreeList(&Scr->IconBackgroundL);
6993e747e6dSmrg    FreeList(&Scr->IconManagerFL);
7003e747e6dSmrg    FreeList(&Scr->IconManagerBL);
7013e747e6dSmrg    FreeList(&Scr->IconMgrs);
7023e747e6dSmrg    FreeList(&Scr->NoTitle);
7033e747e6dSmrg    FreeList(&Scr->MakeTitle);
7043e747e6dSmrg    FreeList(&Scr->AutoRaise);
7053e747e6dSmrg    FreeList(&Scr->IconNames);
7063e747e6dSmrg    FreeList(&Scr->NoHighlight);
7073e747e6dSmrg    FreeList(&Scr->NoStackModeL);
7083e747e6dSmrg    FreeList(&Scr->NoTitleHighlight);
7093e747e6dSmrg    FreeList(&Scr->DontIconify);
7103e747e6dSmrg    FreeList(&Scr->IconMgrNoShow);
7113e747e6dSmrg    FreeList(&Scr->IconMgrShow);
7123e747e6dSmrg    FreeList(&Scr->IconifyByUn);
7133e747e6dSmrg    FreeList(&Scr->StartIconified);
7143e747e6dSmrg    FreeList(&Scr->IconManagerHighlightL);
7153e747e6dSmrg    FreeList(&Scr->SqueezeTitleL);
7163e747e6dSmrg    FreeList(&Scr->DontSqueezeTitleL);
7173e747e6dSmrg    FreeList(&Scr->WindowRingL);
7183e747e6dSmrg    FreeList(&Scr->WarpCursorL);
7193e747e6dSmrg
7203e747e6dSmrg    NewFontCursor(&Scr->FrameCursor, "top_left_arrow");
7213e747e6dSmrg    NewFontCursor(&Scr->TitleCursor, "top_left_arrow");
7223e747e6dSmrg    NewFontCursor(&Scr->IconCursor, "top_left_arrow");
7233e747e6dSmrg    NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow");
7243e747e6dSmrg    NewFontCursor(&Scr->MoveCursor, "fleur");
7253e747e6dSmrg    NewFontCursor(&Scr->ResizeCursor, "fleur");
7263e747e6dSmrg    NewFontCursor(&Scr->MenuCursor, "sb_left_arrow");
7273e747e6dSmrg    NewFontCursor(&Scr->ButtonCursor, "hand2");
7283e747e6dSmrg    NewFontCursor(&Scr->WaitCursor, "watch");
7293e747e6dSmrg    NewFontCursor(&Scr->SelectCursor, "dot");
7303e747e6dSmrg    NewFontCursor(&Scr->DestroyCursor, "pirate");
7313e747e6dSmrg
7323e747e6dSmrg    Scr->Ring = NULL;
7333e747e6dSmrg    Scr->RingLeader = NULL;
7343e747e6dSmrg
7353e747e6dSmrg    Scr->DefaultC.fore = black;
7363e747e6dSmrg    Scr->DefaultC.back = white;
7373e747e6dSmrg    Scr->BorderColor = black;
7383e747e6dSmrg    Scr->BorderTileC.fore = black;
7393e747e6dSmrg    Scr->BorderTileC.back = white;
7403e747e6dSmrg    Scr->TitleC.fore = black;
7413e747e6dSmrg    Scr->TitleC.back = white;
7423e747e6dSmrg    Scr->MenuC.fore = black;
7433e747e6dSmrg    Scr->MenuC.back = white;
7443e747e6dSmrg    Scr->MenuTitleC.fore = black;
7453e747e6dSmrg    Scr->MenuTitleC.back = white;
7463e747e6dSmrg    Scr->MenuShadowColor = black;
7473e747e6dSmrg    Scr->MenuBorderColor = black;
7483e747e6dSmrg    Scr->IconC.fore = black;
7493e747e6dSmrg    Scr->IconC.back = white;
7503e747e6dSmrg    Scr->IconBorderColor = black;
7513e747e6dSmrg    Scr->PointerForeground.pixel = black;
7523e747e6dSmrg    XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c,
7533e747e6dSmrg		&Scr->PointerForeground);
7543e747e6dSmrg    Scr->PointerBackground.pixel = white;
7553e747e6dSmrg    XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c,
7563e747e6dSmrg		&Scr->PointerBackground);
7573e747e6dSmrg    Scr->IconManagerC.fore = black;
7583e747e6dSmrg    Scr->IconManagerC.back = white;
7593e747e6dSmrg    Scr->IconManagerHighlight = black;
7603e747e6dSmrg
7613e747e6dSmrg    Scr->FramePadding = 2;		/* values that look "nice" on */
7623e747e6dSmrg    Scr->TitlePadding = 8;		/* 75 and 100dpi displays */
7633e747e6dSmrg    Scr->ButtonIndent = 1;
7643e747e6dSmrg    Scr->SizeStringOffset = 0;
7653e747e6dSmrg    Scr->BorderWidth = BW;
7663e747e6dSmrg    Scr->IconBorderWidth = BW;
7673e747e6dSmrg    Scr->MenuBorderWidth = BW;
7683e747e6dSmrg    Scr->UnknownWidth = 0;
7693e747e6dSmrg    Scr->UnknownHeight = 0;
7703e747e6dSmrg    Scr->NumAutoRaises = 0;
7713e747e6dSmrg    Scr->NoDefaults = FALSE;
7723e747e6dSmrg    Scr->UsePPosition = PPOS_OFF;
7733e747e6dSmrg    Scr->FocusRoot = TRUE;
7743e747e6dSmrg    Scr->Focus = NULL;
7753e747e6dSmrg    Scr->WarpCursor = FALSE;
7763e747e6dSmrg    Scr->ForceIcon = FALSE;
7773e747e6dSmrg    Scr->NoGrabServer = FALSE;
7783e747e6dSmrg    Scr->NoRaiseMove = FALSE;
7793e747e6dSmrg    Scr->NoRaiseResize = FALSE;
7803e747e6dSmrg    Scr->NoRaiseDeicon = FALSE;
7813e747e6dSmrg    Scr->NoRaiseWarp = FALSE;
7823e747e6dSmrg    Scr->DontMoveOff = FALSE;
7833e747e6dSmrg    Scr->DoZoom = FALSE;
7843e747e6dSmrg    Scr->TitleFocus = TRUE;
7853e747e6dSmrg    Scr->NoTitlebar = FALSE;
7863e747e6dSmrg    Scr->DecorateTransients = FALSE;
7873e747e6dSmrg    Scr->IconifyByUnmapping = FALSE;
7883e747e6dSmrg    Scr->ShowIconManager = FALSE;
7893e747e6dSmrg    Scr->IconManagerDontShow =FALSE;
7903e747e6dSmrg    Scr->BackingStore = TRUE;
7913e747e6dSmrg    Scr->SaveUnder = TRUE;
7923e747e6dSmrg    Scr->RandomPlacement = FALSE;
7933e747e6dSmrg    Scr->OpaqueMove = FALSE;
7943e747e6dSmrg    Scr->Highlight = TRUE;
7953e747e6dSmrg    Scr->StackMode = TRUE;
7963e747e6dSmrg    Scr->TitleHighlight = TRUE;
7973e747e6dSmrg    Scr->MoveDelta = 1;		/* so that f.deltastop will work */
7983e747e6dSmrg    Scr->ZoomCount = 8;
7993e747e6dSmrg    Scr->SortIconMgr = FALSE;
8003e747e6dSmrg    Scr->Shadow = TRUE;
8013e747e6dSmrg    Scr->InterpolateMenuColors = FALSE;
8023e747e6dSmrg    Scr->NoIconManagers = FALSE;
8033e747e6dSmrg    Scr->ClientBorderWidth = FALSE;
8043e747e6dSmrg    Scr->SqueezeTitle = -1;
8053e747e6dSmrg    Scr->FirstRegion = NULL;
8063e747e6dSmrg    Scr->LastRegion = NULL;
8073e747e6dSmrg    Scr->FirstTime = TRUE;
8083e747e6dSmrg    Scr->HaveFonts = FALSE;		/* i.e. not loaded yet */
8093e747e6dSmrg    Scr->CaseSensitive = TRUE;
8103e747e6dSmrg    Scr->WarpUnmapped = FALSE;
8113e747e6dSmrg
8123e747e6dSmrg    /* setup default fonts; overridden by defaults from system.twmrc */
8133e747e6dSmrg#define DEFAULT_NICE_FONT "variable"
8143e747e6dSmrg#define DEFAULT_FAST_FONT "fixed"
8153e747e6dSmrg
8163e747e6dSmrg    Scr->TitleBarFont.font = NULL;
8173e747e6dSmrg    Scr->TitleBarFont.fontset = NULL;
8183e747e6dSmrg    Scr->TitleBarFont.name = DEFAULT_NICE_FONT;
8193e747e6dSmrg    Scr->MenuFont.font = NULL;
8203e747e6dSmrg    Scr->MenuFont.fontset = NULL;
8213e747e6dSmrg    Scr->MenuFont.name = DEFAULT_NICE_FONT;
8223e747e6dSmrg    Scr->IconFont.font = NULL;
8233e747e6dSmrg    Scr->IconFont.fontset = NULL;
8243e747e6dSmrg    Scr->IconFont.name = DEFAULT_NICE_FONT;
8253e747e6dSmrg    Scr->SizeFont.font = NULL;
8263e747e6dSmrg    Scr->SizeFont.fontset = NULL;
8273e747e6dSmrg    Scr->SizeFont.name = DEFAULT_FAST_FONT;
8283e747e6dSmrg    Scr->IconManagerFont.font = NULL;
8293e747e6dSmrg    Scr->IconManagerFont.fontset = NULL;
8303e747e6dSmrg    Scr->IconManagerFont.name = DEFAULT_NICE_FONT;
8313e747e6dSmrg    Scr->DefaultFont.font = NULL;
8323e747e6dSmrg    Scr->DefaultFont.fontset = NULL;
8333e747e6dSmrg    Scr->DefaultFont.name = DEFAULT_FAST_FONT;
8343e747e6dSmrg
8353e747e6dSmrg}
8363e747e6dSmrg
8373e747e6dSmrgvoid
8383e747e6dSmrgCreateFonts ()
8393e747e6dSmrg{
8403e747e6dSmrg    GetFont(&Scr->TitleBarFont);
8413e747e6dSmrg    GetFont(&Scr->MenuFont);
8423e747e6dSmrg    GetFont(&Scr->IconFont);
8433e747e6dSmrg    GetFont(&Scr->SizeFont);
8443e747e6dSmrg    GetFont(&Scr->IconManagerFont);
8453e747e6dSmrg    GetFont(&Scr->DefaultFont);
8463e747e6dSmrg    Scr->HaveFonts = TRUE;
8473e747e6dSmrg}
8483e747e6dSmrg
8493e747e6dSmrgvoid
8503e747e6dSmrgRestoreWithdrawnLocation (TwmWindow *tmp)
8513e747e6dSmrg{
8523e747e6dSmrg    int gravx, gravy;
8533e747e6dSmrg    unsigned int bw, mask;
8543e747e6dSmrg    XWindowChanges xwc;
8553e747e6dSmrg
8563e747e6dSmrg    if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y,
8573e747e6dSmrg		      &JunkWidth, &JunkHeight, &bw, &JunkDepth)) {
8583e747e6dSmrg
8593e747e6dSmrg	GetGravityOffsets (tmp, &gravx, &gravy);
8603e747e6dSmrg	if (gravy < 0) xwc.y -= tmp->title_height;
8613e747e6dSmrg
8623e747e6dSmrg	if (bw != tmp->old_bw) {
8633e747e6dSmrg	    int xoff, yoff;
8643e747e6dSmrg
8653e747e6dSmrg	    if (!Scr->ClientBorderWidth) {
8663e747e6dSmrg		xoff = gravx;
8673e747e6dSmrg		yoff = gravy;
8683e747e6dSmrg	    } else {
8693e747e6dSmrg		xoff = 0;
8703e747e6dSmrg		yoff = 0;
8713e747e6dSmrg	    }
8723e747e6dSmrg
8733e747e6dSmrg	    xwc.x -= (xoff + 1) * tmp->old_bw;
8743e747e6dSmrg	    xwc.y -= (yoff + 1) * tmp->old_bw;
8753e747e6dSmrg	}
8763e747e6dSmrg	if (!Scr->ClientBorderWidth) {
8773e747e6dSmrg	    xwc.x += gravx * tmp->frame_bw;
8783e747e6dSmrg	    xwc.y += gravy * tmp->frame_bw;
8793e747e6dSmrg	}
8803e747e6dSmrg
8813e747e6dSmrg	mask = (CWX | CWY);
8823e747e6dSmrg	if (bw != tmp->old_bw) {
8833e747e6dSmrg	    xwc.border_width = tmp->old_bw;
8843e747e6dSmrg	    mask |= CWBorderWidth;
8853e747e6dSmrg	}
8863e747e6dSmrg
8873e747e6dSmrg	XConfigureWindow (dpy, tmp->w, mask, &xwc);
8883e747e6dSmrg
8893e747e6dSmrg	if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) {
8903e747e6dSmrg	    XUnmapWindow (dpy, tmp->wmhints->icon_window);
8913e747e6dSmrg	}
8923e747e6dSmrg
8933e747e6dSmrg    }
8943e747e6dSmrg}
8953e747e6dSmrg
8963e747e6dSmrg
8973e747e6dSmrgvoid
8983e747e6dSmrgReborder (Time time)
8993e747e6dSmrg{
9003e747e6dSmrg    TwmWindow *tmp;			/* temp twm window structure */
9013e747e6dSmrg    int scrnum;
9023e747e6dSmrg
9033e747e6dSmrg    /* put a border back around all windows */
9043e747e6dSmrg
9053e747e6dSmrg    XGrabServer (dpy);
9063e747e6dSmrg    for (scrnum = 0; scrnum < NumScreens; scrnum++)
9073e747e6dSmrg    {
9083e747e6dSmrg	if ((Scr = ScreenList[scrnum]) == NULL)
9093e747e6dSmrg	    continue;
9103e747e6dSmrg
9113e747e6dSmrg	InstallWindowColormaps (0, &Scr->TwmRoot);	/* force reinstall */
9123e747e6dSmrg	for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
9133e747e6dSmrg	{
9143e747e6dSmrg	    RestoreWithdrawnLocation (tmp);
9153e747e6dSmrg	    XMapWindow (dpy, tmp->w);
9163e747e6dSmrg	}
9173e747e6dSmrg    }
9183e747e6dSmrg
9193e747e6dSmrg    XUngrabServer (dpy);
9203e747e6dSmrg    SetFocus ((TwmWindow*)NULL, time);
9213e747e6dSmrg}
9223e747e6dSmrg
9233e747e6dSmrgstatic SIGNAL_T
9243e747e6dSmrgsigHandler(int sig)
9253e747e6dSmrg{
9263e747e6dSmrg    XtNoticeSignal(si);
9273e747e6dSmrg    SIGNAL_RETURN;
9283e747e6dSmrg}
9293e747e6dSmrg
9303e747e6dSmrg/**
9313e747e6dSmrg * cleanup and exit twm
9323e747e6dSmrg */
9333e747e6dSmrgvoid
9343e747e6dSmrgDone(XtPointer client_data, XtSignalId *si)
9353e747e6dSmrg{
9363e747e6dSmrg    if (dpy)
9373e747e6dSmrg    {
9383e747e6dSmrg	Reborder(CurrentTime);
9393e747e6dSmrg	XCloseDisplay(dpy);
9403e747e6dSmrg    }
9413e747e6dSmrg    exit(0);
9423e747e6dSmrg}
9433e747e6dSmrg
9443e747e6dSmrg
9453e747e6dSmrg/*
9463e747e6dSmrg * Error Handlers.  If a client dies, we'll get a BadWindow error (except for
9473e747e6dSmrg * GetGeometry which returns BadDrawable) for most operations that we do before
9483e747e6dSmrg * manipulating the client's window.
9493e747e6dSmrg */
9503e747e6dSmrg
9513e747e6dSmrgBool ErrorOccurred = False;
9523e747e6dSmrgXErrorEvent LastErrorEvent;
9533e747e6dSmrg
9543e747e6dSmrgstatic int
9553e747e6dSmrgTwmErrorHandler(Display *dpy, XErrorEvent *event)
9563e747e6dSmrg{
9573e747e6dSmrg    LastErrorEvent = *event;
9583e747e6dSmrg    ErrorOccurred = True;
9593e747e6dSmrg
9603e747e6dSmrg    if (PrintErrorMessages && 			/* don't be too obnoxious */
9613e747e6dSmrg	event->error_code != BadWindow &&	/* watch for dead puppies */
9623e747e6dSmrg	(event->request_code != X_GetGeometry &&	 /* of all styles */
9633e747e6dSmrg	 event->error_code != BadDrawable))
9643e747e6dSmrg      XmuPrintDefaultErrorMessage (dpy, event, stderr);
9653e747e6dSmrg    return 0;
9663e747e6dSmrg}
9673e747e6dSmrg
9683e747e6dSmrg
9693e747e6dSmrgstatic int
9703e747e6dSmrgCatchRedirectError(Display *dpy, XErrorEvent *event)
9713e747e6dSmrg{
9723e747e6dSmrg    RedirectError = TRUE;
9733e747e6dSmrg    LastErrorEvent = *event;
9743e747e6dSmrg    ErrorOccurred = True;
9753e747e6dSmrg    return 0;
9763e747e6dSmrg}
977