#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include "twm.h"
#include "iconmgr.h"
#include "add_window.h"
#include "gc.h"
#include "parse.h"
#include "version.h"
#include "menus.h"
#include "events.h"
#include "util.h"
#include "gram.h"
#include "screen.h"
#include "parse.h"
#include "session.h"
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/SM/SMlib.h>
#include <X11/Xmu/Error.h>
#include <X11/extensions/sync.h>
#include <X11/Xlocale.h>
XtAppContext appContext;
XtSignalId si;
Display *dpy = NULL;
Window ResizeWindow;
int MultiScreen = TRUE;
int NumScreens;
int HasShape;
int ShapeEventBase, ShapeErrorBase;
int HasSync;
int SyncEventBase, SyncErrorBase;
ScreenInfo **ScreenList;
ScreenInfo *Scr = NULL;
int PreviousScreen;
int FirstScreen;
Bool PrintErrorMessages = False;
static int RedirectError;
static int TwmErrorHandler ( Display *dpy, XErrorEvent *event );
static int CatchRedirectError ( Display *dpy, XErrorEvent *event );
static SIGNAL_T sigHandler(int);
char Info[INFO_LINES][INFO_SIZE];
int InfoLines;
char *InitFile = NULL;
Cursor UpperLeftCursor;
Cursor RightButt;
Cursor MiddleButt;
Cursor LeftButt;
XContext TwmContext;
XContext MenuContext;
XContext IconManagerContext;
XContext ScreenContext;
XContext ColormapContext;
XClassHint NoClass;
XGCValues Gcv;
char *Home;
int HomeLen;
int ParseError;
int HandlingEvents = FALSE;
Window JunkRoot;
Window JunkChild;
int JunkX;
int JunkY;
unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;
char *ProgramName;
int Argc;
char **Argv;
Bool RestartPreviousState = False;
unsigned long black, white;
Atom TwmAtoms[11];
Bool use_fontset;
static char* atom_names[11] = {
"_MIT_PRIORITY_COLORS",
"WM_CHANGE_STATE",
"WM_STATE",
"WM_COLORMAP_WINDOWS",
"WM_PROTOCOLS",
"WM_TAKE_FOCUS",
"WM_SAVE_YOURSELF",
"WM_DELETE_WINDOW",
"SM_CLIENT_ID",
"WM_CLIENT_LEADER",
"WM_WINDOW_ROLE"
};
int
main(int argc, char *argv[])
{
Window root, parent, *children;
unsigned int nchildren;
int i, j;
char *display_name = NULL;
unsigned long valuemask;
XSetWindowAttributes attributes;
int numManaged, firstscrn, lastscrn, scrnum;
int zero = 0;
char *restore_filename = NULL;
char *client_id = NULL;
char *loc;
ProgramName = argv[0];
Argc = argc;
Argv = argv;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'd':
if (++i >= argc) goto usage;
display_name = argv[i];
continue;
case 's':
MultiScreen = FALSE;
continue;
case 'f':
if (++i >= argc) goto usage;
InitFile = argv[i];
continue;
case 'v':
PrintErrorMessages = True;
continue;
case 'c':
if (++i >= argc) goto usage;
client_id = argv[i];
continue;
case 'r':
if (++i >= argc) goto usage;
restore_filename = argv[i];
continue;
case 'q':
PrintErrorMessages = False;
continue;
}
}
usage:
fprintf (stderr,
"usage: %s [-display dpy] [-f file] [-s] [-q] [-v] [-clientId id] [-restore file]\n",
ProgramName);
exit (1);
}
loc = setlocale(LC_ALL, "");
if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") ||
!XSupportsLocale()) {
use_fontset = False;
} else {
use_fontset = True;
}
#define newhandler(sig) \
if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, sigHandler)
newhandler (SIGINT);
newhandler (SIGHUP);
newhandler (SIGQUIT);
newhandler (SIGTERM);
#undef newhandler
Home = getenv("HOME");
if (Home != NULL) {
char *temp_p;
temp_p = strdup(Home);
Home = temp_p;
}
if (Home == NULL)
Home = "./";
HomeLen = strlen(Home);
NoClass.res_name = NoName;
NoClass.res_class = NoName;
XtToolkitInitialize ();
appContext = XtCreateApplicationContext ();
si = XtAppAddSignal(appContext, Done, NULL);
if (!(dpy = XtOpenDisplay (appContext, display_name, "twm", "twm",
NULL, 0, &zero, NULL))) {
fprintf (stderr, "%s: unable to open display \"%s\"\n",
ProgramName, XDisplayName(display_name));
exit (1);
}
if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) {
fprintf (stderr,
"%s: unable to mark display connection as close-on-exec\n",
ProgramName);
exit (1);
}
if (restore_filename)
ReadWinConfigFile (restore_filename);
HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase);
HasSync = XSyncQueryExtension(dpy, &SyncEventBase, &SyncErrorBase);
TwmContext = XUniqueContext();
MenuContext = XUniqueContext();
IconManagerContext = XUniqueContext();
ScreenContext = XUniqueContext();
ColormapContext = XUniqueContext();
(void) XInternAtoms(dpy, atom_names, sizeof TwmAtoms / sizeof TwmAtoms[0],
False, TwmAtoms);
NumScreens = ScreenCount(dpy);
if (MultiScreen)
{
firstscrn = 0;
lastscrn = NumScreens - 1;
}
else
{
firstscrn = lastscrn = DefaultScreen(dpy);
}
InfoLines = 0;
ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *));
if (ScreenList == NULL)
{
fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
ProgramName);
exit (1);
}
numManaged = 0;
PreviousScreen = DefaultScreen(dpy);
FirstScreen = TRUE;
for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++)
{
XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS,
XA_CARDINAL, 32, PropModeReplace, NULL, 0);
RedirectError = FALSE;
XSetErrorHandler(CatchRedirectError);
XSelectInput(dpy, RootWindow (dpy, scrnum),
ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
SubstructureRedirectMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask);
XSync(dpy, 0);
XSetErrorHandler(TwmErrorHandler);
if (RedirectError)
{
fprintf (stderr, "%s: another window manager is already running",
ProgramName);
if (MultiScreen && NumScreens > 0)
fprintf(stderr, " on screen %d?\n", scrnum);
else
fprintf(stderr, "?\n");
continue;
}
numManaged ++;
Scr = ScreenList[scrnum] =
(ScreenInfo *) calloc(1, sizeof(ScreenInfo));
if (Scr == NULL)
{
fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n",
ProgramName, scrnum);
continue;
}
Scr->BorderColorL = NULL;
Scr->IconBorderColorL = NULL;
Scr->BorderTileForegroundL = NULL;
Scr->BorderTileBackgroundL = NULL;
Scr->TitleForegroundL = NULL;
Scr->TitleBackgroundL = NULL;
Scr->IconForegroundL = NULL;
Scr->IconBackgroundL = NULL;
Scr->NoTitle = NULL;
Scr->MakeTitle = NULL;
Scr->AutoRaise = NULL;
Scr->IconNames = NULL;
Scr->NoHighlight = NULL;
Scr->NoStackModeL = NULL;
Scr->NoTitleHighlight = NULL;
Scr->DontIconify = NULL;
Scr->IconMgrNoShow = NULL;
Scr->IconMgrShow = NULL;
Scr->IconifyByUn = NULL;
Scr->IconManagerFL = NULL;
Scr->IconManagerBL = NULL;
Scr->IconMgrs = NULL;
Scr->StartIconified = NULL;
Scr->SqueezeTitleL = NULL;
Scr->DontSqueezeTitleL = NULL;
Scr->WindowRingL = NULL;
Scr->WarpCursorL = NULL;
Scr->screen = scrnum;
Scr->d_depth = DefaultDepth(dpy, scrnum);
Scr->d_visual = DefaultVisual(dpy, scrnum);
Scr->Root = RootWindow(dpy, scrnum);
XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr);
Scr->TwmRoot.cmaps.number_cwins = 1;
Scr->TwmRoot.cmaps.cwins =
(ColormapWindow **) malloc(sizeof(ColormapWindow *));
Scr->TwmRoot.cmaps.cwins[0] =
CreateColormapWindow(Scr->Root, True, False);
Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured;
Scr->cmapInfo.cmaps = NULL;
Scr->cmapInfo.maxCmaps =
MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen));
Scr->cmapInfo.root_pushes = 0;
InstallWindowColormaps(0, &Scr->TwmRoot);
Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail =
Scr->StdCmapInfo.mru = NULL;
Scr->StdCmapInfo.mruindex = 0;
LocateStandardColormaps();
Scr->TBInfo.nleft = Scr->TBInfo.nright = 0;
Scr->TBInfo.head = NULL;
Scr->TBInfo.border = 1;
Scr->TBInfo.width = 0;
Scr->TBInfo.leftx = 0;
Scr->TBInfo.titlex = 0;
Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum);
Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum);
Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth;
Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight;
Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;
if (DisplayCells(dpy, scrnum) < 3)
Scr->Monochrome = MONOCHROME;
else if (DefaultVisual(dpy, scrnum)->class == GrayScale)
Scr->Monochrome = GRAYSCALE;
else
Scr->Monochrome = COLOR;
Scr->FirstTime = TRUE;
GetColor(Scr->Monochrome, &black, "black");
Scr->Black = black;
GetColor(Scr->Monochrome, &white, "white");
Scr->White = white;
if (FirstScreen)
{
SetFocus ((TwmWindow *)NULL, CurrentTime);
NewFontCursor(&UpperLeftCursor, "top_left_corner");
NewFontCursor(&RightButt, "rightbutton");
NewFontCursor(&LeftButt, "leftbutton");
NewFontCursor(&MiddleButt, "middlebutton");
}
Scr->iconmgr.x = 0;
Scr->iconmgr.y = 0;
Scr->iconmgr.width = 150;
Scr->iconmgr.height = 5;
Scr->iconmgr.next = NULL;
Scr->iconmgr.prev = NULL;
Scr->iconmgr.lasti = &(Scr->iconmgr);
Scr->iconmgr.first = NULL;
Scr->iconmgr.last = NULL;
Scr->iconmgr.active = NULL;
Scr->iconmgr.scr = Scr;
Scr->iconmgr.columns = 1;
Scr->iconmgr.count = 0;
Scr->iconmgr.name = "TWM";
Scr->iconmgr.icon_name = "Icons";
Scr->IconDirectory = NULL;
Scr->siconifyPm = None;
Scr->pullPm = None;
Scr->hilitePm = None;
Scr->tbpm.xlogo = None;
Scr->tbpm.resize = None;
Scr->tbpm.question = None;
Scr->tbpm.menu = None;
Scr->tbpm.delete = None;
InitVariables();
InitMenus();
ParseTwmrc(InitFile);
assign_var_savecolor();
if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE;
if (!Scr->HaveFonts) CreateFonts();
CreateGCs();
MakeMenus();
Scr->TitleBarFont.y += Scr->FramePadding;
Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++;
InitTitlebarButtons ();
XGrabServer(dpy);
XSync(dpy, 0);
JunkX = 0;
JunkY = 0;
XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren);
CreateIconManagers();
if (!Scr->NoIconManagers)
Scr->iconmgr.twm_win->icon = TRUE;
for (i = 0; i < nchildren; i++) {
if (children[i]) {
XWMHints *wmhintsp = XGetWMHints (dpy, children[i]);
if (wmhintsp) {
if (wmhintsp->flags & IconWindowHint) {
for (j = 0; j < nchildren; j++) {
if (children[j] == wmhintsp->icon_window) {
children[j] = None;
break;
}
}
}
XFree ((char *) wmhintsp);
}
}
}
for (i = 0; i < nchildren; i++)
{
if (children[i] && MappedNotOverride(children[i]))
{
XUnmapWindow(dpy, children[i]);
SimulateMapRequest(children[i]);
}
}
if (Scr->ShowIconManager && !Scr->NoIconManagers)
{
Scr->iconmgr.twm_win->icon = FALSE;
if (Scr->iconmgr.count)
{
SetMapStateProp (Scr->iconmgr.twm_win, NormalState);
XMapWindow(dpy, Scr->iconmgr.w);
XMapWindow(dpy, Scr->iconmgr.twm_win->frame);
}
}
attributes.border_pixel = Scr->DefaultC.fore;
attributes.background_pixel = Scr->DefaultC.back;
attributes.event_mask = (ExposureMask | ButtonPressMask |
KeyPressMask | ButtonReleaseMask);
attributes.backing_store = NotUseful;
attributes.cursor = XCreateFontCursor (dpy, XC_hand2);
valuemask = (CWBorderPixel | CWBackPixel | CWEventMask |
CWBackingStore | CWCursor);
Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
(unsigned int) 5, (unsigned int) 5,
(unsigned int) BW, 0,
(unsigned int) CopyFromParent,
(Visual *) CopyFromParent,
valuemask, &attributes);
Scr->SizeStringWidth = MyFont_TextWidth (&Scr->SizeFont,
" 8888 x 8888 ", 13);
valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
attributes.bit_gravity = NorthWestGravity;
Scr->SizeWindow = XCreateWindow (dpy, Scr->Root, 0, 0,
(unsigned int) Scr->SizeStringWidth,
(unsigned int) (Scr->SizeFont.height +
SIZE_VINDENT*2),
(unsigned int) BW, 0,
(unsigned int) CopyFromParent,
(Visual *) CopyFromParent,
valuemask, &attributes);
XUngrabServer(dpy);
FirstScreen = FALSE;
Scr->FirstTime = FALSE;
}
if (numManaged == 0) {
if (MultiScreen && NumScreens > 0)
fprintf (stderr, "%s: unable to find any unmanaged screens\n",
ProgramName);
exit (1);
}
(void) ConnectToSessionManager (client_id);
RestartPreviousState = False;
HandlingEvents = TRUE;
InitEvents();
HandleEvents();
exit(0);
}
void
InitVariables()
{
FreeList(&Scr->BorderColorL);
FreeList(&Scr->IconBorderColorL);
FreeList(&Scr->BorderTileForegroundL);
FreeList(&Scr->BorderTileBackgroundL);
FreeList(&Scr->TitleForegroundL);
FreeList(&Scr->TitleBackgroundL);
FreeList(&Scr->IconForegroundL);
FreeList(&Scr->IconBackgroundL);
FreeList(&Scr->IconManagerFL);
FreeList(&Scr->IconManagerBL);
FreeList(&Scr->IconMgrs);
FreeList(&Scr->NoTitle);
FreeList(&Scr->MakeTitle);
FreeList(&Scr->AutoRaise);
FreeList(&Scr->IconNames);
FreeList(&Scr->NoHighlight);
FreeList(&Scr->NoStackModeL);
FreeList(&Scr->NoTitleHighlight);
FreeList(&Scr->DontIconify);
FreeList(&Scr->IconMgrNoShow);
FreeList(&Scr->IconMgrShow);
FreeList(&Scr->IconifyByUn);
FreeList(&Scr->StartIconified);
FreeList(&Scr->IconManagerHighlightL);
FreeList(&Scr->SqueezeTitleL);
FreeList(&Scr->DontSqueezeTitleL);
FreeList(&Scr->WindowRingL);
FreeList(&Scr->WarpCursorL);
NewFontCursor(&Scr->FrameCursor, "top_left_arrow");
NewFontCursor(&Scr->TitleCursor, "top_left_arrow");
NewFontCursor(&Scr->IconCursor, "top_left_arrow");
NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow");
NewFontCursor(&Scr->MoveCursor, "fleur");
NewFontCursor(&Scr->ResizeCursor, "fleur");
NewFontCursor(&Scr->MenuCursor, "sb_left_arrow");
NewFontCursor(&Scr->ButtonCursor, "hand2");
NewFontCursor(&Scr->WaitCursor, "watch");
NewFontCursor(&Scr->SelectCursor, "dot");
NewFontCursor(&Scr->DestroyCursor, "pirate");
Scr->Ring = NULL;
Scr->RingLeader = NULL;
Scr->DefaultC.fore = black;
Scr->DefaultC.back = white;
Scr->BorderColor = black;
Scr->BorderTileC.fore = black;
Scr->BorderTileC.back = white;
Scr->TitleC.fore = black;
Scr->TitleC.back = white;
Scr->MenuC.fore = black;
Scr->MenuC.back = white;
Scr->MenuTitleC.fore = black;
Scr->MenuTitleC.back = white;
Scr->MenuShadowColor = black;
Scr->MenuBorderColor = black;
Scr->IconC.fore = black;
Scr->IconC.back = white;
Scr->IconBorderColor = black;
Scr->PointerForeground.pixel = black;
XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c,
&Scr->PointerForeground);
Scr->PointerBackground.pixel = white;
XQueryColor(dpy, Scr->TwmRoot.cmaps.cwins[0]->colormap->c,
&Scr->PointerBackground);
Scr->IconManagerC.fore = black;
Scr->IconManagerC.back = white;
Scr->IconManagerHighlight = black;
Scr->FramePadding = 2;
Scr->TitlePadding = 8;
Scr->ButtonIndent = 1;
Scr->SizeStringOffset = 0;
Scr->BorderWidth = BW;
Scr->IconBorderWidth = BW;
Scr->MenuBorderWidth = BW;
Scr->UnknownWidth = 0;
Scr->UnknownHeight = 0;
Scr->NumAutoRaises = 0;
Scr->NoDefaults = FALSE;
Scr->UsePPosition = PPOS_OFF;
Scr->FocusRoot = TRUE;
Scr->Focus = NULL;
Scr->WarpCursor = FALSE;
Scr->ForceIcon = FALSE;
Scr->NoGrabServer = FALSE;
Scr->NoRaiseMove = FALSE;
Scr->NoRaiseResize = FALSE;
Scr->NoRaiseDeicon = FALSE;
Scr->NoRaiseWarp = FALSE;
Scr->DontMoveOff = FALSE;
Scr->DoZoom = FALSE;
Scr->TitleFocus = TRUE;
Scr->NoTitlebar = FALSE;
Scr->DecorateTransients = FALSE;
Scr->IconifyByUnmapping = FALSE;
Scr->ShowIconManager = FALSE;
Scr->IconManagerDontShow =FALSE;
Scr->BackingStore = TRUE;
Scr->SaveUnder = TRUE;
Scr->RandomPlacement = FALSE;
Scr->OpaqueMove = FALSE;
Scr->Highlight = TRUE;
Scr->StackMode = TRUE;
Scr->TitleHighlight = TRUE;
Scr->MoveDelta = 1;
Scr->ZoomCount = 8;
Scr->SortIconMgr = FALSE;
Scr->Shadow = TRUE;
Scr->InterpolateMenuColors = FALSE;
Scr->NoIconManagers = FALSE;
Scr->ClientBorderWidth = FALSE;
Scr->SqueezeTitle = -1;
Scr->FirstRegion = NULL;
Scr->LastRegion = NULL;
Scr->FirstTime = TRUE;
Scr->HaveFonts = FALSE;
Scr->CaseSensitive = TRUE;
Scr->WarpUnmapped = FALSE;
#define DEFAULT_NICE_FONT "variable"
#define DEFAULT_FAST_FONT "fixed"
Scr->TitleBarFont.font = NULL;
Scr->TitleBarFont.fontset = NULL;
Scr->TitleBarFont.name = DEFAULT_NICE_FONT;
Scr->MenuFont.font = NULL;
Scr->MenuFont.fontset = NULL;
Scr->MenuFont.name = DEFAULT_NICE_FONT;
Scr->IconFont.font = NULL;
Scr->IconFont.fontset = NULL;
Scr->IconFont.name = DEFAULT_NICE_FONT;
Scr->SizeFont.font = NULL;
Scr->SizeFont.fontset = NULL;
Scr->SizeFont.name = DEFAULT_FAST_FONT;
Scr->IconManagerFont.font = NULL;
Scr->IconManagerFont.fontset = NULL;
Scr->IconManagerFont.name = DEFAULT_NICE_FONT;
Scr->DefaultFont.font = NULL;
Scr->DefaultFont.fontset = NULL;
Scr->DefaultFont.name = DEFAULT_FAST_FONT;
}
void
CreateFonts ()
{
GetFont(&Scr->TitleBarFont);
GetFont(&Scr->MenuFont);
GetFont(&Scr->IconFont);
GetFont(&Scr->SizeFont);
GetFont(&Scr->IconManagerFont);
GetFont(&Scr->DefaultFont);
Scr->HaveFonts = TRUE;
}
void
RestoreWithdrawnLocation (tmp)
TwmWindow *tmp;
{
int gravx, gravy;
unsigned int bw, mask;
XWindowChanges xwc;
if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y,
&JunkWidth, &JunkHeight, &bw, &JunkDepth)) {
GetGravityOffsets (tmp, &gravx, &gravy);
if (gravy < 0) xwc.y -= tmp->title_height;
if (bw != tmp->old_bw) {
int xoff, yoff;
if (!Scr->ClientBorderWidth) {
xoff = gravx;
yoff = gravy;
} else {
xoff = 0;
yoff = 0;
}
xwc.x -= (xoff + 1) * tmp->old_bw;
xwc.y -= (yoff + 1) * tmp->old_bw;
}
if (!Scr->ClientBorderWidth) {
xwc.x += gravx * tmp->frame_bw;
xwc.y += gravy * tmp->frame_bw;
}
mask = (CWX | CWY);
if (bw != tmp->old_bw) {
xwc.border_width = tmp->old_bw;
mask |= CWBorderWidth;
}
XConfigureWindow (dpy, tmp->w, mask, &xwc);
if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) {
XUnmapWindow (dpy, tmp->wmhints->icon_window);
}
}
}
void
Reborder (time)
Time time;
{
TwmWindow *tmp;
int scrnum;
XGrabServer (dpy);
for (scrnum = 0; scrnum < NumScreens; scrnum++)
{
if ((Scr = ScreenList[scrnum]) == NULL)
continue;
InstallWindowColormaps (0, &Scr->TwmRoot);
for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
{
RestoreWithdrawnLocation (tmp);
XMapWindow (dpy, tmp->w);
}
}
XUngrabServer (dpy);
SetFocus ((TwmWindow*)NULL, time);
}
static SIGNAL_T
sigHandler(int sig)
{
XtNoticeSignal(si);
SIGNAL_RETURN;
}
void
Done(XtPointer client_data, XtSignalId *si)
{
if (dpy)
{
Reborder(CurrentTime);
XCloseDisplay(dpy);
}
exit(0);
}
Bool ErrorOccurred = False;
XErrorEvent LastErrorEvent;
static int
TwmErrorHandler(dpy, event)
Display *dpy;
XErrorEvent *event;
{
LastErrorEvent = *event;
ErrorOccurred = True;
if (PrintErrorMessages &&
event->error_code != BadWindow &&
(event->request_code != X_GetGeometry &&
event->error_code != BadDrawable))
XmuPrintDefaultErrorMessage (dpy, event, stderr);
return 0;
}
static int
CatchRedirectError(dpy, event)
Display *dpy;
XErrorEvent *event;
{
RedirectError = TRUE;
LastErrorEvent = *event;
ErrorOccurred = True;
return 0;
}