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 "screen.h" 763e747e6dSmrg#include "parse.h" 773e747e6dSmrg#include "session.h" 78f66df612Smrg 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> 85f66df612Smrg 86f66df612Smrg#ifdef HAVE_XRANDR 87f66df612Smrg#include <X11/extensions/Xrandr.h> 88f66df612Smrg#endif 893e747e6dSmrg 90f66df612Smrgstatic void InitVariables(void); 91c2535118Smrg 926d8e82c3Smrgstatic XtSignalId si; 933e747e6dSmrg 94f66df612SmrgDisplay *dpy = NULL; /* which display are we talking to */ 95f66df612SmrgWindow ResizeWindow; /* the window we are resizing */ 963e747e6dSmrg 97f66df612Smrgint NumScreens; /* number of screens in ScreenList */ 98f66df612Smrgint HasShape; /* server supports shape extension? */ 99f66df612Smrg 100f66df612Smrg#ifdef HAVE_XRANDR 101f66df612Smrgint HasXrandr; /* server supports Xrandr extension? */ 102f66df612Smrgint XrandrEventBase, XrandrErrorBase; 103f66df612Smrg#endif 104f66df612Smrg 1053e747e6dSmrgint ShapeEventBase, ShapeErrorBase; 106f66df612Smrgint HasSync; /* server supports SYNC extension? */ 1073e747e6dSmrgint SyncEventBase, SyncErrorBase; 108f66df612SmrgScreenInfo **ScreenList; /* structures for each screen */ 109f66df612SmrgScreenInfo *Scr = NULL; /* the cur and prev screens */ 110f66df612Smrgint PreviousScreen; /* last screen that we were on */ 111f66df612Smrgint message_level = 1; /* controls error messages */ 112f66df612Smrgstatic int RedirectError; /* TRUE ==> another window manager running */ 113f66df612Smrgstatic int TwmErrorHandler(Display *dpy, XErrorEvent *event); /* for setting RedirectError */ 114f66df612Smrgstatic int CatchRedirectError(Display *dpy, XErrorEvent *event); /* for everything else */ 115c2535118Smrgstatic void sigHandler(int); 116f66df612Smrgchar Info[INFO_LINES][INFO_SIZE]; /* info strings to print */ 1173e747e6dSmrgint InfoLines; 1183e747e6dSmrg 119f66df612SmrgCursor UpperLeftCursor; /* upper Left corner cursor */ 1203e747e6dSmrgCursor RightButt; 1213e747e6dSmrgCursor MiddleButt; 1223e747e6dSmrgCursor LeftButt; 1233e747e6dSmrg 124f66df612SmrgXContext TwmContext; /* context for twm windows */ 125f66df612SmrgXContext MenuContext; /* context for all menu windows */ 126f66df612SmrgXContext IconManagerContext; /* context for all window list windows */ 127f66df612SmrgXContext ScreenContext; /* context to get screen data */ 128f66df612SmrgXContext ColormapContext; /* context for colormap operations */ 1293e747e6dSmrg 130f66df612SmrgXClassHint NoClass; /* for applications with no class */ 1313e747e6dSmrg 1323e747e6dSmrgXGCValues Gcv; 1333e747e6dSmrg 134f66df612Smrgconst char *Home; /* the HOME environment variable */ 135f66df612Smrgint HomeLen; /* length of Home */ 136f66df612Smrgint ParseError; /* error parsing the .twmrc file */ 1373e747e6dSmrg 138f66df612Smrgint HandlingEvents = FALSE; /* are we handling events yet? */ 1393e747e6dSmrg 1403e747e6dSmrgchar *ProgramName; 1413e747e6dSmrgint Argc; 1423e747e6dSmrgchar **Argv; 1433e747e6dSmrg 144f66df612SmrgBool RestartPreviousState = False; /* try to restart in previous state */ 1453e747e6dSmrg 146c2535118Smrgstatic unsigned long black, white; 1473e747e6dSmrg 1483e747e6dSmrgAtom TwmAtoms[11]; 1493e747e6dSmrg 150f66df612SmrgBool use_fontset; /* use XFontSet-related functions or not */ 1513e747e6dSmrg 1523e747e6dSmrg/* don't change the order of these strings */ 1536d8e82c3Smrgstatic const char *atom_names[11] = { 1543e747e6dSmrg "_MIT_PRIORITY_COLORS", 1553e747e6dSmrg "WM_CHANGE_STATE", 1563e747e6dSmrg "WM_STATE", 1573e747e6dSmrg "WM_COLORMAP_WINDOWS", 1583e747e6dSmrg "WM_PROTOCOLS", 1593e747e6dSmrg "WM_TAKE_FOCUS", 1603e747e6dSmrg "WM_SAVE_YOURSELF", 1613e747e6dSmrg "WM_DELETE_WINDOW", 1623e747e6dSmrg "SM_CLIENT_ID", 1633e747e6dSmrg "WM_CLIENT_LEADER", 1643e747e6dSmrg "WM_WINDOW_ROLE" 1653e747e6dSmrg}; 1663e747e6dSmrg 1676d8e82c3Smrgstatic _X_NORETURN void 168f66df612Smrgusage(void) 169f66df612Smrg{ 170f66df612Smrg fprintf(stderr, "usage: %s [-display dpy] [-f file] [-s] [-q] [-v] [-V]" 171f66df612Smrg " [-clientId id] [-restore file]\n", ProgramName); 172f66df612Smrg exit(EXIT_FAILURE); 173f66df612Smrg} 174f66df612Smrg 175f66df612Smrgstatic Bool 176f66df612Smrgbrief_opt(const char *param, const char *option) 177f66df612Smrg{ 178f66df612Smrg size_t have = strlen(++param); 179f66df612Smrg size_t want = strlen(option); 180f66df612Smrg Bool result = False; 181f66df612Smrg 182f66df612Smrg if (have <= want) { 183f66df612Smrg if (!strncmp(param, option, have)) 184f66df612Smrg result = True; 185f66df612Smrg } 186f66df612Smrg return result; 187f66df612Smrg} 1883e747e6dSmrg 1893e747e6dSmrg/*********************************************************************** 1903e747e6dSmrg * 1913e747e6dSmrg * Procedure: 192f66df612Smrg * main - start of twm 1933e747e6dSmrg * 1943e747e6dSmrg *********************************************************************** 1953e747e6dSmrg */ 1963e747e6dSmrg 1973e747e6dSmrgint 1983e747e6dSmrgmain(int argc, char *argv[]) 1993e747e6dSmrg{ 2003e747e6dSmrg Window root, parent, *children; 2013e747e6dSmrg unsigned int nchildren; 2023e747e6dSmrg int i, j; 2033e747e6dSmrg char *display_name = NULL; 204f66df612Smrg unsigned long valuemask; /* mask for create windows */ 205f66df612Smrg XSetWindowAttributes attributes; /* attributes for create windows */ 2063e747e6dSmrg int numManaged, firstscrn, lastscrn, scrnum; 2073e747e6dSmrg int zero = 0; 2083e747e6dSmrg char *restore_filename = NULL; 2093e747e6dSmrg char *client_id = NULL; 2103e747e6dSmrg char *loc; 2116d8e82c3Smrg int MultiScreen = TRUE; /* try for more than one screen? */ 2126d8e82c3Smrg char *InitFile = NULL; 2136d8e82c3Smrg XtAppContext appContext; /* Xt application context */ 2143e747e6dSmrg 2153e747e6dSmrg ProgramName = argv[0]; 2163e747e6dSmrg Argc = argc; 2173e747e6dSmrg Argv = argv; 2183e747e6dSmrg 2193e747e6dSmrg for (i = 1; i < argc; i++) { 220f66df612Smrg if (argv[i][0] == '-') { 221f66df612Smrg switch (argv[i][1]) { 222f66df612Smrg case 'V': 223f66df612Smrg printf("%s %s\n", APP_NAME, APP_VERSION); 224f66df612Smrg exit(EXIT_SUCCESS); 225f66df612Smrg case 'd': /* -display dpy */ 226f66df612Smrg if (!brief_opt(argv[i], "display")) 227f66df612Smrg usage(); 228f66df612Smrg if (++i >= argc) 229f66df612Smrg usage(); 230f66df612Smrg display_name = argv[i]; 231f66df612Smrg continue; 232f66df612Smrg case 's': /* -single */ 233f66df612Smrg if (!brief_opt(argv[i], "single")) 234f66df612Smrg usage(); 235f66df612Smrg MultiScreen = FALSE; 236f66df612Smrg continue; 237f66df612Smrg case 'f': /* -file twmrcfilename */ 238f66df612Smrg if (!brief_opt(argv[i], "file")) 239f66df612Smrg usage(); 240f66df612Smrg if (++i >= argc) 241f66df612Smrg usage(); 242f66df612Smrg InitFile = argv[i]; 243f66df612Smrg continue; 244f66df612Smrg case 'v': /* -verbose */ 245f66df612Smrg if (!brief_opt(argv[i], "verbose")) 246f66df612Smrg usage(); 247f66df612Smrg message_level++; 248f66df612Smrg continue; 249f66df612Smrg case 'c': /* -clientId */ 250f66df612Smrg if (!brief_opt(argv[i], "clientId")) 251f66df612Smrg usage(); 252f66df612Smrg if (++i >= argc) 253f66df612Smrg usage(); 254f66df612Smrg client_id = argv[i]; 255f66df612Smrg continue; 256f66df612Smrg case 'r': /* -restore */ 257f66df612Smrg if (!brief_opt(argv[i], "restore")) 258f66df612Smrg usage(); 259f66df612Smrg if (++i >= argc) 260f66df612Smrg usage(); 261f66df612Smrg restore_filename = argv[i]; 262f66df612Smrg continue; 263f66df612Smrg case 'q': /* -quiet */ 264f66df612Smrg if (!brief_opt(argv[i], "quiet")) 265f66df612Smrg usage(); 266f66df612Smrg --message_level; 267f66df612Smrg continue; 268f66df612Smrg } 269f66df612Smrg } 270f66df612Smrg usage(); 2713e747e6dSmrg } 2723e747e6dSmrg 2733e747e6dSmrg loc = setlocale(LC_ALL, ""); 2743e747e6dSmrg if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") || 275f66df612Smrg !XSupportsLocale()) { 276f66df612Smrg use_fontset = False; 277f66df612Smrg } 278f66df612Smrg else { 279f66df612Smrg use_fontset = True; 2803e747e6dSmrg } 2813e747e6dSmrg 2823e747e6dSmrg#define newhandler(sig) \ 2833e747e6dSmrg if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, sigHandler) 2843e747e6dSmrg 285f66df612Smrg newhandler(SIGINT); 286f66df612Smrg newhandler(SIGHUP); 287f66df612Smrg newhandler(SIGQUIT); 288f66df612Smrg newhandler(SIGTERM); 2893e747e6dSmrg 2903e747e6dSmrg#undef newhandler 2913e747e6dSmrg 2923e747e6dSmrg Home = getenv("HOME"); 2933e747e6dSmrg if (Home != NULL) { 294f66df612Smrg char *temp_p; 2953e747e6dSmrg 296f66df612Smrg /* 297f66df612Smrg * Make a copy of Home because the string returned by getenv() can be 298f66df612Smrg * overwritten by some POSIX.1 and ANSI-C implementations of getenv() 299f66df612Smrg * when further calls to getenv() are made 300f66df612Smrg */ 3013e747e6dSmrg 302f66df612Smrg temp_p = strdup(Home); 303f66df612Smrg Home = temp_p; 3043e747e6dSmrg } 3053e747e6dSmrg 3063e747e6dSmrg if (Home == NULL) 307f66df612Smrg Home = "./"; 3083e747e6dSmrg 309f66df612Smrg HomeLen = (int) strlen(Home); 3103e747e6dSmrg 3113e747e6dSmrg NoClass.res_name = NoName; 3123e747e6dSmrg NoClass.res_class = NoName; 3133e747e6dSmrg 314f66df612Smrg XtToolkitInitialize(); 315f66df612Smrg appContext = XtCreateApplicationContext(); 3163e747e6dSmrg 3173e747e6dSmrg si = XtAppAddSignal(appContext, Done, NULL); 318ffd25bcaSmrg 3196d8e82c3Smrg if (!(dpy = XtOpenDisplay(appContext, display_name, APP_NAME, APP_CLASS, 320f66df612Smrg NULL, 0, &zero, NULL))) { 321f66df612Smrg twmError("unable to open display \"%s\"", XDisplayName(display_name)); 3223e747e6dSmrg } 3233e747e6dSmrg 3243e747e6dSmrg if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) { 325f66df612Smrg twmError("unable to mark display connection as close-on-exec"); 3263e747e6dSmrg } 3273e747e6dSmrg 3283e747e6dSmrg if (restore_filename) 329f66df612Smrg ReadWinConfigFile(restore_filename); 3303e747e6dSmrg 331f66df612Smrg HasShape = XShapeQueryExtension(dpy, &ShapeEventBase, &ShapeErrorBase); 332f66df612Smrg HasSync = XSyncQueryExtension(dpy, &SyncEventBase, &SyncErrorBase); 333f66df612Smrg#ifdef HAVE_XRANDR 334f66df612Smrg HasXrandr = XRRQueryExtension(dpy, &XrandrEventBase, &XrandrErrorBase); 335f66df612Smrg#endif 3363e747e6dSmrg TwmContext = XUniqueContext(); 3373e747e6dSmrg MenuContext = XUniqueContext(); 3383e747e6dSmrg IconManagerContext = XUniqueContext(); 3393e747e6dSmrg ScreenContext = XUniqueContext(); 3403e747e6dSmrg ColormapContext = XUniqueContext(); 3413e747e6dSmrg 3426d8e82c3Smrg (void) XInternAtoms(dpy, (char **) atom_names, 3436d8e82c3Smrg sizeof TwmAtoms / sizeof TwmAtoms[0], 344f66df612Smrg False, TwmAtoms); 3453e747e6dSmrg 3463e747e6dSmrg /* Set up the per-screen global information. */ 3473e747e6dSmrg 3483e747e6dSmrg NumScreens = ScreenCount(dpy); 3493e747e6dSmrg 350f66df612Smrg if (MultiScreen) { 351f66df612Smrg firstscrn = 0; 352f66df612Smrg lastscrn = NumScreens - 1; 3533e747e6dSmrg } 354f66df612Smrg else { 355f66df612Smrg firstscrn = lastscrn = DefaultScreen(dpy); 3563e747e6dSmrg } 3573e747e6dSmrg 3583e747e6dSmrg InfoLines = 0; 3593e747e6dSmrg 3603e747e6dSmrg /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */ 3616d8e82c3Smrg ScreenList = (ScreenInfo **) 3626d8e82c3Smrg calloc((size_t) NumScreens, sizeof(ScreenInfo *)); 363f66df612Smrg if (ScreenList == NULL) { 364f66df612Smrg twmError("Unable to allocate memory for screen list, exiting"); 3653e747e6dSmrg } 3663e747e6dSmrg numManaged = 0; 3673e747e6dSmrg PreviousScreen = DefaultScreen(dpy); 368f66df612Smrg for (scrnum = firstscrn; scrnum <= lastscrn; scrnum++) { 3696d8e82c3Smrg Bool FirstScreen = scrnum == firstscrn; 3703e747e6dSmrg 3713e747e6dSmrg /* Make sure property priority colors is empty */ 372f66df612Smrg XChangeProperty(dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS, 373f66df612Smrg XA_CARDINAL, 32, PropModeReplace, NULL, 0); 374f66df612Smrg RedirectError = FALSE; 375f66df612Smrg XSetErrorHandler(CatchRedirectError); 376f66df612Smrg XSelectInput(dpy, RootWindow(dpy, scrnum), 377f66df612Smrg ColormapChangeMask | EnterWindowMask | PropertyChangeMask | 378f66df612Smrg SubstructureRedirectMask | KeyPressMask | 379f66df612Smrg ButtonPressMask | ButtonReleaseMask); 380f66df612Smrg XSync(dpy, 0); 381f66df612Smrg XSetErrorHandler(TwmErrorHandler); 382f66df612Smrg 383f66df612Smrg if (RedirectError) { 384f66df612Smrg if (MultiScreen && NumScreens > 0) { 385f66df612Smrg twmWarning("another window manager is already running." 386f66df612Smrg " on screen %d?\n", scrnum); 387f66df612Smrg } 388f66df612Smrg else { 389f66df612Smrg twmWarning("another window manager is already running."); 390f66df612Smrg } 391f66df612Smrg continue; 392f66df612Smrg } 393f66df612Smrg 394f66df612Smrg numManaged++; 395f66df612Smrg 396f66df612Smrg /* Note: ScreenInfo struct is calloc'ed to initialize to zero. */ 3976d8e82c3Smrg Scr = ScreenList[scrnum] = (ScreenInfo *) calloc(1, sizeof(ScreenInfo)); 398f66df612Smrg if (Scr == NULL) { 399f66df612Smrg twmWarning 400f66df612Smrg ("unable to allocate memory for ScreenInfo structure for screen %d.", 401f66df612Smrg scrnum); 402f66df612Smrg continue; 403f66df612Smrg } 404f66df612Smrg 405f66df612Smrg /* initialize list pointers, remember to put an initialization 406f66df612Smrg * in InitVariables also 407f66df612Smrg */ 408f66df612Smrg Scr->BorderColorL = NULL; 409f66df612Smrg Scr->IconBorderColorL = NULL; 410f66df612Smrg Scr->BorderTileForegroundL = NULL; 411f66df612Smrg Scr->BorderTileBackgroundL = NULL; 412f66df612Smrg Scr->TitleForegroundL = NULL; 413f66df612Smrg Scr->TitleBackgroundL = NULL; 414f66df612Smrg Scr->IconForegroundL = NULL; 415f66df612Smrg Scr->IconBackgroundL = NULL; 416f66df612Smrg Scr->NoTitle = NULL; 417f66df612Smrg Scr->MakeTitle = NULL; 418f66df612Smrg Scr->AutoRaise = NULL; 419f66df612Smrg Scr->IconNames = NULL; 420f66df612Smrg Scr->NoHighlight = NULL; 421f66df612Smrg Scr->NoStackModeL = NULL; 422f66df612Smrg Scr->NoTitleHighlight = NULL; 423f66df612Smrg Scr->DontIconify = NULL; 424f66df612Smrg Scr->IconMgrNoShow = NULL; 425f66df612Smrg Scr->IconMgrShow = NULL; 426f66df612Smrg Scr->IconifyByUn = NULL; 427f66df612Smrg Scr->IconManagerFL = NULL; 428f66df612Smrg Scr->IconManagerBL = NULL; 429f66df612Smrg Scr->IconMgrs = NULL; 430f66df612Smrg Scr->StartIconified = NULL; 431f66df612Smrg Scr->SqueezeTitleL = NULL; 432f66df612Smrg Scr->DontSqueezeTitleL = NULL; 433f66df612Smrg Scr->WindowRingL = NULL; 434f66df612Smrg Scr->WarpCursorL = NULL; 435f66df612Smrg /* remember to put an initialization in InitVariables also 436f66df612Smrg */ 437f66df612Smrg 438f66df612Smrg Scr->screen = scrnum; 439f66df612Smrg Scr->d_depth = DefaultDepth(dpy, scrnum); 440f66df612Smrg Scr->d_visual = DefaultVisual(dpy, scrnum); 441f66df612Smrg Scr->Root = RootWindow(dpy, scrnum); 442f66df612Smrg XSaveContext(dpy, Scr->Root, ScreenContext, (XPointer) Scr); 443f66df612Smrg 444f66df612Smrg Scr->TwmRoot.cmaps.number_cwins = 1; 4456d8e82c3Smrg Scr->TwmRoot.cmaps.cwins = (ColormapWindow **) 4466d8e82c3Smrg malloc(sizeof(ColormapWindow *)); 447f66df612Smrg Scr->TwmRoot.cmaps.cwins[0] = 448f66df612Smrg CreateColormapWindow(Scr->Root, True, False); 449f66df612Smrg Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured; 450f66df612Smrg 451f66df612Smrg Scr->cmapInfo.cmaps = NULL; 452f66df612Smrg Scr->cmapInfo.maxCmaps = 453f66df612Smrg MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen)); 454f66df612Smrg Scr->cmapInfo.root_pushes = 0; 455f66df612Smrg InstallWindowColormaps(0, &Scr->TwmRoot); 456f66df612Smrg 457f66df612Smrg Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail = 458f66df612Smrg Scr->StdCmapInfo.mru = NULL; 459f66df612Smrg Scr->StdCmapInfo.mruindex = 0; 460f66df612Smrg LocateStandardColormaps(); 461f66df612Smrg 462f66df612Smrg Scr->TBInfo.nleft = Scr->TBInfo.nright = 0; 463f66df612Smrg Scr->TBInfo.head = NULL; 464f66df612Smrg Scr->TBInfo.border = 1; 465f66df612Smrg Scr->TBInfo.width = 0; 466f66df612Smrg Scr->TBInfo.leftx = 0; 467f66df612Smrg Scr->TBInfo.titlex = 0; 468f66df612Smrg 469f66df612Smrg Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum); 470f66df612Smrg Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum); 471f66df612Smrg Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth; 472f66df612Smrg Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight; 473f66df612Smrg 474f66df612Smrg Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1; 475f66df612Smrg 476f66df612Smrg if (DisplayCells(dpy, scrnum) < 3) 477f66df612Smrg Scr->Monochrome = MONOCHROME; 4786d8e82c3Smrg#if defined(__cplusplus) || defined(c_plusplus) 4796d8e82c3Smrg else if (DefaultVisual(dpy, scrnum)->c_class == GrayScale) 4806d8e82c3Smrg#else 481f66df612Smrg else if (DefaultVisual(dpy, scrnum)->class == GrayScale) 4826d8e82c3Smrg#endif 483f66df612Smrg Scr->Monochrome = GRAYSCALE; 484f66df612Smrg else 485f66df612Smrg Scr->Monochrome = COLOR; 486f66df612Smrg 487f66df612Smrg /* setup default colors */ 488f66df612Smrg Scr->FirstTime = TRUE; 489f66df612Smrg GetColor(Scr->Monochrome, &black, "black"); 490f66df612Smrg Scr->Black = black; 491f66df612Smrg GetColor(Scr->Monochrome, &white, "white"); 492f66df612Smrg Scr->White = white; 493f66df612Smrg 494f66df612Smrg if (FirstScreen) { 495f66df612Smrg SetFocus((TwmWindow *) NULL, CurrentTime); 496f66df612Smrg 497f66df612Smrg /* define cursors */ 498f66df612Smrg 499f66df612Smrg NewFontCursor(&UpperLeftCursor, "top_left_corner"); 500f66df612Smrg NewFontCursor(&RightButt, "rightbutton"); 501f66df612Smrg NewFontCursor(&LeftButt, "leftbutton"); 502f66df612Smrg NewFontCursor(&MiddleButt, "middlebutton"); 503f66df612Smrg } 504f66df612Smrg 505f66df612Smrg Scr->iconmgr.x = 0; 506f66df612Smrg Scr->iconmgr.y = 0; 507f66df612Smrg Scr->iconmgr.width = 150; 508f66df612Smrg Scr->iconmgr.height = 5; 509f66df612Smrg Scr->iconmgr.next = NULL; 510f66df612Smrg Scr->iconmgr.prev = NULL; 511f66df612Smrg Scr->iconmgr.lasti = &(Scr->iconmgr); 512f66df612Smrg Scr->iconmgr.first = NULL; 513f66df612Smrg Scr->iconmgr.last = NULL; 514f66df612Smrg Scr->iconmgr.active = NULL; 515f66df612Smrg Scr->iconmgr.scr = Scr; 516f66df612Smrg Scr->iconmgr.columns = 1; 517f66df612Smrg Scr->iconmgr.count = 0; 518f66df612Smrg Scr->iconmgr.name = "TWM"; 519f66df612Smrg Scr->iconmgr.icon_name = "Icons"; 520f66df612Smrg 521f66df612Smrg Scr->IconDirectory = NULL; 522f66df612Smrg 523f66df612Smrg Scr->siconifyPm = None; 524f66df612Smrg Scr->pullPm = None; 525f66df612Smrg Scr->hilitePm = None; 526f66df612Smrg Scr->tbpm.xlogo = None; 527f66df612Smrg Scr->tbpm.resize = None; 528f66df612Smrg Scr->tbpm.question = None; 529f66df612Smrg Scr->tbpm.menu = None; 5306d8e82c3Smrg Scr->tbpm.remove = None; 531f66df612Smrg 532f66df612Smrg InitVariables(); 533f66df612Smrg InitMenus(); 5346d8e82c3Smrg if (FirstScreen) 5356d8e82c3Smrg InitMenusFirst(); 536f66df612Smrg 537f66df612Smrg /* Parse it once for each screen. */ 538f66df612Smrg ParseTwmrc(InitFile); 539f66df612Smrg assign_var_savecolor(); /* storing pixels for twmrc "entities" */ 540f66df612Smrg if (Scr->SqueezeTitle == -1) 541f66df612Smrg Scr->SqueezeTitle = FALSE; 542f66df612Smrg if (!Scr->HaveFonts) 543f66df612Smrg CreateFonts(); 544f66df612Smrg CreateGCs(); 545f66df612Smrg MakeMenus(); 546f66df612Smrg 547f66df612Smrg Scr->TitleBarFont.y += Scr->FramePadding; 548f66df612Smrg Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2; 549f66df612Smrg /* make title height be odd so buttons look nice and centered */ 550f66df612Smrg if (!(Scr->TitleHeight & 1)) 551f66df612Smrg Scr->TitleHeight++; 552f66df612Smrg 553f66df612Smrg InitTitlebarButtons(); /* menus are now loaded! */ 554f66df612Smrg 555f66df612Smrg XGrabServer(dpy); 556f66df612Smrg XSync(dpy, 0); 557f66df612Smrg 558f66df612Smrg XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren); 559f66df612Smrg CreateIconManagers(); 560f66df612Smrg if (!Scr->NoIconManagers) 561f66df612Smrg Scr->iconmgr.twm_win->icon = TRUE; 562f66df612Smrg 563f66df612Smrg /* 564f66df612Smrg * weed out icon windows 565f66df612Smrg */ 566f66df612Smrg for (i = 0; (unsigned) i < nchildren; i++) { 567f66df612Smrg if (children[i]) { 568f66df612Smrg XWMHints *wmhintsp = XGetWMHints(dpy, children[i]); 569f66df612Smrg 570f66df612Smrg if (wmhintsp) { 571f66df612Smrg if (wmhintsp->flags & IconWindowHint) { 572f66df612Smrg for (j = 0; (unsigned) j < nchildren; j++) { 573f66df612Smrg if (children[j] == wmhintsp->icon_window) { 574f66df612Smrg children[j] = None; 575f66df612Smrg break; 576f66df612Smrg } 577f66df612Smrg } 578f66df612Smrg } 579f66df612Smrg XFree(wmhintsp); 580f66df612Smrg } 581f66df612Smrg } 582f66df612Smrg } 583f66df612Smrg 584f66df612Smrg /* 585f66df612Smrg * map all of the non-override windows 586f66df612Smrg */ 587f66df612Smrg for (i = 0; (unsigned) i < nchildren; i++) { 588f66df612Smrg if (children[i] && MappedNotOverride(children[i])) { 589f66df612Smrg XUnmapWindow(dpy, children[i]); 590f66df612Smrg SimulateMapRequest(children[i]); 591f66df612Smrg } 592f66df612Smrg } 593f66df612Smrg 594f66df612Smrg if (Scr->ShowIconManager && !Scr->NoIconManagers) { 595f66df612Smrg Scr->iconmgr.twm_win->icon = FALSE; 596f66df612Smrg if (Scr->iconmgr.count) { 597f66df612Smrg SetMapStateProp(Scr->iconmgr.twm_win, NormalState); 598f66df612Smrg XMapWindow(dpy, Scr->iconmgr.w); 599f66df612Smrg XMapWindow(dpy, Scr->iconmgr.twm_win->frame); 600f66df612Smrg } 601f66df612Smrg } 602f66df612Smrg 603f66df612Smrg attributes.border_pixel = Scr->DefaultC.fore; 604f66df612Smrg attributes.background_pixel = Scr->DefaultC.back; 605f66df612Smrg attributes.event_mask = (ExposureMask | ButtonPressMask | 606f66df612Smrg KeyPressMask | ButtonReleaseMask); 607f66df612Smrg attributes.backing_store = NotUseful; 608f66df612Smrg attributes.cursor = XCreateFontCursor(dpy, XC_hand2); 609f66df612Smrg valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | 610f66df612Smrg CWBackingStore | CWCursor); 611f66df612Smrg Scr->InfoWindow = XCreateWindow(dpy, Scr->Root, 0, 0, 612f66df612Smrg (unsigned int) 5, (unsigned int) 5, 613f66df612Smrg (unsigned int) BW, 0, 614f66df612Smrg (unsigned int) CopyFromParent, 615f66df612Smrg (Visual *) CopyFromParent, 616f66df612Smrg valuemask, &attributes); 617f66df612Smrg 618f66df612Smrg Scr->SizeStringWidth = MyFont_TextWidth(&Scr->SizeFont, 619f66df612Smrg " 8888 x 8888 ", 13); 620f66df612Smrg valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity); 621f66df612Smrg attributes.bit_gravity = NorthWestGravity; 622f66df612Smrg Scr->SizeWindow = XCreateWindow(dpy, Scr->Root, 0, 0, 623f66df612Smrg (unsigned int) Scr->SizeStringWidth, 624f66df612Smrg (unsigned int) (Scr->SizeFont.height + 625f66df612Smrg SIZE_VINDENT * 2), 626f66df612Smrg (unsigned int) BW, 0, 627f66df612Smrg (unsigned int) CopyFromParent, 628f66df612Smrg (Visual *) CopyFromParent, 629f66df612Smrg valuemask, &attributes); 630f66df612Smrg 631f66df612Smrg XUngrabServer(dpy); 632f66df612Smrg 633f66df612Smrg Scr->FirstTime = FALSE; 634f66df612Smrg } /* for */ 6353e747e6dSmrg 6363e747e6dSmrg if (numManaged == 0) { 637f66df612Smrg if (MultiScreen && NumScreens > 0) { 6386d8e82c3Smrg twmError("unable to find any unmanaged video screens.\n"); 639f66df612Smrg } 640f66df612Smrg exit(EXIT_FAILURE); 6413e747e6dSmrg } 6423e747e6dSmrg 6436d8e82c3Smrg (void) ConnectToSessionManager(client_id, appContext); 6443e747e6dSmrg 6453e747e6dSmrg RestartPreviousState = False; 6463e747e6dSmrg HandlingEvents = TRUE; 6473e747e6dSmrg InitEvents(); 6486d8e82c3Smrg HandleEvents(appContext); 649f66df612Smrg exit(EXIT_SUCCESS); 6503e747e6dSmrg} 6513e747e6dSmrg 6523e747e6dSmrg/** 6533e747e6dSmrg * initialize twm variables 6543e747e6dSmrg */ 655c2535118Smrgstatic void 656c2535118SmrgInitVariables(void) 6573e747e6dSmrg{ 6583e747e6dSmrg FreeList(&Scr->BorderColorL); 6593e747e6dSmrg FreeList(&Scr->IconBorderColorL); 6603e747e6dSmrg FreeList(&Scr->BorderTileForegroundL); 6613e747e6dSmrg FreeList(&Scr->BorderTileBackgroundL); 6623e747e6dSmrg FreeList(&Scr->TitleForegroundL); 6633e747e6dSmrg FreeList(&Scr->TitleBackgroundL); 6643e747e6dSmrg FreeList(&Scr->IconForegroundL); 6653e747e6dSmrg FreeList(&Scr->IconBackgroundL); 6663e747e6dSmrg FreeList(&Scr->IconManagerFL); 6673e747e6dSmrg FreeList(&Scr->IconManagerBL); 6683e747e6dSmrg FreeList(&Scr->IconMgrs); 6693e747e6dSmrg FreeList(&Scr->NoTitle); 6703e747e6dSmrg FreeList(&Scr->MakeTitle); 6713e747e6dSmrg FreeList(&Scr->AutoRaise); 6723e747e6dSmrg FreeList(&Scr->IconNames); 6733e747e6dSmrg FreeList(&Scr->NoHighlight); 6743e747e6dSmrg FreeList(&Scr->NoStackModeL); 6753e747e6dSmrg FreeList(&Scr->NoTitleHighlight); 6763e747e6dSmrg FreeList(&Scr->DontIconify); 6773e747e6dSmrg FreeList(&Scr->IconMgrNoShow); 6783e747e6dSmrg FreeList(&Scr->IconMgrShow); 6793e747e6dSmrg FreeList(&Scr->IconifyByUn); 6803e747e6dSmrg FreeList(&Scr->StartIconified); 6813e747e6dSmrg FreeList(&Scr->IconManagerHighlightL); 6823e747e6dSmrg FreeList(&Scr->SqueezeTitleL); 6833e747e6dSmrg FreeList(&Scr->DontSqueezeTitleL); 6843e747e6dSmrg FreeList(&Scr->WindowRingL); 6853e747e6dSmrg FreeList(&Scr->WarpCursorL); 6863e747e6dSmrg 6873e747e6dSmrg NewFontCursor(&Scr->FrameCursor, "top_left_arrow"); 6883e747e6dSmrg NewFontCursor(&Scr->TitleCursor, "top_left_arrow"); 6893e747e6dSmrg NewFontCursor(&Scr->IconCursor, "top_left_arrow"); 6903e747e6dSmrg NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow"); 6913e747e6dSmrg NewFontCursor(&Scr->MoveCursor, "fleur"); 6923e747e6dSmrg NewFontCursor(&Scr->ResizeCursor, "fleur"); 6933e747e6dSmrg NewFontCursor(&Scr->MenuCursor, "sb_left_arrow"); 6943e747e6dSmrg NewFontCursor(&Scr->ButtonCursor, "hand2"); 6953e747e6dSmrg NewFontCursor(&Scr->WaitCursor, "watch"); 6963e747e6dSmrg NewFontCursor(&Scr->SelectCursor, "dot"); 6973e747e6dSmrg NewFontCursor(&Scr->DestroyCursor, "pirate"); 6983e747e6dSmrg 6993e747e6dSmrg Scr->Ring = NULL; 7003e747e6dSmrg Scr->RingLeader = NULL; 7013e747e6dSmrg 7023e747e6dSmrg Scr->DefaultC.fore = black; 7033e747e6dSmrg Scr->DefaultC.back = white; 7043e747e6dSmrg Scr->BorderColor = black; 7053e747e6dSmrg Scr->BorderTileC.fore = black; 7063e747e6dSmrg Scr->BorderTileC.back = white; 7073e747e6dSmrg Scr->TitleC.fore = black; 7083e747e6dSmrg Scr->TitleC.back = white; 7093e747e6dSmrg Scr->MenuC.fore = black; 7103e747e6dSmrg Scr->MenuC.back = white; 7113e747e6dSmrg Scr->MenuTitleC.fore = black; 7123e747e6dSmrg Scr->MenuTitleC.back = white; 7133e747e6dSmrg Scr->MenuShadowColor = black; 7143e747e6dSmrg Scr->MenuBorderColor = black; 7153e747e6dSmrg Scr->IconC.fore = black; 7163e747e6dSmrg Scr->IconC.back = white; 7173e747e6dSmrg Scr->IconBorderColor = black; 7183e747e6dSmrg Scr->PointerForeground.pixel = black; 7193e747e6dSmrg XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c, 720f66df612Smrg &Scr->PointerForeground); 7213e747e6dSmrg Scr->PointerBackground.pixel = white; 7223e747e6dSmrg XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c, 723f66df612Smrg &Scr->PointerBackground); 7243e747e6dSmrg Scr->IconManagerC.fore = black; 7253e747e6dSmrg Scr->IconManagerC.back = white; 7263e747e6dSmrg Scr->IconManagerHighlight = black; 7273e747e6dSmrg 728f66df612Smrg Scr->FramePadding = 2; /* values that look "nice" on */ 729f66df612Smrg Scr->TitlePadding = 8; /* 75 and 100dpi displays */ 7303e747e6dSmrg Scr->ButtonIndent = 1; 7313e747e6dSmrg Scr->SizeStringOffset = 0; 7323e747e6dSmrg Scr->BorderWidth = BW; 7333e747e6dSmrg Scr->IconBorderWidth = BW; 7343e747e6dSmrg Scr->MenuBorderWidth = BW; 7353e747e6dSmrg Scr->UnknownWidth = 0; 7363e747e6dSmrg Scr->UnknownHeight = 0; 7373e747e6dSmrg Scr->NumAutoRaises = 0; 7383e747e6dSmrg Scr->NoDefaults = FALSE; 7393e747e6dSmrg Scr->UsePPosition = PPOS_OFF; 7403e747e6dSmrg Scr->FocusRoot = TRUE; 7413e747e6dSmrg Scr->Focus = NULL; 7423e747e6dSmrg Scr->WarpCursor = FALSE; 7433e747e6dSmrg Scr->ForceIcon = FALSE; 7443e747e6dSmrg Scr->NoGrabServer = FALSE; 7453e747e6dSmrg Scr->NoRaiseMove = FALSE; 7463e747e6dSmrg Scr->NoRaiseResize = FALSE; 7473e747e6dSmrg Scr->NoRaiseDeicon = FALSE; 7483e747e6dSmrg Scr->NoRaiseWarp = FALSE; 7493e747e6dSmrg Scr->DontMoveOff = FALSE; 7503e747e6dSmrg Scr->DoZoom = FALSE; 7513e747e6dSmrg Scr->TitleFocus = TRUE; 7523e747e6dSmrg Scr->NoTitlebar = FALSE; 7533e747e6dSmrg Scr->DecorateTransients = FALSE; 7543e747e6dSmrg Scr->IconifyByUnmapping = FALSE; 7553e747e6dSmrg Scr->ShowIconManager = FALSE; 756f66df612Smrg Scr->IconManagerDontShow = FALSE; 7573e747e6dSmrg Scr->BackingStore = TRUE; 7583e747e6dSmrg Scr->SaveUnder = TRUE; 7593e747e6dSmrg Scr->RandomPlacement = FALSE; 7603e747e6dSmrg Scr->OpaqueMove = FALSE; 7613e747e6dSmrg Scr->Highlight = TRUE; 7623e747e6dSmrg Scr->StackMode = TRUE; 7633e747e6dSmrg Scr->TitleHighlight = TRUE; 764f66df612Smrg Scr->MoveDelta = 1; /* so that f.deltastop will work */ 7653e747e6dSmrg Scr->ZoomCount = 8; 7663e747e6dSmrg Scr->SortIconMgr = FALSE; 7673e747e6dSmrg Scr->Shadow = TRUE; 7683e747e6dSmrg Scr->InterpolateMenuColors = FALSE; 7693e747e6dSmrg Scr->NoIconManagers = FALSE; 7703e747e6dSmrg Scr->ClientBorderWidth = FALSE; 7713e747e6dSmrg Scr->SqueezeTitle = -1; 7723e747e6dSmrg Scr->FirstRegion = NULL; 7733e747e6dSmrg Scr->LastRegion = NULL; 7743e747e6dSmrg Scr->FirstTime = TRUE; 775f66df612Smrg Scr->HaveFonts = FALSE; /* i.e. not loaded yet */ 7763e747e6dSmrg Scr->CaseSensitive = TRUE; 7773e747e6dSmrg Scr->WarpUnmapped = FALSE; 7783e747e6dSmrg 7793e747e6dSmrg /* setup default fonts; overridden by defaults from system.twmrc */ 7803e747e6dSmrg#define DEFAULT_NICE_FONT "variable" 7813e747e6dSmrg#define DEFAULT_FAST_FONT "fixed" 7823e747e6dSmrg 7833e747e6dSmrg Scr->TitleBarFont.font = NULL; 7843e747e6dSmrg Scr->TitleBarFont.fontset = NULL; 7853e747e6dSmrg Scr->TitleBarFont.name = DEFAULT_NICE_FONT; 7863e747e6dSmrg Scr->MenuFont.font = NULL; 7873e747e6dSmrg Scr->MenuFont.fontset = NULL; 7883e747e6dSmrg Scr->MenuFont.name = DEFAULT_NICE_FONT; 7893e747e6dSmrg Scr->IconFont.font = NULL; 7903e747e6dSmrg Scr->IconFont.fontset = NULL; 7913e747e6dSmrg Scr->IconFont.name = DEFAULT_NICE_FONT; 7923e747e6dSmrg Scr->SizeFont.font = NULL; 7933e747e6dSmrg Scr->SizeFont.fontset = NULL; 7943e747e6dSmrg Scr->SizeFont.name = DEFAULT_FAST_FONT; 7953e747e6dSmrg Scr->IconManagerFont.font = NULL; 7963e747e6dSmrg Scr->IconManagerFont.fontset = NULL; 7973e747e6dSmrg Scr->IconManagerFont.name = DEFAULT_NICE_FONT; 7983e747e6dSmrg Scr->DefaultFont.font = NULL; 7993e747e6dSmrg Scr->DefaultFont.fontset = NULL; 8003e747e6dSmrg Scr->DefaultFont.name = DEFAULT_FAST_FONT; 8013e747e6dSmrg 8023e747e6dSmrg} 8033e747e6dSmrg 8043e747e6dSmrgvoid 805f66df612SmrgCreateFonts(void) 8063e747e6dSmrg{ 8073e747e6dSmrg GetFont(&Scr->TitleBarFont); 8083e747e6dSmrg GetFont(&Scr->MenuFont); 8093e747e6dSmrg GetFont(&Scr->IconFont); 8103e747e6dSmrg GetFont(&Scr->SizeFont); 8113e747e6dSmrg GetFont(&Scr->IconManagerFont); 8123e747e6dSmrg GetFont(&Scr->DefaultFont); 8133e747e6dSmrg Scr->HaveFonts = TRUE; 8143e747e6dSmrg} 8153e747e6dSmrg 8166d8e82c3Smrgstatic void 8176d8e82c3SmrgDestroyFonts(void) 8186d8e82c3Smrg{ 8196d8e82c3Smrg int i; 8206d8e82c3Smrg for (i = 0; i < NumScreens; ++i) { 8216d8e82c3Smrg ScreenInfo *scr = ScreenList[i]; 8226d8e82c3Smrg 8236d8e82c3Smrg if (!scr) { 8246d8e82c3Smrg continue; 8256d8e82c3Smrg } 8266d8e82c3Smrg 8276d8e82c3Smrg DestroyFont(&scr->TitleBarFont); 8286d8e82c3Smrg DestroyFont(&scr->MenuFont); 8296d8e82c3Smrg DestroyFont(&scr->IconFont); 8306d8e82c3Smrg DestroyFont(&scr->SizeFont); 8316d8e82c3Smrg DestroyFont(&scr->IconManagerFont); 8326d8e82c3Smrg DestroyFont(&scr->DefaultFont); 8336d8e82c3Smrg } 8346d8e82c3Smrg} 8356d8e82c3Smrg 8363e747e6dSmrgvoid 837f66df612SmrgRestoreWithdrawnLocation(TwmWindow *tmp) 8383e747e6dSmrg{ 8393e747e6dSmrg int gravx, gravy; 840f66df612Smrg unsigned int bw; 8413e747e6dSmrg XWindowChanges xwc; 8426d8e82c3Smrg unsigned udummy = 0; 8436d8e82c3Smrg Window wdummy = None; 8443e747e6dSmrg 8456d8e82c3Smrg if (XGetGeometry(dpy, tmp->w, &wdummy, &xwc.x, &xwc.y, 8466d8e82c3Smrg &udummy, &udummy, &bw, &udummy)) { 847f66df612Smrg unsigned mask; 8483e747e6dSmrg 849f66df612Smrg GetGravityOffsets(tmp, &gravx, &gravy); 850f66df612Smrg if (gravy < 0) 851f66df612Smrg xwc.y -= tmp->title_height; 8523e747e6dSmrg 853f66df612Smrg if (bw != (unsigned) tmp->old_bw) { 854f66df612Smrg int xoff, yoff; 8553e747e6dSmrg 856f66df612Smrg if (!Scr->ClientBorderWidth) { 857f66df612Smrg xoff = gravx; 858f66df612Smrg yoff = gravy; 859f66df612Smrg } 860f66df612Smrg else { 861f66df612Smrg xoff = 0; 862f66df612Smrg yoff = 0; 863f66df612Smrg } 8643e747e6dSmrg 865f66df612Smrg xwc.x -= (xoff + 1) * tmp->old_bw; 866f66df612Smrg xwc.y -= (yoff + 1) * tmp->old_bw; 867f66df612Smrg } 868f66df612Smrg if (!Scr->ClientBorderWidth) { 869f66df612Smrg xwc.x += gravx * tmp->frame_bw; 870f66df612Smrg xwc.y += gravy * tmp->frame_bw; 871f66df612Smrg } 8723e747e6dSmrg 873f66df612Smrg mask = (CWX | CWY); 874f66df612Smrg if (bw != (unsigned) tmp->old_bw) { 875f66df612Smrg xwc.border_width = tmp->old_bw; 876f66df612Smrg mask |= CWBorderWidth; 877f66df612Smrg } 8783e747e6dSmrg 879f66df612Smrg XConfigureWindow(dpy, tmp->w, mask, &xwc); 8803e747e6dSmrg 881f66df612Smrg if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) { 882f66df612Smrg XUnmapWindow(dpy, tmp->wmhints->icon_window); 883f66df612Smrg } 8843e747e6dSmrg 8853e747e6dSmrg } 8863e747e6dSmrg} 8873e747e6dSmrg 888ffd25bcaSmrgvoid 889f66df612SmrgReborder(Time time) 8903e747e6dSmrg{ 891f66df612Smrg TwmWindow *tmp; /* temp twm window structure */ 8923e747e6dSmrg int scrnum; 8933e747e6dSmrg 8943e747e6dSmrg /* put a border back around all windows */ 8953e747e6dSmrg 896f66df612Smrg XGrabServer(dpy); 897f66df612Smrg for (scrnum = 0; scrnum < NumScreens; scrnum++) { 898f66df612Smrg if ((Scr = ScreenList[scrnum]) == NULL) 899f66df612Smrg continue; 900f66df612Smrg 901f66df612Smrg InstallWindowColormaps(0, &Scr->TwmRoot); /* force reinstall */ 902f66df612Smrg for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next) { 903f66df612Smrg RestoreWithdrawnLocation(tmp); 904f66df612Smrg XMapWindow(dpy, tmp->w); 905f66df612Smrg } 9063e747e6dSmrg } 9073e747e6dSmrg 908f66df612Smrg XUngrabServer(dpy); 909f66df612Smrg SetFocus((TwmWindow *) NULL, time); 9103e747e6dSmrg} 9113e747e6dSmrg 912c2535118Smrgstatic void 913f66df612SmrgsigHandler(int sig _X_UNUSED) 9143e747e6dSmrg{ 9153e747e6dSmrg XtNoticeSignal(si); 9163e747e6dSmrg} 9173e747e6dSmrg 9183e747e6dSmrg/** 9193e747e6dSmrg * cleanup and exit twm 9203e747e6dSmrg */ 9213e747e6dSmrgvoid 922f66df612SmrgDone(XtPointer client_data _X_UNUSED, XtSignalId *si2 _X_UNUSED) 9233e747e6dSmrg{ 924f66df612Smrg if (dpy) { 925f66df612Smrg Reborder(CurrentTime); 9266d8e82c3Smrg DestroyFonts(); 927f66df612Smrg XCloseDisplay(dpy); 9283e747e6dSmrg } 9296d8e82c3Smrg 9306d8e82c3Smrg DestroySession(); 931f66df612Smrg exit(EXIT_SUCCESS); 9323e747e6dSmrg} 9333e747e6dSmrg 9343e747e6dSmrg/* 9353e747e6dSmrg * Error Handlers. If a client dies, we'll get a BadWindow error (except for 9363e747e6dSmrg * GetGeometry which returns BadDrawable) for most operations that we do before 9373e747e6dSmrg * manipulating the client's window. 9383e747e6dSmrg */ 9393e747e6dSmrg 9403e747e6dSmrgBool ErrorOccurred = False; 9413e747e6dSmrgXErrorEvent LastErrorEvent; 9423e747e6dSmrg 943ffd25bcaSmrgstatic int 944f66df612SmrgTwmErrorHandler(Display *dpy2, XErrorEvent *event) 9453e747e6dSmrg{ 9463e747e6dSmrg LastErrorEvent = *event; 9473e747e6dSmrg ErrorOccurred = True; 9483e747e6dSmrg 949f66df612Smrg if ((message_level > 1) && /* don't be too obnoxious */ 950f66df612Smrg event->error_code != BadWindow && /* watch for dead puppies */ 951f66df612Smrg (event->request_code != X_GetGeometry && /* of all styles */ 952f66df612Smrg event->error_code != BadDrawable)) 953f66df612Smrg XmuPrintDefaultErrorMessage(dpy2, event, stderr); 9543e747e6dSmrg return 0; 9553e747e6dSmrg} 9563e747e6dSmrg 957ffd25bcaSmrgstatic int 958f66df612SmrgCatchRedirectError(Display *dpy2 _X_UNUSED, XErrorEvent *event) 9593e747e6dSmrg{ 9603e747e6dSmrg RedirectError = TRUE; 9613e747e6dSmrg LastErrorEvent = *event; 9623e747e6dSmrg ErrorOccurred = True; 9633e747e6dSmrg return 0; 9643e747e6dSmrg} 965f66df612Smrg 966f66df612Smrgvoid 967f66df612SmrgtwmError(const char *format, ...) 968f66df612Smrg{ 969f66df612Smrg va_list ap; 970f66df612Smrg 971f66df612Smrg va_start(ap, format); 972f66df612Smrg fprintf(stderr, "%s: error: ", ProgramName); 973f66df612Smrg vfprintf(stderr, format, ap); 974f66df612Smrg fputc('\n', stderr); 975f66df612Smrg va_end(ap); 976f66df612Smrg exit(EXIT_FAILURE); 977f66df612Smrg} 978f66df612Smrg 979f66df612Smrgvoid 980f66df612SmrgtwmWarning(const char *format, ...) 981f66df612Smrg{ 982f66df612Smrg if (message_level > 0) { 983f66df612Smrg va_list ap; 984f66df612Smrg 985f66df612Smrg va_start(ap, format); 986f66df612Smrg fprintf(stderr, "%s: warning: ", ProgramName); 987f66df612Smrg vfprintf(stderr, format, ap); 988f66df612Smrg fputc('\n', stderr); 989f66df612Smrg va_end(ap); 990f66df612Smrg } 991f66df612Smrg} 992f66df612Smrg 993f66df612Smrgvoid 994f66df612SmrgtwmVerbose(const char *format, ...) 995f66df612Smrg{ 996f66df612Smrg if (message_level > 1) { 997f66df612Smrg va_list ap; 998f66df612Smrg 999f66df612Smrg va_start(ap, format); 1000f66df612Smrg fprintf(stderr, "%s: warning: ", ProgramName); 1001f66df612Smrg vfprintf(stderr, format, ap); 1002f66df612Smrg fputc('\n', stderr); 1003f66df612Smrg va_end(ap); 1004f66df612Smrg } 1005f66df612Smrg} 1006f66df612Smrg 1007f66df612Smrgvoid 1008f66df612SmrgtwmMessage(const char *format, ...) 1009f66df612Smrg{ 1010f66df612Smrg va_list ap; 1011f66df612Smrg 1012f66df612Smrg va_start(ap, format); 1013f66df612Smrg printf("%s: ", ProgramName); 1014f66df612Smrg vprintf(format, ap); 1015f66df612Smrg putc('\n', stdout); 1016f66df612Smrg va_end(ap); 1017f66df612Smrg 1018f66df612Smrg fflush(stdout); 1019f66df612Smrg} 1020