/*****************************************************************************/
/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
/**                          Salt Lake City, Utah                           **/
/**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
/**                        Cambridge, Massachusetts                         **/
/**                                                                         **/
/**                           All Rights Reserved                           **/
/**                                                                         **/
/**    Permission to use, copy, modify, and distribute this software and    **/
/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
/**    granted, provided that the above copyright notice appear  in  all    **/
/**    copies and that both  that  copyright  notice  and  this  permis-    **/
/**    sion  notice appear in supporting  documentation,  and  that  the    **/
/**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
/**    in publicity pertaining to distribution of the  software  without    **/
/**    specific, written prior permission.                                  **/
/**                                                                         **/
/**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
/**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
/*****************************************************************************/


/***********************************************************************
 *
 * $XConsortium: twm.c,v 1.124 91/05/08 11:01:54 dave Exp $
 *
 * twm - "Tom's Window Manager"
 *
 * 27-Oct-87 Thomas E. LaStrange	File created
 * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
 ***********************************************************************/

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> /* for sleep() */
#include <signal.h>
#include <fcntl.h>
#include "twm.h"
#include "add_window.h"
#include "gc.h"
#include "parse.h"
#include "version.h"
#include "menus.h"
#include "events.h"
#include "util.h"
#include "gram.h"
#include "screen.h"
#include "iconmgr.h"
#include "desktop.h"
/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
#include "sound.h"
#endif
#include <X11/Xresource.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Xmu/Error.h>
/* djhjr - 9/14/03 */
#ifndef NO_I18N_SUPPORT
#include <X11/Xlocale.h>
#endif

Display *dpy;			/* which display are we talking to */
Window ResizeWindow;		/* the window we are resizing */

int MultiScreen = TRUE;		/* try for more than one screen? */
int NumScreens;			/* number of screens in ScreenList */
int HasShape;			/* server supports shape extension? */
int ShapeEventBase, ShapeErrorBase;
ScreenInfo **ScreenList;	/* structures for each screen */
ScreenInfo *Scr = NULL;		/* the cur and prev screens */
int PreviousScreen;		/* last screen that we were on */
int FirstScreen;		/* TRUE ==> first screen of display */
Bool PrintPID = False;		/* controls PID file - djhjr - 12/2/01 */
Bool PrintErrorMessages = False;	/* controls error messages */
static int RedirectError;	/* TRUE ==> another window manager running */
static int CatchRedirectError();	/* for settting RedirectError */
static int TwmErrorHandler();	/* for everything else */
void InitVariables();
void InternUsefulAtoms();

char Info[INFO_LINES][INFO_SIZE];		/* info strings to print */
int InfoLines;

char *InitFile = NULL;
int parseInitFile = TRUE;	/* djhjr - 10/7/02 */

Cursor UpperLeftCursor;		/* upper Left corner cursor */
Cursor RightButt;
Cursor MiddleButt;
Cursor LeftButt;

XContext TwmContext;		/* context for twm windows */
XContext MenuContext;		/* context for all menu windows */
XContext IconManagerContext;	/* context for all window list windows */
XContext VirtualContext;	/* context for all desktop display windows */
XContext ScreenContext;		/* context to get screen data */
XContext ColormapContext;	/* context for colormap operations */
XContext DoorContext;		/* context for doors */

XClassHint NoClass;		/* for applications with no class */

XGCValues Gcv;

char *Home;			/* the HOME environment variable */
int HomeLen;			/* length of Home */
int ParseError;			/* error parsing the .twmrc file */

int HandlingEvents = FALSE;	/* are we handling events yet? */

Window JunkRoot;		/* junk window */
Window JunkChild;		/* junk window */
int JunkX;			/* junk variable */
int JunkY;			/* junk variable */
unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;

char *ProgramName, *PidName = "vtwm.pid"; /* PID file - djhjr - 12/2/01 */
int Argc;
char **Argv;
char **Environ;

Bool RestartPreviousState = False;	/* try to restart in previous state */

unsigned long black, white;

/* djhjr - 9/14/03 */
#ifndef NO_I18N_SUPPORT
Bool use_fontset;
#endif

extern void assign_var_savecolor();

/* djhjr - 4/26/99 */
extern void FreeRegions();

/***********************************************************************
 *
 *  Procedure:
 *	main - start of twm
 *
 ***********************************************************************
 */

/* Changes for m4 pre-processing submitted by Jason Gloudon */
int
main(argc, argv, environ)
    int argc;
    char **argv;
    char **environ;
{
    Window root, parent, *children;
    unsigned int nchildren;
    int i, j;
    char *def, *display_name = NULL;
    unsigned long valuemask;	/* mask for create windows */
    XSetWindowAttributes attributes;	/* attributes for create windows */
    int numManaged, firstscrn, lastscrn, scrnum;
    extern ColormapWindow *CreateColormapWindow();
#ifndef NO_M4_SUPPORT
    int m4_preprocess = False;	/* filter the *twmrc file through m4 */
    char *m4_option = NULL; /* pass these options to m4 - djhjr - 2/20/98 */
#endif
/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
    int sound_state = 0;
#endif
    extern char *defTwmrc[];	/* djhjr - 10/7/02 */
/* djhjr - 9/14/03 */
#ifndef NO_I18N_SUPPORT
    char *loc;
#endif

    /* djhjr - 7/21/98 */
    SIGNAL_T QueueRestartVtwm();
    
	if ((ProgramName = strrchr(argv[0], '/')))
		ProgramName++;
	else
		ProgramName = argv[0];
    Argc = argc;
    Argv = argv;
    Environ = environ;

    for (i = 1; i < argc; i++) {
	if (argv[i][0] == '-') {
	    switch (argv[i][1]) {
	      case 'd':				/* -display display */
		if (++i >= argc) goto usage;
		display_name = argv[i];
		continue;
	      case 'f':				/* -file [initfile] */
		/* this isn't really right, but hey... - djhjr - 10/7/02 */
		if (i + 1 < argc &&
				(argv[i + 1][0] != '-' ||
				(argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1]))))
			InitFile = argv[++i];
		else
			parseInitFile = FALSE;
		continue;
#ifndef NO_M4_SUPPORT
	      case 'm':				/* -m4 [options] */
		m4_preprocess = True;
		/* this isn't really right, but hey... - djhjr - 2/20/98 */
		if (i + 1 < argc &&
				(argv[i + 1][0] != '-' ||
				(argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1]))))
			m4_option = argv[++i];
		continue;
#endif
	      case 'p':				/* -pidfile - djhjr - 12/2/01 */
		PrintPID = True;
		continue;
	      case 's':				/* -single */
		MultiScreen = FALSE;
		continue;
	      case 'v':				/* -verbose */
		PrintErrorMessages = True;
		continue;
#ifdef NEVER /* djhjr - 2/20/99 */
	      case 'q':				/* -quiet */
		PrintErrorMessages = False;
		continue;
#endif
	    }
	}
      usage:
	fprintf (stderr,
#ifndef NO_M4_SUPPORT
		 "usage:  %s [-d display] [-f [initfile]] [-m [options]] [-p] [-s] [-v]\n",
#else
		 "usage:  %s [-d display] [-f [initfile]] [-p] [-s] [-v]\n",
#endif
		 ProgramName);
	exit (1);
    }

/* djhjr - 9/14/03 */
#ifndef NO_I18N_SUPPORT
    loc = setlocale(LC_ALL, "");
    if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") ||
		!XSupportsLocale())
	use_fontset = False;
    else
	use_fontset = True;

    if (PrintErrorMessages)
	fprintf(stderr, "%s: I18N supported, L10N %sabled\n",
		ProgramName, (use_fontset) ? "en" : "dis");
#endif

/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
#define sounddonehandler(sig) \
    if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, PlaySoundDone)
#else
#define sounddonehandler(sig) \
    if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
#endif
#define donehandler(sig) \
    if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)

    sounddonehandler (SIGINT);
    sounddonehandler (SIGHUP);
    sounddonehandler (SIGQUIT);
    sounddonehandler (SIGTERM);

    /* djhjr - 12/2/01 */
    donehandler (SIGABRT);
    donehandler (SIGFPE);
    donehandler (SIGSEGV);
    donehandler (SIGILL);
    donehandler (SIGTSTP);
    donehandler (SIGPIPE);
#undef sounddonehandler
#undef donehandler

    /* djhjr - 7/31/98 */
    signal (SIGUSR1, QueueRestartVtwm);

    Home = getenv("HOME");
    if (Home == NULL)
	Home = "./";

    HomeLen = strlen(Home);

    NoClass.res_name = NoName;
    NoClass.res_class = NoName;

    if (!(dpy = XOpenDisplay(display_name))) {
	fprintf (stderr, "%s:  unable to open display \"%s\"\n",
		 ProgramName, XDisplayName(display_name));
	exit (1);
    }

    if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) {
	fprintf (stderr,
		 "%s:  unable to mark display connection as close-on-exec\n",
		 ProgramName);
	exit (1);
    }

    HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase);
    TwmContext = XUniqueContext();
    MenuContext = XUniqueContext();
    IconManagerContext = XUniqueContext();
    VirtualContext = XUniqueContext();
    ScreenContext = XUniqueContext();
    ColormapContext = XUniqueContext();
    DoorContext = XUniqueContext();

    InternUsefulAtoms ();


    /* Set up the per-screen global information. */

    NumScreens = ScreenCount(dpy);

    if (MultiScreen)
    {
	firstscrn = 0;
	lastscrn = NumScreens - 1;
    }
    else
    {
	firstscrn = lastscrn = DefaultScreen(dpy);
    }

    InfoLines = 0;

    /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */
    ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *));
    if (ScreenList == NULL)
    {
	fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
		 ProgramName);
	exit (1);
    }
    numManaged = 0;
    PreviousScreen = DefaultScreen(dpy);
    FirstScreen = TRUE;
    for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++)
    {
        /* Make sure property priority colors is empty */
        XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS,
			 XA_CARDINAL, 32, PropModeReplace, NULL, 0);
	RedirectError = FALSE;
	XSetErrorHandler(CatchRedirectError);
	XSelectInput(dpy, RootWindow (dpy, scrnum),
	    ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
	    SubstructureRedirectMask | KeyPressMask |
	    ButtonPressMask | ButtonReleaseMask);
	XSync(dpy, 0);
	XSetErrorHandler(TwmErrorHandler);

	if (RedirectError)
	{
	    fprintf (stderr, "%s:  another window manager is already running",
		     ProgramName);
	    if (MultiScreen && NumScreens > 0)
		fprintf(stderr, " on screen %d?\n", scrnum);
	    else
		fprintf(stderr, "?\n");
	    continue;
	}

	numManaged ++;

	/* Note:  ScreenInfo struct is calloc'ed to initialize to zero. */
	Scr = ScreenList[scrnum] =
	    (ScreenInfo *) calloc(1, sizeof(ScreenInfo));
  	if (Scr == NULL)
  	{
  	    fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n",
  		     ProgramName, scrnum);
  	    continue;
  	}

	/* initialize list pointers, remember to put an initialization
	 * in InitVariables also
	 */
	Scr->BorderColorL = NULL;
	Scr->IconBorderColorL = NULL;
	Scr->BorderTileForegroundL = NULL;
	Scr->BorderTileBackgroundL = NULL;
	Scr->TitleForegroundL = NULL;
	Scr->TitleBackgroundL = NULL;
	Scr->IconForegroundL = NULL;
	Scr->IconBackgroundL = NULL;
	Scr->NoTitle = NULL;
	Scr->MakeTitle = NULL;
	Scr->AutoRaise = NULL;
	Scr->IconNames = NULL;
	Scr->NoHighlight = NULL;
	Scr->NoStackModeL = NULL;
	Scr->NoTitleHighlight = NULL;
	Scr->DontIconify = NULL;
	Scr->IconMgrNoShow = NULL;
	Scr->IconMgrShow = NULL;
	Scr->IconifyByUn = NULL;
	Scr->IconManagerFL = NULL;
	Scr->IconManagerBL = NULL;
	Scr->IconMgrs = NULL;
	Scr->StartIconified = NULL;
	Scr->SqueezeTitleL = NULL;
	Scr->DontSqueezeTitleL = NULL;
	Scr->WindowRingL = NULL;

	/* submitted by Jonathan Paisley - 10/27/02 */
	Scr->NoWindowRingL = NULL;

	Scr->WarpCursorL = NULL;

	/* djhjr - 4/22/96 */
	Scr->ImageCache = NULL;

	/* djhjr - 4/7/98 */
	Scr->OpaqueMoveL = NULL;
	Scr->NoOpaqueMoveL = NULL;
	Scr->OpaqueResizeL = NULL;
	Scr->NoOpaqueResizeL = NULL;

	/* djhjr - 5/2/98 */
	Scr->NoBorder = NULL;

	/* djhjr - 9/24/02 */
	Scr->UsePPositionL = NULL;

	/* remember to put an initialization in InitVariables also
	 */

	Scr->screen = scrnum;
	Scr->d_depth = DefaultDepth(dpy, scrnum);
	Scr->d_visual = DefaultVisual(dpy, scrnum);
	Scr->Root = RootWindow(dpy, scrnum);
	XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr);

	/* djhjr - 1/31/99 */
	if ((def = XGetDefault(dpy, "*", "bitmapFilePath")))
		Scr->BitmapFilePath = strdup(def);
	else
		Scr->BitmapFilePath = NULL;

	Scr->TwmRoot.cmaps.number_cwins = 1;
	Scr->TwmRoot.cmaps.cwins =
		(ColormapWindow **) malloc(sizeof(ColormapWindow *));
	Scr->TwmRoot.cmaps.cwins[0] =
		CreateColormapWindow(Scr->Root, True, False);
	Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured;

	Scr->cmapInfo.cmaps = NULL;
	Scr->cmapInfo.maxCmaps =
		MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen));
	Scr->cmapInfo.root_pushes = 0;
	InstallWindowColormaps(0, &Scr->TwmRoot);

	Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail =
	  Scr->StdCmapInfo.mru = NULL;
	Scr->StdCmapInfo.mruindex = 0;
	LocateStandardColormaps();

	Scr->TBInfo.nleft = Scr->TBInfo.nright = 0;
	Scr->TBInfo.head = NULL;

/* djhjr - 4/19/96
	Scr->TBInfo.border = 1;
*/
	Scr->TBInfo.border = -100;

	Scr->TBInfo.width = 0;
	Scr->TBInfo.leftx = 0;
	Scr->TBInfo.titlex = 0;

	Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum);
	Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum);
	Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth;
	Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight;

	Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;

	if (DisplayCells(dpy, scrnum) < 3)
	    Scr->Monochrome = MONOCHROME;
	else
	    Scr->Monochrome = COLOR;

	/* setup default colors */
	Scr->FirstTime = TRUE;
	GetColor(Scr->Monochrome, &black, "black");
	Scr->Black = black;
	GetColor(Scr->Monochrome, &white, "white");
	Scr->White = white;

	if (FirstScreen)
	{
	    SetFocus ((TwmWindow *)NULL, CurrentTime);

	    /* define cursors */

	    NewFontCursor(&UpperLeftCursor, "top_left_corner");
	    NewFontCursor(&RightButt, "rightbutton");
	    NewFontCursor(&LeftButt, "leftbutton");
	    NewFontCursor(&MiddleButt, "middlebutton");
	}

	Scr->iconmgr.x = 0;
	Scr->iconmgr.y = 0;
	Scr->iconmgr.width = 150;
	Scr->iconmgr.height = 5;
	Scr->iconmgr.next = NULL;
	Scr->iconmgr.prev = NULL;
	Scr->iconmgr.lasti = &(Scr->iconmgr);
	Scr->iconmgr.first = NULL;
	Scr->iconmgr.last = NULL;
	Scr->iconmgr.active = NULL;
	Scr->iconmgr.scr = Scr;
	Scr->iconmgr.columns = 1;
	Scr->iconmgr.count = 0;
	Scr->iconmgr.name = "VTWM";
	Scr->iconmgr.icon_name = "Icons";

	Scr->IconDirectory = NULL;

	/* djhjr - 10/30/02 */
	Scr->hiliteName = NULL;
	Scr->menuIconName = TBPM_MENU;
	Scr->iconMgrIconName = TBPM_XLOGO;

/* djhjr - 10/30/02
	Scr->siconifyPm = NULL;
	Scr->pullPm = NULL;
*/

/* djhjr - 5/17/98 */
#ifdef ORIGINAL_PIXMAPS
	Scr->hilitePm = None;
	Scr->virtualPm = None; /* RFB PIXMAP */
	Scr->RealScreenPm = None; /* RFB PIXMAP */
#else /* ORIGINAL_PIXMAPS */
	/* djhjr - 10/25/02 */
	Scr->hiliteName = NULL;

	Scr->hilitePm = NULL;
	Scr->virtualPm = NULL;
	Scr->realscreenPm = NULL;
#endif /* ORIGINAL_PIXMAPS */

	if ( Scr->FirstTime )
	{	/* retain max size on restart. */
		Scr->VirtualDesktopMaxWidth = 0;
		Scr->VirtualDesktopMaxHeight = 0;
	}

	InitVariables();
	InitMenus();

	/* added this 'if (...) else' - djhjr - 10/7/02 */
	if (!parseInitFile)
		ParseStringList(defTwmrc);
	else
	{
		/* Parse it once for each screen. */
#ifndef NO_M4_SUPPORT
		/* added 'm4_option' - djhjr - 2/20/99 */
		ParseTwmrc(InitFile, display_name, m4_preprocess, m4_option);
#else
		ParseTwmrc(InitFile);
#endif
	}

/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
	OpenSound();

	if (PlaySound(S_START))
	{
		/*
		 * Save setting from resource file, and turn sound off
		 */
		sound_state = ToggleSounds();
		sound_state ^= 1;
		if (sound_state == 0) ToggleSounds();
	}
#endif

	assign_var_savecolor(); /* storeing pixels for twmrc "entities" */

/* djhjr - 10/17/02 */
#if 0
	/* djhjr - 4/19/96 */
	/* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
	if (Scr->TitleBevelWidth > 0) {
/* djhjr - 10/17/02
	    if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 0;
*/

/* djhjr - 3/12/97
	    if (Scr->ButtonIndent  == -100) Scr->ButtonIndent  = 0;
	    if (Scr->FramePadding  == -100) Scr->FramePadding  = 0;
	    if (Scr->TitlePadding  == -100) Scr->TitlePadding  = 0;
*/
	    Scr->ButtonIndent  = 0;
	    Scr->FramePadding  = 0;
	    Scr->TitlePadding  = 0;

/* djhjr - 4/3/98
		* djhjr - 4/26/96 *
		if (Scr->SunkFocusWindowTitle) Scr->TitleHighlight = FALSE;
*/
	}
	else {
		/* djhjr - 4/5/98 */
		Scr->SunkFocusWindowTitle = FALSE;
	}
#endif

	/* was only if Scr->TitleBevelWidth == 0 - djhjr - 10/17/02 */
	if (Scr->FramePadding  == -100) Scr->FramePadding  = 2; /* values that look */
	if (Scr->TitlePadding  == -100) Scr->TitlePadding  = 8; /* "nice" on */
	if (Scr->ButtonIndent  == -100) Scr->ButtonIndent  = 1; /* 75 and 100dpi displays */
	if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 1;

	/* was 'Scr->use3D*' - djhjr - 8/11/98 */
	/* rem'd 'Scr->*BevelWidth > 0' - djhjr - 10/30/02 */
	if (/*Scr->TitleBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->TitleC);
	if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuC);
	if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuTitleC);
	if (Scr->BorderBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->BorderColorC);

	/* djhjr - 2/7/99 */
	if (Scr->DoorBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->DoorC);
	if (Scr->VirtualDesktopBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->VirtualC);

/* djhjr - 8/11/98
	* was 'Scr->use3Dborders' - djhjr - 8/11/98 *
	if (Scr->BorderBevelWidth == 0)
		Scr->ThreeDBorderWidth = 0;
	else
*/
	{
/* djhjr - 8/11/98
		* djhjr - 4/29/98 *
		if (2 * Scr->BorderBevelWidth > Scr->ThreeDBorderWidth)
			Scr->ThreeDBorderWidth = 2 * Scr->BorderBevelWidth;
*/
		if (2 * Scr->BorderBevelWidth > Scr->BorderWidth)
			Scr->BorderWidth = 2 * Scr->BorderBevelWidth;

    	if (!Scr->BeNiceToColormap)
			GetShadeColors(&Scr->DefaultC);
	}

	/* djhjr - 5/5/98 */
	/* was 'Scr->use3Dicons' - djhjr - 8/11/98 */
	if (Scr->IconBevelWidth > 0)
		Scr->IconBorderWidth = 0;

	if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE;
	if (!Scr->HaveFonts) CreateFonts();
	CreateGCs();
	MakeMenus();

/* djhjr - 10/18/02 */
#if 0
	/*
	 * Set titlebar height from font height and padding,
	 * then adjust to titlebutton height - djhjr - 12/10/98
	 */
	Scr->TitleBarFont.y += Scr->FramePadding;
	i = Scr->TitleBarFont.height;
	do
	{
		Scr->TitleBarFont.y += (i - Scr->TitleBarFont.height) / 2;
		Scr->TitleHeight = i + Scr->FramePadding * 2;

/* djhjr - 4/29/98
		* djhjr - 4/19/96 *
		if (Scr->use3Dtitles) Scr->TitleHeight += 4;
*/
/* djhjr - 10/18/02
		* was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
		if (Scr->TitleBevelWidth > 0)
			Scr->TitleHeight += 2 * Scr->TitleBevelWidth + 2;
*/

		/* make title height be odd so buttons look nice and centered */
		if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
	} while ((i = InitTitlebarButtons()) > Scr->TitleHeight - Scr->FramePadding * 2);
#else
	/* set titlebar height to font height plus frame padding */
	Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
	if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;

	i = InitTitlebarButtons();	/* returns the button height */
	
 	/* adjust titlebar height to button height */
	if (i > Scr->TitleHeight) Scr->TitleHeight = i + Scr->FramePadding * 2;
	if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;

	/* adjust font baseline */
	Scr->TitleBarFont.y += ((Scr->TitleHeight - Scr->TitleBarFont.height) / 2);
#endif

	XGrabServer(dpy);
	XSync(dpy, 0);

	JunkX = 0;
	JunkY = 0;

	XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren);
	CreateIconManagers();
	if (!Scr->NoIconManagers)
	    Scr->iconmgr.twm_win->icon = TRUE;

 	if (Scr->VirtualDesktopWidth > 0)
 		CreateDesktopDisplay();

	/* create all of the door windows */
	door_open_all();

	/*
	 * weed out icon windows
	 */
	for (i = 0; i < nchildren; i++) {
	    if (children[i]) {
		XWMHints *wmhintsp = XGetWMHints (dpy, children[i]);

		if (wmhintsp) {
		    if (wmhintsp->flags & IconWindowHint) {
			for (j = 0; j < nchildren; j++) {
			    if (children[j] == wmhintsp->icon_window) {
				children[j] = None;
				break;
			    }
			}
		    }
		    XFree ((char *) wmhintsp);
		}
	    }
	}

	/*
	 * map all of the non-override windows
	 */
	for (i = 0; i < nchildren; i++)
	{
	    if (children[i] && MappedNotOverride(children[i]))
	    {
		XUnmapWindow(dpy, children[i]);
		SimulateMapRequest(children[i]);
	    }
	}

	if (Scr->ShowIconManager && !Scr->NoIconManagers)
	{
	    Scr->iconmgr.twm_win->icon = FALSE;
	    if (Scr->iconmgr.count)
	    {
		SetMapStateProp (Scr->iconmgr.twm_win, NormalState);
		XMapWindow(dpy, Scr->iconmgr.w);
		XMapWindow(dpy, Scr->iconmgr.twm_win->frame);
	    }
	}

	/* djhjr - 5/9/96 */
	/* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
	if (!Scr->BorderBevelWidth > 0)
		attributes.border_pixel = Scr->DefaultC.fore;

	attributes.background_pixel = Scr->DefaultC.back;
	attributes.event_mask = (ExposureMask | ButtonPressMask |
				 KeyPressMask | ButtonReleaseMask);
	attributes.backing_store = NotUseful;

#ifdef ORIGINAL_INFOCURSOR
	attributes.cursor = XCreateFontCursor (dpy, Scr->WaitCursor);

	/* djhjr - 5/9/96 */
	/* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
	if (!Scr->BorderBevelWidth > 0)
		valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
			     CWBackingStore | CWCursor);
	else
		valuemask = (CWBackPixel | CWEventMask | CWBackingStore | CWCursor);
#else

	/* djhjr - 5/9/96 */
	/* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
	if (!Scr->BorderBevelWidth > 0)
		valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
			     CWBackingStore);
	else
		valuemask = (CWBackPixel | CWEventMask | CWBackingStore);
#endif

	Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
					 (unsigned int) 5, (unsigned int) 5,

					 /* djhjr - 5/9/96 */
					 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
					 (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0,

					 (unsigned int) CopyFromParent,
					 (Visual *) CopyFromParent,
					 valuemask, &attributes);

/* djhjr - 9/14/03 */
#ifndef NO_I18N_SUPPORT
	Scr->SizeStringWidth = MyFont_TextWidth (&Scr->SizeFont,
#else
	Scr->SizeStringWidth = XTextWidth (Scr->SizeFont.font,
#endif
/* djhjr - 5/9/96
					   " 8888 x 8888 ", 13);
*/
/* djhjr - 4/29/98
					   "nnnnnnnnnnnnn", 13);
*/
					   /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
					   "nnnnnnnnnnnnn", 13) + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0);

	/* djhjr - 5/9/96 */
	/* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
	if (!Scr->InfoBevelWidth > 0)
		valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
	else
		valuemask = (CWBackPixel | CWBitGravity);

	/* djhjr - 5/15/96 */
	switch (Scr->ResizeX)
	{
		case R_NORTHWEST:
			Scr->ResizeX = 20;
			Scr->ResizeY = 20;
			break;
		case R_NORTHEAST:
			Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20;
			Scr->ResizeY = 20;
			break;
		case R_SOUTHWEST:
			Scr->ResizeX = 20;
			Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20;
			break;
		case R_SOUTHEAST:
			Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20;
			Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20;
			break;
		case R_CENTERED:
			Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) / 2;
			Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) / 2;
			break;
	}

	attributes.bit_gravity = NorthWestGravity;
	Scr->SizeWindow = XCreateWindow (dpy, Scr->Root,

/* djhjr - 5/15/96
					 0,0,
*/
					 Scr->ResizeX, Scr->ResizeY,

					 (unsigned int) Scr->SizeStringWidth,

/* djhjr - 4/29/98
					 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2),
*/
					 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
					 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) +
						((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0),

					 /* djhjr - 5/9/96 */
					 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
					 (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0,

					 (unsigned int) CopyFromParent,
					 (Visual *) CopyFromParent,
					 valuemask, &attributes);

	XUngrabServer(dpy);

	FirstScreen = FALSE;
    	Scr->FirstTime = FALSE;
    } /* for */

    if (numManaged == 0) {
	if (MultiScreen && NumScreens > 0)
	  fprintf (stderr, "%s:  unable to find any unmanaged screens\n",
		   ProgramName);
	exit (1);
	
    }

    RestartPreviousState = False;
    HandlingEvents = TRUE;

	RaiseStickyAbove(); /* DSE */    
    RaiseAutoPan(); /* autopan windows should have been raised
                       after [re]starting vtwm -- DSE */

    InitEvents();

	/* profile function stuff by DSE */
#define VTWM_PROFILE "VTWM Profile"
	if (FindMenuRoot (VTWM_PROFILE)) {
		ExecuteFunction (F_FUNCTION, VTWM_PROFILE, Event.xany.window,
			&Scr->TwmRoot, &Event, C_NO_CONTEXT, FALSE);
	}

/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
	/* restore setting from resource file */
	if (sound_state == 1) ToggleSounds();
#endif

    
    /* write out a PID file - djhjr - 12/2/01 */
    if (PrintPID)
    {
	int fd, err = 0;
	char buf[10], *fn = malloc(HomeLen + strlen(PidName) + 2);

	/* removed group and other permissions - djhjr - 10/20/02 */
	sprintf(fn, "%s/%s", Home, PidName);
	if ((fd = open(fn,
		O_WRONLY|O_EXCL|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) != -1)
	{
	    sprintf(buf, "%d\n", getpid());
	    err = write(fd, buf, strlen(buf));
	    close(fd);
	}

	if (fd == -1 || err == -1)
	{
	    fprintf(stderr, "%s: cannot write to %s\n", ProgramName, fn);
	    DoAudible();
	}

	free(fn);
    }

    HandleEvents();

	return (0);
}

/***********************************************************************
 *
 *  Procedure:
 *	InitVariables - initialize twm variables
 *
 ***********************************************************************
 */

void InitVariables()
{
    FreeList(&Scr->BorderColorL);
    FreeList(&Scr->IconBorderColorL);
    FreeList(&Scr->BorderTileForegroundL);
    FreeList(&Scr->BorderTileBackgroundL);
    FreeList(&Scr->TitleForegroundL);
    FreeList(&Scr->TitleBackgroundL);
    FreeList(&Scr->IconForegroundL);
    FreeList(&Scr->IconBackgroundL);
    FreeList(&Scr->IconManagerFL);
    FreeList(&Scr->IconManagerBL);
    FreeList(&Scr->IconMgrs);
    FreeList(&Scr->NoTitle);
    FreeList(&Scr->MakeTitle);
    FreeList(&Scr->AutoRaise);
    FreeList(&Scr->IconNames);
    FreeList(&Scr->NoHighlight);
    FreeList(&Scr->NoStackModeL);
    FreeList(&Scr->NoTitleHighlight);
    FreeList(&Scr->DontIconify);
    FreeList(&Scr->IconMgrNoShow);
    FreeList(&Scr->IconMgrShow);
    FreeList(&Scr->IconifyByUn);
    FreeList(&Scr->StartIconified);
    FreeList(&Scr->IconManagerHighlightL);
    FreeList(&Scr->SqueezeTitleL);
    FreeList(&Scr->DontSqueezeTitleL);
    FreeList(&Scr->WindowRingL);

    /* submitted by Jonathan Paisley - 10/27/02 */
    FreeList(&Scr->NoWindowRingL);

    FreeList(&Scr->WarpCursorL);
    FreeList(&Scr->NailedDown);
    FreeList(&Scr->VirtualDesktopColorFL);
    FreeList(&Scr->VirtualDesktopColorBL);
    FreeList(&Scr->VirtualDesktopColorBoL);
    FreeList(&Scr->DontShowInDisplay);

	/* Submitted by Erik Agsjo <erik.agsjo@aktiedirekt.com> */
    FreeList(&Scr->DontShowInTWMWindows);

    FreeList(&Scr->DoorForegroundL);
    FreeList(&Scr->DoorBackgroundL);

	/* djhjr - 4/22/96 */
	FreeList(&Scr->ImageCache);

	/* djhjr - 4/7/98 */
	FreeList(&Scr->OpaqueMoveL);
	FreeList(&Scr->NoOpaqueMoveL);
	FreeList(&Scr->OpaqueResizeL);
	FreeList(&Scr->NoOpaqueResizeL);

	/* djhjr - 5/2/98 */
	FreeList(&Scr->NoBorder);

	/* djhjr - 9/24/02 */
	FreeList(&Scr->UsePPositionL);

    NewFontCursor(&Scr->FrameCursor, "top_left_arrow");
    NewFontCursor(&Scr->TitleCursor, "top_left_arrow");
    NewFontCursor(&Scr->IconCursor, "top_left_arrow");
    NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow");
    NewFontCursor(&Scr->MoveCursor, "fleur");
    NewFontCursor(&Scr->ResizeCursor, "fleur");
    NewFontCursor(&Scr->MenuCursor, "sb_left_arrow");
    NewFontCursor(&Scr->ButtonCursor, "hand2");
    NewFontCursor(&Scr->WaitCursor, "watch");
    NewFontCursor(&Scr->SelectCursor, "dot");
    NewFontCursor(&Scr->DestroyCursor, "pirate");
    NewFontCursor(&Scr->DoorCursor, "exchange");/*RFBCURSOR*/
    NewFontCursor(&Scr->VirtualCursor, "rtl_logo");/*RFBCURSOR*/
    NewFontCursor(&Scr->DesktopCursor, "dotbox");/*RFBCURSOR*/
    Scr->NoCursor = NoCursor();

    Scr->Ring = NULL;
    Scr->RingLeader = NULL;

    Scr->DefaultC.fore = black;
    Scr->DefaultC.back = white;
    Scr->BorderColor = black;
    Scr->BorderTileC.fore = black;
    Scr->BorderTileC.back = white;
    Scr->TitleC.fore = black;
    Scr->TitleC.back = white;
    Scr->MenuC.fore = black;
    Scr->MenuC.back = white;
    Scr->MenuTitleC.fore = black;
    Scr->MenuTitleC.back = white;
    Scr->MenuShadowColor = black;
    Scr->IconC.fore = black;
    Scr->IconC.back = white;
    Scr->IconBorderColor = black;
    Scr->IconManagerC.fore = black;
    Scr->IconManagerC.back = white;
    Scr->IconManagerHighlight = black;

	/* djhjr - 4/19/96 */
    Scr->FramePadding = -100;
    Scr->TitlePadding = -100;
    Scr->ButtonIndent = -100;

/* djhjr - 8/11/98
    Scr->ThreeDBorderWidth = 6;
*/

	/* djhjr - 5/15/96 */
	Scr->ResizeX = Scr->ResizeY = 0;

    Scr->VirtualC.fore = black;/*RFB VCOLOR*/
    Scr->VirtualC.back = white;/*RFB VCOLOR*/
	Scr->RealScreenC.back = black;/*RFB 4/92 */
	Scr->RealScreenC.fore = white;/*RFB 4/92 */
    Scr->VirtualDesktopDisplayC.fore = black;
    Scr->VirtualDesktopDisplayC.back = white;
    Scr->VirtualDesktopDisplayBorder = black;
    Scr->DoorC.fore = black;
    Scr->DoorC.back = white;

	Scr->AutoRaiseDefault = FALSE;/*RAISEDELAY*/
    Scr->FramePadding = 2;		/* values that look "nice" on */
    Scr->TitlePadding = 8;		/* 75 and 100dpi displays */
    Scr->ButtonIndent = 1;
    Scr->SizeStringOffset = 0;
    Scr->BorderWidth = BW;
    Scr->IconBorderWidth = BW;

/* djhjr - 8/13/98 */
#ifdef ORIGINAL_PIXMAPS
    Scr->UnknownWidth = 0;
    Scr->UnknownHeight = 0;
#else
    Scr->unknownName = NULL;
#endif

    Scr->NumAutoRaises = 0;
/*  Scr->NoDefaults = FALSE;  */
	Scr->NoDefaultMouseOrKeyboardBindings = FALSE; /* DSE */
	Scr->NoDefaultTitleButtons = FALSE; /* DSE */
    Scr->UsePPosition = PPOS_OFF;
    Scr->FocusRoot = TRUE;
    Scr->Newest = NULL; /* PF */
    Scr->Focus = NULL;

    /* djhjr - 9/10/03 */
    Scr->IgnoreModifiers = 0;

    /* djhjr - 10/16/02 */
    Scr->WarpCentered = WARPC_OFF;

    Scr->WarpCursor = FALSE;
    Scr->ForceIcon = FALSE;
    Scr->NoGrabServer = FALSE;
    Scr->NoRaiseMove = FALSE;
    Scr->NoRaiseResize = FALSE;
    Scr->NoRaiseDeicon = FALSE;
    Scr->NoRaiseWarp = FALSE;
    Scr->DontMoveOff = FALSE;
    Scr->DoZoom = FALSE;
    Scr->TitleFocus = TRUE;

    /* djhjr - 5/27/98 */
    Scr->IconManagerFocus = TRUE;

    /* djhjr - 12/14/98 */
    Scr->StaticIconPositions = FALSE;

    /* djhjr - 10/2/01 */
    Scr->StrictIconManager = FALSE;

    /* djhjr - 8/23/02 */
    Scr->NoBorders = FALSE;

    Scr->NoTitlebar = FALSE;
    Scr->DecorateTransients = FALSE;
    Scr->IconifyByUnmapping = FALSE;
    Scr->ShowIconManager = FALSE;
    Scr->IconManagerDontShow =FALSE;
    Scr->BackingStore = TRUE;
    Scr->SaveUnder = TRUE;
    Scr->RandomPlacement = FALSE;
    Scr->PointerPlacement = FALSE;
    Scr->OpaqueMove = FALSE;

	/* djhjr - 4/6/98 */
	Scr->OpaqueResize = FALSE;

    Scr->Highlight = TRUE;

	/* djhjr - 1/27/98 */
    Scr->IconMgrHighlight = TRUE;

    Scr->StackMode = TRUE;
    Scr->TitleHighlight = TRUE;
    Scr->MoveDelta = 1;		/* so that f.deltastop will work */
    Scr->ZoomCount = 8;
    Scr->SortIconMgr = FALSE;
    Scr->Shadow = TRUE;
    Scr->InterpolateMenuColors = FALSE;
    Scr->NoIconManagers = FALSE;
    Scr->NoIconifyIconManagers = FALSE; /* PF */
    Scr->ClientBorderWidth = FALSE;
    Scr->SqueezeTitle = -1;

/* djhjr - 4/26/99
    Scr->FirstIconRegion = NULL;
    Scr->LastIconRegion = NULL;
*/
    FreeRegions(Scr->FirstIconRegion, Scr->LastIconRegion);

	/* djhjr - 4/26/99 */
    FreeRegions(Scr->FirstAppletRegion, Scr->LastAppletRegion);

    Scr->FirstTime = TRUE;
    Scr->HaveFonts = FALSE;		/* i.e. not loaded yet */
    Scr->CaseSensitive = TRUE;
    Scr->WarpUnmapped = FALSE;
    Scr->DeIconifyToScreen = FALSE;
    Scr->WarpWindows = FALSE;
    Scr->WarpToTransients = FALSE; /* PF */

	/* djhjr - 6/25/96 */
    Scr->ShallowReliefWindowButton = 2;

/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98
	* djhjr - 4/19/96 *
    Scr->use3Diconmanagers = FALSE;
    Scr->use3Dmenus = FALSE;
    Scr->use3Dtitles = FALSE;
    Scr->use3Dborders = FALSE;
*/

    Scr->ClearBevelContrast = 50;
    Scr->DarkBevelContrast  = 40;
    Scr->BeNiceToColormap = FALSE;

/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98
	* djhjr - 5/5/98 *
    Scr->use3Dicons = FALSE;
*/

/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02
	* djhjr - 4/26/96 *
    Scr->SunkFocusWindowTitle = FALSE;
*/

	/* for rader - djhjr - 2/9/99 */
	Scr->NoPrettyTitles = FALSE;

	/* djhjr - 9/21/96 */
    Scr->ButtonColorIsFrame = FALSE;

    Scr->snapRealScreen = FALSE;
	Scr->OldFashionedTwmWindowsMenu = FALSE;
    Scr->GeometriesAreVirtual = TRUE;
	Scr->UseWindowRing = FALSE;

    /* setup default fonts; overridden by defaults from system.twmrc */
#define DEFAULT_NICE_FONT "variable"
#define DEFAULT_FAST_FONT "fixed"
#define DEFAULT_SMALL_FONT "5x8"

    Scr->TitleBarFont.font = NULL;
    Scr->TitleBarFont.name = DEFAULT_NICE_FONT;
    Scr->MenuFont.font = NULL;
    Scr->MenuFont.name = DEFAULT_NICE_FONT;
    Scr->MenuTitleFont.font = NULL; /* DSE */
    Scr->MenuTitleFont.name = NULL; /* uses MenuFont unless set -- DSE */
    Scr->IconFont.font = NULL;
    Scr->IconFont.name = DEFAULT_NICE_FONT;
    Scr->SizeFont.font = NULL;
    Scr->SizeFont.name = DEFAULT_FAST_FONT;

	/* djhjr - 5/10/96 */
    Scr->InfoFont.font = NULL;
    Scr->InfoFont.name = DEFAULT_FAST_FONT;

    Scr->IconManagerFont.font = NULL;
    Scr->IconManagerFont.name = DEFAULT_NICE_FONT;
    Scr->VirtualFont.font = NULL;
    Scr->VirtualFont.name = DEFAULT_SMALL_FONT;
    Scr->DoorFont.font = NULL;
    Scr->DoorFont.name = DEFAULT_NICE_FONT;
    Scr->DefaultFont.font = NULL;
    Scr->DefaultFont.name = DEFAULT_FAST_FONT;

    /* no names unless they say so */
    Scr->NamesInVirtualDesktop = FALSE;

    /* by default we emulate the old twm - ie. no virtual desktop */
    Scr->Virtual = FALSE;

    /* this makes some of the algorithms for checking if windows
     * are on the screen simpler */
    Scr->VirtualDesktopWidth = Scr->MyDisplayWidth;
    Scr->VirtualDesktopHeight = Scr->MyDisplayHeight;

    /* start at the top left of the virtual desktop */
    Scr->VirtualDesktopX = 0;
    Scr->VirtualDesktopY = 0;

    /* pan defaults to half screen size */
    Scr->VirtualDesktopPanDistanceX = 50;
    Scr->VirtualDesktopPanDistanceY = 50;

	/* djhjr - 9/8/98 */
	Scr->VirtualDesktopPanResistance = 0;

    /* default scale is 1:25 */
    Scr->VirtualDesktopDScale = 25;

    /* and the display should appear at 0, 0 */
    Scr->VirtualDesktopDX = 0;
    Scr->VirtualDesktopDY = 0;

    /* by default no autopan */
    Scr->AutoPanX = 0;
    Scr->StayUpMenus = FALSE;
    Scr->StayUpOptionalMenus = FALSE; /* PF */

	Scr->AutoPanWarpWithRespectToRealScreen = 0;   /* DSE */
	Scr->AutoPanBorderWidth = 5;                   /* DSE */
	Scr->AutoPanExtraWarp = 2;                     /* DSE */
	Scr->EnhancedExecResources = FALSE;            /* DSE */
	Scr->RightHandSidePulldownMenus = FALSE;       /* DSE */

	/* was '2' for when UseRealScreenBorderWidth existed - djhjr - 2/15/99 */
	Scr->RealScreenBorderWidth = 0;                /* DSE */

	/* djhjr - 10/11/01 */
	Scr->ZoomZoom = FALSE;

	Scr->LessRandomZoomZoom = FALSE;               /* DSE */
	Scr->PrettyZoom = FALSE;                       /* DSE */
	Scr->StickyAbove = FALSE;                      /* DSE */
	Scr->DontInterpolateTitles = FALSE;            /* DSE */

	/* djhjr - 1/6/98 */
	Scr->FixManagedVirtualGeometries = FALSE;

	Scr->FixTransientVirtualGeometries = FALSE;    /* DSE */
	Scr->WarpSnug = FALSE;                         /* DSE */

	/* djhjr - 4/17/98 */
	Scr->VirtualReceivesMotionEvents = FALSE;
	Scr->VirtualSendsMotionEvents = FALSE;

	/* djhjr - 5/2/98 */
	Scr->BorderBevelWidth = 0;
	Scr->TitleBevelWidth = 0;
	Scr->MenuBevelWidth = 0;
	Scr->IconMgrBevelWidth = 0;
	Scr->InfoBevelWidth = 0;

	/* djhjr - 8/11/98 */
	Scr->IconBevelWidth = 0;
	Scr->ButtonBevelWidth = 0;

	/* djhjr - 2/7/99 */
	Scr->DoorBevelWidth = 0;
	Scr->VirtualDesktopBevelWidth = 0;

	/* djhjr - 5/22/00 */
	Scr->MenuScrollBorderWidth = 2;
	Scr->MenuScrollJump = 3;

	/* djhjr - 6/22/99 */
	Scr->DontDeiconifyTransients = FALSE;

	/* submitted by Ugen Antsilevitch - 5/28/00 */
	Scr->WarpVisible = FALSE;

	/* djhjr - 6/22/01 */
	Scr->PauseOnExit = 0;
	Scr->PauseOnQuit = 0;

	/* djhjr - 11/3/03 */
	Scr->RaiseOnStart = FALSE;
}


void CreateFonts ()
{
    GetFont(&Scr->TitleBarFont);
    GetFont(&Scr->MenuFont);
    GetFont(&Scr->IconFont);
    GetFont(&Scr->SizeFont);

	/* djhjr - 5/10/96 */
    GetFont(&Scr->InfoFont);

    GetFont(&Scr->IconManagerFont);
    GetFont(&Scr->VirtualFont);
    GetFont(&Scr->DoorFont);
    GetFont(&Scr->DefaultFont);
    GetFont(&Scr->MenuTitleFont); /* DSE */
    Scr->HaveFonts = TRUE;
}


void RestoreWithdrawnLocation (tmp)
    TwmWindow *tmp;
{
    int gravx, gravy;
    unsigned int bw, mask;
    XWindowChanges xwc;

    if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y,
		      &JunkWidth, &JunkHeight, &bw, &JunkDepth)) {

	GetGravityOffsets (tmp, &gravx, &gravy);
	if (gravy < 0) xwc.y -= tmp->title_height;

	/* djhjr - 4/19/96 */
	xwc.x += gravx * tmp->frame_bw3D;
	xwc.y += gravy * tmp->frame_bw3D;

	if (bw != tmp->old_bw) {
	    int xoff, yoff;

	    if (!Scr->ClientBorderWidth) {
		xoff = gravx;
		yoff = gravy;
	    } else {
		xoff = 0;
		yoff = 0;
	    }

	    xwc.x -= (xoff + 1) * tmp->old_bw;
	    xwc.y -= (yoff + 1) * tmp->old_bw;
	}
	if (!Scr->ClientBorderWidth) {
	    xwc.x += gravx * tmp->frame_bw;
	    xwc.y += gravy * tmp->frame_bw;
	}

	mask = (CWX | CWY);
	if (bw != tmp->old_bw) {
	    xwc.border_width = tmp->old_bw;
	    mask |= CWBorderWidth;
	}

	XConfigureWindow (dpy, tmp->w, mask, &xwc);

	if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) {
	    XUnmapWindow (dpy, tmp->wmhints->icon_window);
	}

    }
}


void Reborder (time)
Time time;
{
    TwmWindow *tmp;			/* temp twm window structure */
    int scrnum;

    /* put a border back around all windows */

    XGrabServer (dpy);
    for (scrnum = 0; scrnum < NumScreens; scrnum++)
    {
	if ((Scr = ScreenList[scrnum]) == NULL)
	    continue;

	InstallWindowColormaps (0, &Scr->TwmRoot);	/* force reinstall */
	for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
	{
	    RestoreWithdrawnLocation (tmp);
	    XMapWindow (dpy, tmp->w);
	}
    }

    XUngrabServer (dpy);
    SetFocus ((TwmWindow*)NULL, time);
}

/* delete the PID file - djhjr - 12/2/01 */
void delete_pidfile()
{
    char *fn;

    if (PrintPID)
    {    
	fn = malloc(HomeLen + strlen(PidName) + 2);
	sprintf(fn, "%s/%s", Home, PidName);
	unlink(fn);
	free(fn);
    }
}


/*
 * Exit handlers. Clean up and exit VTWM.
 *
 *    PlaySoundDone()
 *    Done()
 *    QueueRestartVtwm()
 */

/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
SIGNAL_T PlaySoundDone()
{
    if (PlaySound(S_STOP))
    {
	/* allow time to emit */
	if (Scr->PauseOnExit) sleep(Scr->PauseOnExit);
    }

    Done();
    SIGNAL_RETURN;
}

void Done()
{
    CloseSound();

    SetRealScreen(0,0);
    Reborder (CurrentTime);
    XCloseDisplay(dpy);
    
    delete_pidfile(); /* djhjr - 12/2/01 */

    exit(0);
}
#else
SIGNAL_T Done()
{
    SetRealScreen(0,0);
    Reborder (CurrentTime);
    XCloseDisplay(dpy);
    
    delete_pidfile(); /* djhjr - 12/2/01 */

    exit(0);
    SIGNAL_RETURN;
}
#endif

/* djhjr - 7/31/98 */
SIGNAL_T
QueueRestartVtwm()
{
    XClientMessageEvent ev;

    delete_pidfile(); /* djhjr - 12/2/01 */

    ev.type = ClientMessage;
    ev.window = Scr->Root;
    ev.message_type = _XA_TWM_RESTART;
    ev.format = 32;
    ev.data.b[0] = (char)0;

    XSendEvent (dpy, Scr->VirtualDesktopDisplay, False, 0L, (XEvent *) &ev);
    XFlush(dpy);
    SIGNAL_RETURN;
}


/*
 * Error Handlers.  If a client dies, we'll get a BadWindow error (except for
 * GetGeometry which returns BadDrawable) for most operations that we do before
 * manipulating the client's window.
 */

Bool ErrorOccurred = False;
XErrorEvent LastErrorEvent;

static int TwmErrorHandler(dpy, event)
    Display *dpy;
    XErrorEvent *event;
{
    LastErrorEvent = *event;
    ErrorOccurred = True;

    if (PrintErrorMessages && 			/* don't be too obnoxious */
	event->error_code != BadWindow &&	/* watch for dead puppies */
	(event->request_code != X_GetGeometry &&	 /* of all styles */
	 event->error_code != BadDrawable))
      XmuPrintDefaultErrorMessage (dpy, event, stderr);
    return 0;
}


/* ARGSUSED*/
static int CatchRedirectError(dpy, event)
    Display *dpy;
    XErrorEvent *event;
{
    RedirectError = TRUE;
    LastErrorEvent = *event;
    ErrorOccurred = True;
    return 0;
}

Atom _XA_MIT_PRIORITY_COLORS;
Atom _XA_WM_CHANGE_STATE;
Atom _XA_WM_STATE;
Atom _XA_WM_COLORMAP_WINDOWS;
Atom _XA_WM_PROTOCOLS;
Atom _XA_WM_TAKE_FOCUS;
Atom _XA_WM_SAVE_YOURSELF;
Atom _XA_WM_DELETE_WINDOW;

/* djhjr - 7/31/98 */
Atom _XA_TWM_RESTART;

void InternUsefulAtoms ()
{
    /*
     * Create priority colors if necessary.
     */
    _XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False);
    _XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False);
    _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False);
    _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False);
    _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
    _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False);
    _XA_WM_SAVE_YOURSELF = XInternAtom (dpy, "WM_SAVE_YOURSELF", False);
    _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);

    /* djhjr - 7/31/98 */
    _XA_TWM_RESTART = XInternAtom (dpy, "_TWM_RESTART", False);
}
