twm.c revision f66df612
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 * twm - "Tom's Window Manager" 563e747e6dSmrg * 573e747e6dSmrg * 27-Oct-1987 Thomas E. LaStrange File created 583e747e6dSmrg * 10-Oct-1990 David M. Sternlicht Storing saved colors on root 593e747e6dSmrg * 19-Feb-2005 Julien Lafon Handle print screens for unified Xserver 603e747e6dSmrg ***********************************************************************/ 613e747e6dSmrg 623e747e6dSmrg#include <stdio.h> 633e747e6dSmrg#include <signal.h> 643e747e6dSmrg#include <fcntl.h> 65f66df612Smrg#include <stdarg.h> 66f66df612Smrg 673e747e6dSmrg#include "twm.h" 683e747e6dSmrg#include "iconmgr.h" 693e747e6dSmrg#include "add_window.h" 703e747e6dSmrg#include "gc.h" 713e747e6dSmrg#include "parse.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" 79f66df612Smrg 803e747e6dSmrg#include <X11/Xproto.h> 813e747e6dSmrg#include <X11/Xatom.h> 823e747e6dSmrg#include <X11/SM/SMlib.h> 833e747e6dSmrg#include <X11/Xmu/Error.h> 843e747e6dSmrg#include <X11/extensions/sync.h> 853e747e6dSmrg#include <X11/Xlocale.h> 86f66df612Smrg 873e747e6dSmrg#ifdef XPRINT 883e747e6dSmrg#include <X11/extensions/Print.h> 89f66df612Smrg#endif /* XPRINT */ 90f66df612Smrg 91f66df612Smrg#ifdef HAVE_XRANDR 92f66df612Smrg#include <X11/extensions/Xrandr.h> 93f66df612Smrg#endif 943e747e6dSmrg 95f66df612Smrgstatic void InitVariables(void); 96c2535118Smrg 97f66df612SmrgXtAppContext appContext; /* Xt application context */ 983e747e6dSmrgXtSignalId si; 993e747e6dSmrg 100f66df612SmrgDisplay *dpy = NULL; /* which display are we talking to */ 101f66df612SmrgWindow ResizeWindow; /* the window we are resizing */ 1023e747e6dSmrg 103f66df612Smrgint MultiScreen = TRUE; /* try for more than one screen? */ 1043e747e6dSmrgint NoPrintscreens = False; /* ignore special handling of print screens? */ 105f66df612Smrgint NumScreens; /* number of screens in ScreenList */ 106f66df612Smrgint HasShape; /* server supports shape extension? */ 107f66df612Smrg 108f66df612Smrg#ifdef HAVE_XRANDR 109f66df612Smrgint HasXrandr; /* server supports Xrandr extension? */ 110f66df612Smrgint XrandrEventBase, XrandrErrorBase; 111f66df612Smrg#endif 112f66df612Smrg 1133e747e6dSmrgint ShapeEventBase, ShapeErrorBase; 114f66df612Smrgint HasSync; /* server supports SYNC extension? */ 1153e747e6dSmrgint SyncEventBase, SyncErrorBase; 116f66df612SmrgScreenInfo **ScreenList; /* structures for each screen */ 117f66df612SmrgScreenInfo *Scr = NULL; /* the cur and prev screens */ 118f66df612Smrgint PreviousScreen; /* last screen that we were on */ 119f66df612Smrgint FirstScreen; /* TRUE ==> first screen of display */ 120f66df612Smrgint message_level = 1; /* controls error messages */ 121f66df612Smrgstatic int RedirectError; /* TRUE ==> another window manager running */ 122f66df612Smrgstatic int TwmErrorHandler(Display *dpy, XErrorEvent *event); /* for setting RedirectError */ 123f66df612Smrgstatic int CatchRedirectError(Display *dpy, XErrorEvent *event); /* for everything else */ 124c2535118Smrgstatic void sigHandler(int); 125f66df612Smrgchar Info[INFO_LINES][INFO_SIZE]; /* info strings to print */ 1263e747e6dSmrgint InfoLines; 127c2535118Smrgstatic char *InitFile = NULL; 1283e747e6dSmrg 129f66df612SmrgCursor UpperLeftCursor; /* upper Left corner cursor */ 1303e747e6dSmrgCursor RightButt; 1313e747e6dSmrgCursor MiddleButt; 1323e747e6dSmrgCursor LeftButt; 1333e747e6dSmrg 134f66df612SmrgXContext TwmContext; /* context for twm windows */ 135f66df612SmrgXContext MenuContext; /* context for all menu windows */ 136f66df612SmrgXContext IconManagerContext; /* context for all window list windows */ 137f66df612SmrgXContext ScreenContext; /* context to get screen data */ 138f66df612SmrgXContext ColormapContext; /* context for colormap operations */ 1393e747e6dSmrg 140f66df612SmrgXClassHint NoClass; /* for applications with no class */ 1413e747e6dSmrg 1423e747e6dSmrgXGCValues Gcv; 1433e747e6dSmrg 144f66df612Smrgconst char *Home; /* the HOME environment variable */ 145f66df612Smrgint HomeLen; /* length of Home */ 146f66df612Smrgint ParseError; /* error parsing the .twmrc file */ 1473e747e6dSmrg 148f66df612Smrgint HandlingEvents = FALSE; /* are we handling events yet? */ 1493e747e6dSmrg 150f66df612SmrgWindow JunkRoot; /* junk window */ 151f66df612SmrgWindow JunkChild; /* junk window */ 152f66df612Smrgint JunkX; /* junk variable */ 153f66df612Smrgint JunkY; /* junk variable */ 1543e747e6dSmrgunsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask; 1553e747e6dSmrg 1563e747e6dSmrgchar *ProgramName; 1573e747e6dSmrgint Argc; 1583e747e6dSmrgchar **Argv; 1593e747e6dSmrg 160f66df612SmrgBool RestartPreviousState = False; /* try to restart in previous state */ 1613e747e6dSmrg 162c2535118Smrgstatic unsigned long black, white; 1633e747e6dSmrg 1643e747e6dSmrgAtom TwmAtoms[11]; 1653e747e6dSmrg 166f66df612SmrgBool use_fontset; /* use XFontSet-related functions or not */ 1673e747e6dSmrg 1683e747e6dSmrg/* don't change the order of these strings */ 169f66df612Smrgstatic char *atom_names[11] = { 1703e747e6dSmrg "_MIT_PRIORITY_COLORS", 1713e747e6dSmrg "WM_CHANGE_STATE", 1723e747e6dSmrg "WM_STATE", 1733e747e6dSmrg "WM_COLORMAP_WINDOWS", 1743e747e6dSmrg "WM_PROTOCOLS", 1753e747e6dSmrg "WM_TAKE_FOCUS", 1763e747e6dSmrg "WM_SAVE_YOURSELF", 1773e747e6dSmrg "WM_DELETE_WINDOW", 1783e747e6dSmrg "SM_CLIENT_ID", 1793e747e6dSmrg "WM_CLIENT_LEADER", 1803e747e6dSmrg "WM_WINDOW_ROLE" 1813e747e6dSmrg}; 1823e747e6dSmrg 1833e747e6dSmrg#ifdef XPRINT 1843e747e6dSmrg/* |hasExtension()| and |IsPrintScreen()| have been stolen from 1853e747e6dSmrg * xc/programs/xdpyinfo/xdpyinfo.c */ 186f66df612Smrgstatic Bool 187f66df612SmrghasExtension(Display *dpy2, char *extname) 1883e747e6dSmrg{ 189f66df612Smrg int num_extensions, i; 190f66df612Smrg char **extensions; 191f66df612Smrg 192f66df612Smrg extensions = XListExtensions(dpy2, &num_extensions); 193f66df612Smrg for (i = 0; i < num_extensions && 1943e747e6dSmrg (strcmp(extensions[i], extname) != 0); i++); 195f66df612Smrg XFreeExtensionList(extensions); 196f66df612Smrg return i != num_extensions; 1973e747e6dSmrg} 1983e747e6dSmrg 199f66df612Smrgstatic Bool 200f66df612SmrgIsPrintScreen(Screen *s) 2013e747e6dSmrg{ 202f66df612Smrg Display *dpy2 = XDisplayOfScreen(s); 2033e747e6dSmrg 2043e747e6dSmrg /* Check whether this is a screen of a print DDX */ 205f66df612Smrg if (hasExtension(dpy2, XP_PRINTNAME)) { 2063e747e6dSmrg Screen **pscreens; 207f66df612Smrg int pscrcount; 208f66df612Smrg int i; 2093e747e6dSmrg 210f66df612Smrg pscreens = XpQueryScreens(dpy2, &pscrcount); 211f66df612Smrg for (i = 0; (i < pscrcount) && pscreens; i++) { 2123e747e6dSmrg if (s == pscreens[i]) { 2133e747e6dSmrg return True; 2143e747e6dSmrg } 2153e747e6dSmrg } 216ffd25bcaSmrg XFree(pscreens); 2173e747e6dSmrg } 2183e747e6dSmrg return False; 2193e747e6dSmrg} 220f66df612Smrg#endif /* XPRINT */ 221f66df612Smrg 222f66df612Smrgstatic void 223f66df612Smrgusage(void) 224f66df612Smrg{ 225f66df612Smrg fprintf(stderr, "usage: %s [-display dpy] [-f file] [-s] [-q] [-v] [-V]" 226f66df612Smrg#ifdef XPRINT 227f66df612Smrg " [-noprint]" 228f66df612Smrg#endif /* XPRINT */ 229f66df612Smrg " [-clientId id] [-restore file]\n", ProgramName); 230f66df612Smrg exit(EXIT_FAILURE); 231f66df612Smrg} 232f66df612Smrg 233f66df612Smrgstatic Bool 234f66df612Smrgbrief_opt(const char *param, const char *option) 235f66df612Smrg{ 236f66df612Smrg size_t have = strlen(++param); 237f66df612Smrg size_t want = strlen(option); 238f66df612Smrg Bool result = False; 239f66df612Smrg 240f66df612Smrg if (have <= want) { 241f66df612Smrg if (!strncmp(param, option, have)) 242f66df612Smrg result = True; 243f66df612Smrg } 244f66df612Smrg return result; 245f66df612Smrg} 2463e747e6dSmrg 2473e747e6dSmrg/*********************************************************************** 2483e747e6dSmrg * 2493e747e6dSmrg * Procedure: 250f66df612Smrg * main - start of twm 2513e747e6dSmrg * 2523e747e6dSmrg *********************************************************************** 2533e747e6dSmrg */ 2543e747e6dSmrg 2553e747e6dSmrgint 2563e747e6dSmrgmain(int argc, char *argv[]) 2573e747e6dSmrg{ 2583e747e6dSmrg Window root, parent, *children; 2593e747e6dSmrg unsigned int nchildren; 2603e747e6dSmrg int i, j; 2613e747e6dSmrg char *display_name = NULL; 262f66df612Smrg unsigned long valuemask; /* mask for create windows */ 263f66df612Smrg XSetWindowAttributes attributes; /* attributes for create windows */ 2643e747e6dSmrg int numManaged, firstscrn, lastscrn, scrnum; 2653e747e6dSmrg int zero = 0; 2663e747e6dSmrg char *restore_filename = NULL; 2673e747e6dSmrg char *client_id = NULL; 2683e747e6dSmrg char *loc; 2693e747e6dSmrg 2703e747e6dSmrg ProgramName = argv[0]; 2713e747e6dSmrg Argc = argc; 2723e747e6dSmrg Argv = argv; 2733e747e6dSmrg 2743e747e6dSmrg for (i = 1; i < argc; i++) { 275f66df612Smrg if (argv[i][0] == '-') { 276f66df612Smrg switch (argv[i][1]) { 277f66df612Smrg case 'V': 278f66df612Smrg printf("%s %s\n", APP_NAME, APP_VERSION); 279f66df612Smrg exit(EXIT_SUCCESS); 280f66df612Smrg case 'd': /* -display dpy */ 281f66df612Smrg if (!brief_opt(argv[i], "display")) 282f66df612Smrg usage(); 283f66df612Smrg if (++i >= argc) 284f66df612Smrg usage(); 285f66df612Smrg display_name = argv[i]; 286f66df612Smrg continue; 287f66df612Smrg case 's': /* -single */ 288f66df612Smrg if (!brief_opt(argv[i], "single")) 289f66df612Smrg usage(); 290f66df612Smrg MultiScreen = FALSE; 291f66df612Smrg continue; 2923e747e6dSmrg#ifdef XPRINT 293f66df612Smrg case 'n': /* -noprint */ 294f66df612Smrg if (!brief_opt(argv[i], "noprint")) 295f66df612Smrg usage(); 296f66df612Smrg NoPrintscreens = True; 297f66df612Smrg continue; 298f66df612Smrg#endif /* XPRINT */ 299f66df612Smrg case 'f': /* -file twmrcfilename */ 300f66df612Smrg if (!brief_opt(argv[i], "file")) 301f66df612Smrg usage(); 302f66df612Smrg if (++i >= argc) 303f66df612Smrg usage(); 304f66df612Smrg InitFile = argv[i]; 305f66df612Smrg continue; 306f66df612Smrg case 'v': /* -verbose */ 307f66df612Smrg if (!brief_opt(argv[i], "verbose")) 308f66df612Smrg usage(); 309f66df612Smrg message_level++; 310f66df612Smrg continue; 311f66df612Smrg case 'c': /* -clientId */ 312f66df612Smrg if (!brief_opt(argv[i], "clientId")) 313f66df612Smrg usage(); 314f66df612Smrg if (++i >= argc) 315f66df612Smrg usage(); 316f66df612Smrg client_id = argv[i]; 317f66df612Smrg continue; 318f66df612Smrg case 'r': /* -restore */ 319f66df612Smrg if (!brief_opt(argv[i], "restore")) 320f66df612Smrg usage(); 321f66df612Smrg if (++i >= argc) 322f66df612Smrg usage(); 323f66df612Smrg restore_filename = argv[i]; 324f66df612Smrg continue; 325f66df612Smrg case 'q': /* -quiet */ 326f66df612Smrg if (!brief_opt(argv[i], "quiet")) 327f66df612Smrg usage(); 328f66df612Smrg --message_level; 329f66df612Smrg continue; 330f66df612Smrg } 331f66df612Smrg } 332f66df612Smrg usage(); 3333e747e6dSmrg } 3343e747e6dSmrg 3353e747e6dSmrg loc = setlocale(LC_ALL, ""); 3363e747e6dSmrg if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") || 337f66df612Smrg !XSupportsLocale()) { 338f66df612Smrg use_fontset = False; 339f66df612Smrg } 340f66df612Smrg else { 341f66df612Smrg use_fontset = True; 3423e747e6dSmrg } 3433e747e6dSmrg 3443e747e6dSmrg#define newhandler(sig) \ 3453e747e6dSmrg if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, sigHandler) 3463e747e6dSmrg 347f66df612Smrg newhandler(SIGINT); 348f66df612Smrg newhandler(SIGHUP); 349f66df612Smrg newhandler(SIGQUIT); 350f66df612Smrg newhandler(SIGTERM); 3513e747e6dSmrg 3523e747e6dSmrg#undef newhandler 3533e747e6dSmrg 3543e747e6dSmrg Home = getenv("HOME"); 3553e747e6dSmrg if (Home != NULL) { 356f66df612Smrg char *temp_p; 3573e747e6dSmrg 358f66df612Smrg /* 359f66df612Smrg * Make a copy of Home because the string returned by getenv() can be 360f66df612Smrg * overwritten by some POSIX.1 and ANSI-C implementations of getenv() 361f66df612Smrg * when further calls to getenv() are made 362f66df612Smrg */ 3633e747e6dSmrg 364f66df612Smrg temp_p = strdup(Home); 365f66df612Smrg Home = temp_p; 3663e747e6dSmrg } 3673e747e6dSmrg 3683e747e6dSmrg if (Home == NULL) 369f66df612Smrg Home = "./"; 3703e747e6dSmrg 371f66df612Smrg HomeLen = (int) strlen(Home); 3723e747e6dSmrg 3733e747e6dSmrg NoClass.res_name = NoName; 3743e747e6dSmrg NoClass.res_class = NoName; 3753e747e6dSmrg 376f66df612Smrg XtToolkitInitialize(); 377f66df612Smrg appContext = XtCreateApplicationContext(); 3783e747e6dSmrg 3793e747e6dSmrg si = XtAppAddSignal(appContext, Done, NULL); 380ffd25bcaSmrg 381f66df612Smrg if (!(dpy = XtOpenDisplay(appContext, display_name, "twm", "twm", 382f66df612Smrg NULL, 0, &zero, NULL))) { 383f66df612Smrg twmError("unable to open display \"%s\"", XDisplayName(display_name)); 3843e747e6dSmrg } 3853e747e6dSmrg 3863e747e6dSmrg if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) { 387f66df612Smrg twmError("unable to mark display connection as close-on-exec"); 3883e747e6dSmrg } 3893e747e6dSmrg 3903e747e6dSmrg if (restore_filename) 391f66df612Smrg ReadWinConfigFile(restore_filename); 3923e747e6dSmrg 393f66df612Smrg HasShape = XShapeQueryExtension(dpy, &ShapeEventBase, &ShapeErrorBase); 394f66df612Smrg HasSync = XSyncQueryExtension(dpy, &SyncEventBase, &SyncErrorBase); 395f66df612Smrg#ifdef HAVE_XRANDR 396f66df612Smrg HasXrandr = XRRQueryExtension(dpy, &XrandrEventBase, &XrandrErrorBase); 397f66df612Smrg#endif 3983e747e6dSmrg TwmContext = XUniqueContext(); 3993e747e6dSmrg MenuContext = XUniqueContext(); 4003e747e6dSmrg IconManagerContext = XUniqueContext(); 4013e747e6dSmrg ScreenContext = XUniqueContext(); 4023e747e6dSmrg ColormapContext = XUniqueContext(); 4033e747e6dSmrg 4043e747e6dSmrg (void) XInternAtoms(dpy, atom_names, sizeof TwmAtoms / sizeof TwmAtoms[0], 405f66df612Smrg False, TwmAtoms); 4063e747e6dSmrg 4073e747e6dSmrg /* Set up the per-screen global information. */ 4083e747e6dSmrg 4093e747e6dSmrg NumScreens = ScreenCount(dpy); 4103e747e6dSmrg 411f66df612Smrg if (MultiScreen) { 412f66df612Smrg firstscrn = 0; 413f66df612Smrg lastscrn = NumScreens - 1; 4143e747e6dSmrg } 415f66df612Smrg else { 416f66df612Smrg firstscrn = lastscrn = DefaultScreen(dpy); 4173e747e6dSmrg } 4183e747e6dSmrg 4193e747e6dSmrg InfoLines = 0; 4203e747e6dSmrg 4213e747e6dSmrg /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */ 422f66df612Smrg ScreenList = calloc((size_t) NumScreens, sizeof(ScreenInfo *)); 423f66df612Smrg if (ScreenList == NULL) { 424f66df612Smrg twmError("Unable to allocate memory for screen list, exiting"); 4253e747e6dSmrg } 4263e747e6dSmrg numManaged = 0; 4273e747e6dSmrg PreviousScreen = DefaultScreen(dpy); 4283e747e6dSmrg FirstScreen = TRUE; 429f66df612Smrg for (scrnum = firstscrn; scrnum <= lastscrn; scrnum++) { 4303e747e6dSmrg#ifdef XPRINT 4313e747e6dSmrg /* Ignore print screens to avoid that users accidentally warp on a 4323e747e6dSmrg * print screen (which are not visible on video displays) */ 433f66df612Smrg if ((!NoPrintscreens) && IsPrintScreen(XScreenOfDisplay(dpy, scrnum))) { 434f66df612Smrg twmWarning("skipping print screen %d", scrnum); 4353e747e6dSmrg continue; 4363e747e6dSmrg } 437f66df612Smrg#endif /* XPRINT */ 4383e747e6dSmrg 4393e747e6dSmrg /* Make sure property priority colors is empty */ 440f66df612Smrg XChangeProperty(dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS, 441f66df612Smrg XA_CARDINAL, 32, PropModeReplace, NULL, 0); 442f66df612Smrg RedirectError = FALSE; 443f66df612Smrg XSetErrorHandler(CatchRedirectError); 444f66df612Smrg XSelectInput(dpy, RootWindow(dpy, scrnum), 445f66df612Smrg ColormapChangeMask | EnterWindowMask | PropertyChangeMask | 446f66df612Smrg SubstructureRedirectMask | KeyPressMask | 447f66df612Smrg ButtonPressMask | ButtonReleaseMask); 448f66df612Smrg XSync(dpy, 0); 449f66df612Smrg XSetErrorHandler(TwmErrorHandler); 450f66df612Smrg 451f66df612Smrg if (RedirectError) { 452f66df612Smrg if (MultiScreen && NumScreens > 0) { 453f66df612Smrg twmWarning("another window manager is already running." 454f66df612Smrg " on screen %d?\n", scrnum); 455f66df612Smrg } 456f66df612Smrg else { 457f66df612Smrg twmWarning("another window manager is already running."); 458f66df612Smrg } 459f66df612Smrg continue; 460f66df612Smrg } 461f66df612Smrg 462f66df612Smrg numManaged++; 463f66df612Smrg 464f66df612Smrg /* Note: ScreenInfo struct is calloc'ed to initialize to zero. */ 465f66df612Smrg Scr = ScreenList[scrnum] = calloc(1, sizeof(ScreenInfo)); 466f66df612Smrg if (Scr == NULL) { 467f66df612Smrg twmWarning 468f66df612Smrg ("unable to allocate memory for ScreenInfo structure for screen %d.", 469f66df612Smrg scrnum); 470f66df612Smrg continue; 471f66df612Smrg } 472f66df612Smrg 473f66df612Smrg /* initialize list pointers, remember to put an initialization 474f66df612Smrg * in InitVariables also 475f66df612Smrg */ 476f66df612Smrg Scr->BorderColorL = NULL; 477f66df612Smrg Scr->IconBorderColorL = NULL; 478f66df612Smrg Scr->BorderTileForegroundL = NULL; 479f66df612Smrg Scr->BorderTileBackgroundL = NULL; 480f66df612Smrg Scr->TitleForegroundL = NULL; 481f66df612Smrg Scr->TitleBackgroundL = NULL; 482f66df612Smrg Scr->IconForegroundL = NULL; 483f66df612Smrg Scr->IconBackgroundL = NULL; 484f66df612Smrg Scr->NoTitle = NULL; 485f66df612Smrg Scr->MakeTitle = NULL; 486f66df612Smrg Scr->AutoRaise = NULL; 487f66df612Smrg Scr->IconNames = NULL; 488f66df612Smrg Scr->NoHighlight = NULL; 489f66df612Smrg Scr->NoStackModeL = NULL; 490f66df612Smrg Scr->NoTitleHighlight = NULL; 491f66df612Smrg Scr->DontIconify = NULL; 492f66df612Smrg Scr->IconMgrNoShow = NULL; 493f66df612Smrg Scr->IconMgrShow = NULL; 494f66df612Smrg Scr->IconifyByUn = NULL; 495f66df612Smrg Scr->IconManagerFL = NULL; 496f66df612Smrg Scr->IconManagerBL = NULL; 497f66df612Smrg Scr->IconMgrs = NULL; 498f66df612Smrg Scr->StartIconified = NULL; 499f66df612Smrg Scr->SqueezeTitleL = NULL; 500f66df612Smrg Scr->DontSqueezeTitleL = NULL; 501f66df612Smrg Scr->WindowRingL = NULL; 502f66df612Smrg Scr->WarpCursorL = NULL; 503f66df612Smrg /* remember to put an initialization in InitVariables also 504f66df612Smrg */ 505f66df612Smrg 506f66df612Smrg Scr->screen = scrnum; 507f66df612Smrg Scr->d_depth = DefaultDepth(dpy, scrnum); 508f66df612Smrg Scr->d_visual = DefaultVisual(dpy, scrnum); 509f66df612Smrg Scr->Root = RootWindow(dpy, scrnum); 510f66df612Smrg XSaveContext(dpy, Scr->Root, ScreenContext, (XPointer) Scr); 511f66df612Smrg 512f66df612Smrg Scr->TwmRoot.cmaps.number_cwins = 1; 513f66df612Smrg Scr->TwmRoot.cmaps.cwins = malloc(sizeof(ColormapWindow *)); 514f66df612Smrg Scr->TwmRoot.cmaps.cwins[0] = 515f66df612Smrg CreateColormapWindow(Scr->Root, True, False); 516f66df612Smrg Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured; 517f66df612Smrg 518f66df612Smrg Scr->cmapInfo.cmaps = NULL; 519f66df612Smrg Scr->cmapInfo.maxCmaps = 520f66df612Smrg MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen)); 521f66df612Smrg Scr->cmapInfo.root_pushes = 0; 522f66df612Smrg InstallWindowColormaps(0, &Scr->TwmRoot); 523f66df612Smrg 524f66df612Smrg Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail = 525f66df612Smrg Scr->StdCmapInfo.mru = NULL; 526f66df612Smrg Scr->StdCmapInfo.mruindex = 0; 527f66df612Smrg LocateStandardColormaps(); 528f66df612Smrg 529f66df612Smrg Scr->TBInfo.nleft = Scr->TBInfo.nright = 0; 530f66df612Smrg Scr->TBInfo.head = NULL; 531f66df612Smrg Scr->TBInfo.border = 1; 532f66df612Smrg Scr->TBInfo.width = 0; 533f66df612Smrg Scr->TBInfo.leftx = 0; 534f66df612Smrg Scr->TBInfo.titlex = 0; 535f66df612Smrg 536f66df612Smrg Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum); 537f66df612Smrg Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum); 538f66df612Smrg Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth; 539f66df612Smrg Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight; 540f66df612Smrg 541f66df612Smrg Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1; 542f66df612Smrg 543f66df612Smrg if (DisplayCells(dpy, scrnum) < 3) 544f66df612Smrg Scr->Monochrome = MONOCHROME; 545f66df612Smrg else if (DefaultVisual(dpy, scrnum)->class == GrayScale) 546f66df612Smrg Scr->Monochrome = GRAYSCALE; 547f66df612Smrg else 548f66df612Smrg Scr->Monochrome = COLOR; 549f66df612Smrg 550f66df612Smrg /* setup default colors */ 551f66df612Smrg Scr->FirstTime = TRUE; 552f66df612Smrg GetColor(Scr->Monochrome, &black, "black"); 553f66df612Smrg Scr->Black = black; 554f66df612Smrg GetColor(Scr->Monochrome, &white, "white"); 555f66df612Smrg Scr->White = white; 556f66df612Smrg 557f66df612Smrg if (FirstScreen) { 558f66df612Smrg SetFocus((TwmWindow *) NULL, CurrentTime); 559f66df612Smrg 560f66df612Smrg /* define cursors */ 561f66df612Smrg 562f66df612Smrg NewFontCursor(&UpperLeftCursor, "top_left_corner"); 563f66df612Smrg NewFontCursor(&RightButt, "rightbutton"); 564f66df612Smrg NewFontCursor(&LeftButt, "leftbutton"); 565f66df612Smrg NewFontCursor(&MiddleButt, "middlebutton"); 566f66df612Smrg } 567f66df612Smrg 568f66df612Smrg Scr->iconmgr.x = 0; 569f66df612Smrg Scr->iconmgr.y = 0; 570f66df612Smrg Scr->iconmgr.width = 150; 571f66df612Smrg Scr->iconmgr.height = 5; 572f66df612Smrg Scr->iconmgr.next = NULL; 573f66df612Smrg Scr->iconmgr.prev = NULL; 574f66df612Smrg Scr->iconmgr.lasti = &(Scr->iconmgr); 575f66df612Smrg Scr->iconmgr.first = NULL; 576f66df612Smrg Scr->iconmgr.last = NULL; 577f66df612Smrg Scr->iconmgr.active = NULL; 578f66df612Smrg Scr->iconmgr.scr = Scr; 579f66df612Smrg Scr->iconmgr.columns = 1; 580f66df612Smrg Scr->iconmgr.count = 0; 581f66df612Smrg Scr->iconmgr.name = "TWM"; 582f66df612Smrg Scr->iconmgr.icon_name = "Icons"; 583f66df612Smrg 584f66df612Smrg Scr->IconDirectory = NULL; 585f66df612Smrg 586f66df612Smrg Scr->siconifyPm = None; 587f66df612Smrg Scr->pullPm = None; 588f66df612Smrg Scr->hilitePm = None; 589f66df612Smrg Scr->tbpm.xlogo = None; 590f66df612Smrg Scr->tbpm.resize = None; 591f66df612Smrg Scr->tbpm.question = None; 592f66df612Smrg Scr->tbpm.menu = None; 593f66df612Smrg Scr->tbpm.delete = None; 594f66df612Smrg 595f66df612Smrg InitVariables(); 596f66df612Smrg InitMenus(); 597f66df612Smrg 598f66df612Smrg /* Parse it once for each screen. */ 599f66df612Smrg ParseTwmrc(InitFile); 600f66df612Smrg assign_var_savecolor(); /* storing pixels for twmrc "entities" */ 601f66df612Smrg if (Scr->SqueezeTitle == -1) 602f66df612Smrg Scr->SqueezeTitle = FALSE; 603f66df612Smrg if (!Scr->HaveFonts) 604f66df612Smrg CreateFonts(); 605f66df612Smrg CreateGCs(); 606f66df612Smrg MakeMenus(); 607f66df612Smrg 608f66df612Smrg Scr->TitleBarFont.y += Scr->FramePadding; 609f66df612Smrg Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2; 610f66df612Smrg /* make title height be odd so buttons look nice and centered */ 611f66df612Smrg if (!(Scr->TitleHeight & 1)) 612f66df612Smrg Scr->TitleHeight++; 613f66df612Smrg 614f66df612Smrg InitTitlebarButtons(); /* menus are now loaded! */ 615f66df612Smrg 616f66df612Smrg XGrabServer(dpy); 617f66df612Smrg XSync(dpy, 0); 618f66df612Smrg 619f66df612Smrg JunkX = 0; 620f66df612Smrg JunkY = 0; 621f66df612Smrg 622f66df612Smrg XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren); 623f66df612Smrg CreateIconManagers(); 624f66df612Smrg if (!Scr->NoIconManagers) 625f66df612Smrg Scr->iconmgr.twm_win->icon = TRUE; 626f66df612Smrg 627f66df612Smrg /* 628f66df612Smrg * weed out icon windows 629f66df612Smrg */ 630f66df612Smrg for (i = 0; (unsigned) i < nchildren; i++) { 631f66df612Smrg if (children[i]) { 632f66df612Smrg XWMHints *wmhintsp = XGetWMHints(dpy, children[i]); 633f66df612Smrg 634f66df612Smrg if (wmhintsp) { 635f66df612Smrg if (wmhintsp->flags & IconWindowHint) { 636f66df612Smrg for (j = 0; (unsigned) j < nchildren; j++) { 637f66df612Smrg if (children[j] == wmhintsp->icon_window) { 638f66df612Smrg children[j] = None; 639f66df612Smrg break; 640f66df612Smrg } 641f66df612Smrg } 642f66df612Smrg } 643f66df612Smrg XFree(wmhintsp); 644f66df612Smrg } 645f66df612Smrg } 646f66df612Smrg } 647f66df612Smrg 648f66df612Smrg /* 649f66df612Smrg * map all of the non-override windows 650f66df612Smrg */ 651f66df612Smrg for (i = 0; (unsigned) i < nchildren; i++) { 652f66df612Smrg if (children[i] && MappedNotOverride(children[i])) { 653f66df612Smrg XUnmapWindow(dpy, children[i]); 654f66df612Smrg SimulateMapRequest(children[i]); 655f66df612Smrg } 656f66df612Smrg } 657f66df612Smrg 658f66df612Smrg if (Scr->ShowIconManager && !Scr->NoIconManagers) { 659f66df612Smrg Scr->iconmgr.twm_win->icon = FALSE; 660f66df612Smrg if (Scr->iconmgr.count) { 661f66df612Smrg SetMapStateProp(Scr->iconmgr.twm_win, NormalState); 662f66df612Smrg XMapWindow(dpy, Scr->iconmgr.w); 663f66df612Smrg XMapWindow(dpy, Scr->iconmgr.twm_win->frame); 664f66df612Smrg } 665f66df612Smrg } 666f66df612Smrg 667f66df612Smrg attributes.border_pixel = Scr->DefaultC.fore; 668f66df612Smrg attributes.background_pixel = Scr->DefaultC.back; 669f66df612Smrg attributes.event_mask = (ExposureMask | ButtonPressMask | 670f66df612Smrg KeyPressMask | ButtonReleaseMask); 671f66df612Smrg attributes.backing_store = NotUseful; 672f66df612Smrg attributes.cursor = XCreateFontCursor(dpy, XC_hand2); 673f66df612Smrg valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | 674f66df612Smrg CWBackingStore | CWCursor); 675f66df612Smrg Scr->InfoWindow = XCreateWindow(dpy, Scr->Root, 0, 0, 676f66df612Smrg (unsigned int) 5, (unsigned int) 5, 677f66df612Smrg (unsigned int) BW, 0, 678f66df612Smrg (unsigned int) CopyFromParent, 679f66df612Smrg (Visual *) CopyFromParent, 680f66df612Smrg valuemask, &attributes); 681f66df612Smrg 682f66df612Smrg Scr->SizeStringWidth = MyFont_TextWidth(&Scr->SizeFont, 683f66df612Smrg " 8888 x 8888 ", 13); 684f66df612Smrg valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity); 685f66df612Smrg attributes.bit_gravity = NorthWestGravity; 686f66df612Smrg Scr->SizeWindow = XCreateWindow(dpy, Scr->Root, 0, 0, 687f66df612Smrg (unsigned int) Scr->SizeStringWidth, 688f66df612Smrg (unsigned int) (Scr->SizeFont.height + 689f66df612Smrg SIZE_VINDENT * 2), 690f66df612Smrg (unsigned int) BW, 0, 691f66df612Smrg (unsigned int) CopyFromParent, 692f66df612Smrg (Visual *) CopyFromParent, 693f66df612Smrg valuemask, &attributes); 694f66df612Smrg 695f66df612Smrg XUngrabServer(dpy); 696f66df612Smrg 697f66df612Smrg FirstScreen = FALSE; 698f66df612Smrg Scr->FirstTime = FALSE; 699f66df612Smrg } /* for */ 7003e747e6dSmrg 7013e747e6dSmrg if (numManaged == 0) { 702f66df612Smrg if (MultiScreen && NumScreens > 0) { 703f66df612Smrg twmError("unable to find any unmanaged %sscreens.\n", 704f66df612Smrg NoPrintscreens ? "" : "video "); 705f66df612Smrg } 706f66df612Smrg exit(EXIT_FAILURE); 7073e747e6dSmrg } 7083e747e6dSmrg 709f66df612Smrg (void) ConnectToSessionManager(client_id); 7103e747e6dSmrg 7113e747e6dSmrg RestartPreviousState = False; 7123e747e6dSmrg HandlingEvents = TRUE; 7133e747e6dSmrg InitEvents(); 7143e747e6dSmrg HandleEvents(); 715f66df612Smrg exit(EXIT_SUCCESS); 7163e747e6dSmrg} 7173e747e6dSmrg 7183e747e6dSmrg/** 7193e747e6dSmrg * initialize twm variables 7203e747e6dSmrg */ 721c2535118Smrgstatic void 722c2535118SmrgInitVariables(void) 7233e747e6dSmrg{ 7243e747e6dSmrg FreeList(&Scr->BorderColorL); 7253e747e6dSmrg FreeList(&Scr->IconBorderColorL); 7263e747e6dSmrg FreeList(&Scr->BorderTileForegroundL); 7273e747e6dSmrg FreeList(&Scr->BorderTileBackgroundL); 7283e747e6dSmrg FreeList(&Scr->TitleForegroundL); 7293e747e6dSmrg FreeList(&Scr->TitleBackgroundL); 7303e747e6dSmrg FreeList(&Scr->IconForegroundL); 7313e747e6dSmrg FreeList(&Scr->IconBackgroundL); 7323e747e6dSmrg FreeList(&Scr->IconManagerFL); 7333e747e6dSmrg FreeList(&Scr->IconManagerBL); 7343e747e6dSmrg FreeList(&Scr->IconMgrs); 7353e747e6dSmrg FreeList(&Scr->NoTitle); 7363e747e6dSmrg FreeList(&Scr->MakeTitle); 7373e747e6dSmrg FreeList(&Scr->AutoRaise); 7383e747e6dSmrg FreeList(&Scr->IconNames); 7393e747e6dSmrg FreeList(&Scr->NoHighlight); 7403e747e6dSmrg FreeList(&Scr->NoStackModeL); 7413e747e6dSmrg FreeList(&Scr->NoTitleHighlight); 7423e747e6dSmrg FreeList(&Scr->DontIconify); 7433e747e6dSmrg FreeList(&Scr->IconMgrNoShow); 7443e747e6dSmrg FreeList(&Scr->IconMgrShow); 7453e747e6dSmrg FreeList(&Scr->IconifyByUn); 7463e747e6dSmrg FreeList(&Scr->StartIconified); 7473e747e6dSmrg FreeList(&Scr->IconManagerHighlightL); 7483e747e6dSmrg FreeList(&Scr->SqueezeTitleL); 7493e747e6dSmrg FreeList(&Scr->DontSqueezeTitleL); 7503e747e6dSmrg FreeList(&Scr->WindowRingL); 7513e747e6dSmrg FreeList(&Scr->WarpCursorL); 7523e747e6dSmrg 7533e747e6dSmrg NewFontCursor(&Scr->FrameCursor, "top_left_arrow"); 7543e747e6dSmrg NewFontCursor(&Scr->TitleCursor, "top_left_arrow"); 7553e747e6dSmrg NewFontCursor(&Scr->IconCursor, "top_left_arrow"); 7563e747e6dSmrg NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow"); 7573e747e6dSmrg NewFontCursor(&Scr->MoveCursor, "fleur"); 7583e747e6dSmrg NewFontCursor(&Scr->ResizeCursor, "fleur"); 7593e747e6dSmrg NewFontCursor(&Scr->MenuCursor, "sb_left_arrow"); 7603e747e6dSmrg NewFontCursor(&Scr->ButtonCursor, "hand2"); 7613e747e6dSmrg NewFontCursor(&Scr->WaitCursor, "watch"); 7623e747e6dSmrg NewFontCursor(&Scr->SelectCursor, "dot"); 7633e747e6dSmrg NewFontCursor(&Scr->DestroyCursor, "pirate"); 7643e747e6dSmrg 7653e747e6dSmrg Scr->Ring = NULL; 7663e747e6dSmrg Scr->RingLeader = NULL; 7673e747e6dSmrg 7683e747e6dSmrg Scr->DefaultC.fore = black; 7693e747e6dSmrg Scr->DefaultC.back = white; 7703e747e6dSmrg Scr->BorderColor = black; 7713e747e6dSmrg Scr->BorderTileC.fore = black; 7723e747e6dSmrg Scr->BorderTileC.back = white; 7733e747e6dSmrg Scr->TitleC.fore = black; 7743e747e6dSmrg Scr->TitleC.back = white; 7753e747e6dSmrg Scr->MenuC.fore = black; 7763e747e6dSmrg Scr->MenuC.back = white; 7773e747e6dSmrg Scr->MenuTitleC.fore = black; 7783e747e6dSmrg Scr->MenuTitleC.back = white; 7793e747e6dSmrg Scr->MenuShadowColor = black; 7803e747e6dSmrg Scr->MenuBorderColor = black; 7813e747e6dSmrg Scr->IconC.fore = black; 7823e747e6dSmrg Scr->IconC.back = white; 7833e747e6dSmrg Scr->IconBorderColor = black; 7843e747e6dSmrg Scr->PointerForeground.pixel = black; 7853e747e6dSmrg XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c, 786f66df612Smrg &Scr->PointerForeground); 7873e747e6dSmrg Scr->PointerBackground.pixel = white; 7883e747e6dSmrg XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c, 789f66df612Smrg &Scr->PointerBackground); 7903e747e6dSmrg Scr->IconManagerC.fore = black; 7913e747e6dSmrg Scr->IconManagerC.back = white; 7923e747e6dSmrg Scr->IconManagerHighlight = black; 7933e747e6dSmrg 794f66df612Smrg Scr->FramePadding = 2; /* values that look "nice" on */ 795f66df612Smrg Scr->TitlePadding = 8; /* 75 and 100dpi displays */ 7963e747e6dSmrg Scr->ButtonIndent = 1; 7973e747e6dSmrg Scr->SizeStringOffset = 0; 7983e747e6dSmrg Scr->BorderWidth = BW; 7993e747e6dSmrg Scr->IconBorderWidth = BW; 8003e747e6dSmrg Scr->MenuBorderWidth = BW; 8013e747e6dSmrg Scr->UnknownWidth = 0; 8023e747e6dSmrg Scr->UnknownHeight = 0; 8033e747e6dSmrg Scr->NumAutoRaises = 0; 8043e747e6dSmrg Scr->NoDefaults = FALSE; 8053e747e6dSmrg Scr->UsePPosition = PPOS_OFF; 8063e747e6dSmrg Scr->FocusRoot = TRUE; 8073e747e6dSmrg Scr->Focus = NULL; 8083e747e6dSmrg Scr->WarpCursor = FALSE; 8093e747e6dSmrg Scr->ForceIcon = FALSE; 8103e747e6dSmrg Scr->NoGrabServer = FALSE; 8113e747e6dSmrg Scr->NoRaiseMove = FALSE; 8123e747e6dSmrg Scr->NoRaiseResize = FALSE; 8133e747e6dSmrg Scr->NoRaiseDeicon = FALSE; 8143e747e6dSmrg Scr->NoRaiseWarp = FALSE; 8153e747e6dSmrg Scr->DontMoveOff = FALSE; 8163e747e6dSmrg Scr->DoZoom = FALSE; 8173e747e6dSmrg Scr->TitleFocus = TRUE; 8183e747e6dSmrg Scr->NoTitlebar = FALSE; 8193e747e6dSmrg Scr->DecorateTransients = FALSE; 8203e747e6dSmrg Scr->IconifyByUnmapping = FALSE; 8213e747e6dSmrg Scr->ShowIconManager = FALSE; 822f66df612Smrg Scr->IconManagerDontShow = FALSE; 8233e747e6dSmrg Scr->BackingStore = TRUE; 8243e747e6dSmrg Scr->SaveUnder = TRUE; 8253e747e6dSmrg Scr->RandomPlacement = FALSE; 8263e747e6dSmrg Scr->OpaqueMove = FALSE; 8273e747e6dSmrg Scr->Highlight = TRUE; 8283e747e6dSmrg Scr->StackMode = TRUE; 8293e747e6dSmrg Scr->TitleHighlight = TRUE; 830f66df612Smrg Scr->MoveDelta = 1; /* so that f.deltastop will work */ 8313e747e6dSmrg Scr->ZoomCount = 8; 8323e747e6dSmrg Scr->SortIconMgr = FALSE; 8333e747e6dSmrg Scr->Shadow = TRUE; 8343e747e6dSmrg Scr->InterpolateMenuColors = FALSE; 8353e747e6dSmrg Scr->NoIconManagers = FALSE; 8363e747e6dSmrg Scr->ClientBorderWidth = FALSE; 8373e747e6dSmrg Scr->SqueezeTitle = -1; 8383e747e6dSmrg Scr->FirstRegion = NULL; 8393e747e6dSmrg Scr->LastRegion = NULL; 8403e747e6dSmrg Scr->FirstTime = TRUE; 841f66df612Smrg Scr->HaveFonts = FALSE; /* i.e. not loaded yet */ 8423e747e6dSmrg Scr->CaseSensitive = TRUE; 8433e747e6dSmrg Scr->WarpUnmapped = FALSE; 8443e747e6dSmrg 8453e747e6dSmrg /* setup default fonts; overridden by defaults from system.twmrc */ 8463e747e6dSmrg#define DEFAULT_NICE_FONT "variable" 8473e747e6dSmrg#define DEFAULT_FAST_FONT "fixed" 8483e747e6dSmrg 8493e747e6dSmrg Scr->TitleBarFont.font = NULL; 8503e747e6dSmrg Scr->TitleBarFont.fontset = NULL; 8513e747e6dSmrg Scr->TitleBarFont.name = DEFAULT_NICE_FONT; 8523e747e6dSmrg Scr->MenuFont.font = NULL; 8533e747e6dSmrg Scr->MenuFont.fontset = NULL; 8543e747e6dSmrg Scr->MenuFont.name = DEFAULT_NICE_FONT; 8553e747e6dSmrg Scr->IconFont.font = NULL; 8563e747e6dSmrg Scr->IconFont.fontset = NULL; 8573e747e6dSmrg Scr->IconFont.name = DEFAULT_NICE_FONT; 8583e747e6dSmrg Scr->SizeFont.font = NULL; 8593e747e6dSmrg Scr->SizeFont.fontset = NULL; 8603e747e6dSmrg Scr->SizeFont.name = DEFAULT_FAST_FONT; 8613e747e6dSmrg Scr->IconManagerFont.font = NULL; 8623e747e6dSmrg Scr->IconManagerFont.fontset = NULL; 8633e747e6dSmrg Scr->IconManagerFont.name = DEFAULT_NICE_FONT; 8643e747e6dSmrg Scr->DefaultFont.font = NULL; 8653e747e6dSmrg Scr->DefaultFont.fontset = NULL; 8663e747e6dSmrg Scr->DefaultFont.name = DEFAULT_FAST_FONT; 8673e747e6dSmrg 8683e747e6dSmrg} 8693e747e6dSmrg 8703e747e6dSmrgvoid 871f66df612SmrgCreateFonts(void) 8723e747e6dSmrg{ 8733e747e6dSmrg GetFont(&Scr->TitleBarFont); 8743e747e6dSmrg GetFont(&Scr->MenuFont); 8753e747e6dSmrg GetFont(&Scr->IconFont); 8763e747e6dSmrg GetFont(&Scr->SizeFont); 8773e747e6dSmrg GetFont(&Scr->IconManagerFont); 8783e747e6dSmrg GetFont(&Scr->DefaultFont); 8793e747e6dSmrg Scr->HaveFonts = TRUE; 8803e747e6dSmrg} 8813e747e6dSmrg 8823e747e6dSmrgvoid 883f66df612SmrgRestoreWithdrawnLocation(TwmWindow *tmp) 8843e747e6dSmrg{ 8853e747e6dSmrg int gravx, gravy; 886f66df612Smrg unsigned int bw; 8873e747e6dSmrg XWindowChanges xwc; 8883e747e6dSmrg 889f66df612Smrg if (XGetGeometry(dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y, 890f66df612Smrg &JunkWidth, &JunkHeight, &bw, &JunkDepth)) { 891f66df612Smrg unsigned mask; 8923e747e6dSmrg 893f66df612Smrg GetGravityOffsets(tmp, &gravx, &gravy); 894f66df612Smrg if (gravy < 0) 895f66df612Smrg xwc.y -= tmp->title_height; 8963e747e6dSmrg 897f66df612Smrg if (bw != (unsigned) tmp->old_bw) { 898f66df612Smrg int xoff, yoff; 8993e747e6dSmrg 900f66df612Smrg if (!Scr->ClientBorderWidth) { 901f66df612Smrg xoff = gravx; 902f66df612Smrg yoff = gravy; 903f66df612Smrg } 904f66df612Smrg else { 905f66df612Smrg xoff = 0; 906f66df612Smrg yoff = 0; 907f66df612Smrg } 9083e747e6dSmrg 909f66df612Smrg xwc.x -= (xoff + 1) * tmp->old_bw; 910f66df612Smrg xwc.y -= (yoff + 1) * tmp->old_bw; 911f66df612Smrg } 912f66df612Smrg if (!Scr->ClientBorderWidth) { 913f66df612Smrg xwc.x += gravx * tmp->frame_bw; 914f66df612Smrg xwc.y += gravy * tmp->frame_bw; 915f66df612Smrg } 9163e747e6dSmrg 917f66df612Smrg mask = (CWX | CWY); 918f66df612Smrg if (bw != (unsigned) tmp->old_bw) { 919f66df612Smrg xwc.border_width = tmp->old_bw; 920f66df612Smrg mask |= CWBorderWidth; 921f66df612Smrg } 9223e747e6dSmrg 923f66df612Smrg XConfigureWindow(dpy, tmp->w, mask, &xwc); 9243e747e6dSmrg 925f66df612Smrg if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) { 926f66df612Smrg XUnmapWindow(dpy, tmp->wmhints->icon_window); 927f66df612Smrg } 9283e747e6dSmrg 9293e747e6dSmrg } 9303e747e6dSmrg} 9313e747e6dSmrg 932ffd25bcaSmrgvoid 933f66df612SmrgReborder(Time time) 9343e747e6dSmrg{ 935f66df612Smrg TwmWindow *tmp; /* temp twm window structure */ 9363e747e6dSmrg int scrnum; 9373e747e6dSmrg 9383e747e6dSmrg /* put a border back around all windows */ 9393e747e6dSmrg 940f66df612Smrg XGrabServer(dpy); 941f66df612Smrg for (scrnum = 0; scrnum < NumScreens; scrnum++) { 942f66df612Smrg if ((Scr = ScreenList[scrnum]) == NULL) 943f66df612Smrg continue; 944f66df612Smrg 945f66df612Smrg InstallWindowColormaps(0, &Scr->TwmRoot); /* force reinstall */ 946f66df612Smrg for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next) { 947f66df612Smrg RestoreWithdrawnLocation(tmp); 948f66df612Smrg XMapWindow(dpy, tmp->w); 949f66df612Smrg } 9503e747e6dSmrg } 9513e747e6dSmrg 952f66df612Smrg XUngrabServer(dpy); 953f66df612Smrg SetFocus((TwmWindow *) NULL, time); 9543e747e6dSmrg} 9553e747e6dSmrg 956c2535118Smrgstatic void 957f66df612SmrgsigHandler(int sig _X_UNUSED) 9583e747e6dSmrg{ 9593e747e6dSmrg XtNoticeSignal(si); 9603e747e6dSmrg} 9613e747e6dSmrg 9623e747e6dSmrg/** 9633e747e6dSmrg * cleanup and exit twm 9643e747e6dSmrg */ 9653e747e6dSmrgvoid 966f66df612SmrgDone(XtPointer client_data _X_UNUSED, XtSignalId *si2 _X_UNUSED) 9673e747e6dSmrg{ 968f66df612Smrg if (dpy) { 969f66df612Smrg Reborder(CurrentTime); 970f66df612Smrg XCloseDisplay(dpy); 9713e747e6dSmrg } 972f66df612Smrg exit(EXIT_SUCCESS); 9733e747e6dSmrg} 9743e747e6dSmrg 9753e747e6dSmrg/* 9763e747e6dSmrg * Error Handlers. If a client dies, we'll get a BadWindow error (except for 9773e747e6dSmrg * GetGeometry which returns BadDrawable) for most operations that we do before 9783e747e6dSmrg * manipulating the client's window. 9793e747e6dSmrg */ 9803e747e6dSmrg 9813e747e6dSmrgBool ErrorOccurred = False; 9823e747e6dSmrgXErrorEvent LastErrorEvent; 9833e747e6dSmrg 984ffd25bcaSmrgstatic int 985f66df612SmrgTwmErrorHandler(Display *dpy2, XErrorEvent *event) 9863e747e6dSmrg{ 9873e747e6dSmrg LastErrorEvent = *event; 9883e747e6dSmrg ErrorOccurred = True; 9893e747e6dSmrg 990f66df612Smrg if ((message_level > 1) && /* don't be too obnoxious */ 991f66df612Smrg event->error_code != BadWindow && /* watch for dead puppies */ 992f66df612Smrg (event->request_code != X_GetGeometry && /* of all styles */ 993f66df612Smrg event->error_code != BadDrawable)) 994f66df612Smrg XmuPrintDefaultErrorMessage(dpy2, event, stderr); 9953e747e6dSmrg return 0; 9963e747e6dSmrg} 9973e747e6dSmrg 998ffd25bcaSmrgstatic int 999f66df612SmrgCatchRedirectError(Display *dpy2 _X_UNUSED, XErrorEvent *event) 10003e747e6dSmrg{ 10013e747e6dSmrg RedirectError = TRUE; 10023e747e6dSmrg LastErrorEvent = *event; 10033e747e6dSmrg ErrorOccurred = True; 10043e747e6dSmrg return 0; 10053e747e6dSmrg} 1006f66df612Smrg 1007f66df612Smrgvoid 1008f66df612SmrgtwmError(const char *format, ...) 1009f66df612Smrg{ 1010f66df612Smrg va_list ap; 1011f66df612Smrg 1012f66df612Smrg va_start(ap, format); 1013f66df612Smrg fprintf(stderr, "%s: error: ", ProgramName); 1014f66df612Smrg vfprintf(stderr, format, ap); 1015f66df612Smrg fputc('\n', stderr); 1016f66df612Smrg va_end(ap); 1017f66df612Smrg exit(EXIT_FAILURE); 1018f66df612Smrg} 1019f66df612Smrg 1020f66df612Smrgvoid 1021f66df612SmrgtwmWarning(const char *format, ...) 1022f66df612Smrg{ 1023f66df612Smrg if (message_level > 0) { 1024f66df612Smrg va_list ap; 1025f66df612Smrg 1026f66df612Smrg va_start(ap, format); 1027f66df612Smrg fprintf(stderr, "%s: warning: ", ProgramName); 1028f66df612Smrg vfprintf(stderr, format, ap); 1029f66df612Smrg fputc('\n', stderr); 1030f66df612Smrg va_end(ap); 1031f66df612Smrg } 1032f66df612Smrg} 1033f66df612Smrg 1034f66df612Smrgvoid 1035f66df612SmrgtwmVerbose(const char *format, ...) 1036f66df612Smrg{ 1037f66df612Smrg if (message_level > 1) { 1038f66df612Smrg va_list ap; 1039f66df612Smrg 1040f66df612Smrg va_start(ap, format); 1041f66df612Smrg fprintf(stderr, "%s: warning: ", ProgramName); 1042f66df612Smrg vfprintf(stderr, format, ap); 1043f66df612Smrg fputc('\n', stderr); 1044f66df612Smrg va_end(ap); 1045f66df612Smrg } 1046f66df612Smrg} 1047f66df612Smrg 1048f66df612Smrgvoid 1049f66df612SmrgtwmMessage(const char *format, ...) 1050f66df612Smrg{ 1051f66df612Smrg va_list ap; 1052f66df612Smrg 1053f66df612Smrg va_start(ap, format); 1054f66df612Smrg printf("%s: ", ProgramName); 1055f66df612Smrg vprintf(format, ap); 1056f66df612Smrg putc('\n', stdout); 1057f66df612Smrg va_end(ap); 1058f66df612Smrg 1059f66df612Smrg fflush(stdout); 1060f66df612Smrg} 1061