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