CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/ctwm_takeover.c
Go to the documentation of this file.
1
/*
2
* Taking over the screen
3
*/
4
5
#include "
ctwm.h
"
6
7
#include <stdio.h>
8
#include <X11/Xproto.h>
9
#include <X11/Xmu/Error.h>
10
11
#include "
ctwm_takeover.h
"
12
#include "
screen.h
"
13
14
15
/// Flag for "we got an error trying to take over". Set in temporary
16
/// error handler.
17
static
bool
RedirectError
;
18
19
// Our special during-takeover and normal operating error handlers.
20
static
int
CatchRedirectError
(
Display
*
display
,
XErrorEvent
*
event
);
21
static
int
TwmErrorHandler
(
Display
*
display
,
XErrorEvent
*
event
);
22
23
24
25
/**
26
* Take over as WM for a screen
27
*/
28
bool
29
takeover_screen
(
ScreenInfo
*scr)
30
{
31
unsigned
long
attrmask
;
32
33
#ifdef EWMH
34
// Early EWMH setup. This tries to do the EWMH display takeover.
35
EwmhInitScreenEarly
(scr);
36
#endif
37
38
39
/*
40
* Subscribe to various events on the root window. Because X
41
* only allows a single client to subscribe to
42
* SubstructureRedirect and ButtonPress bits, this also serves to
43
* mutex who is The WM for the root window, and thus (aside from
44
* captive) the Screen.
45
*
46
* To catch whether that failed, we set a special one-shot error
47
* handler to flip a var that we test to find out whether the
48
* redirect failed.
49
*/
50
// Flush out any previous errors
51
XSync
(
dpy
, 0);
52
53
// Set our event listening mask
54
RedirectError
=
false
;
55
XSetErrorHandler
(
CatchRedirectError
);
56
attrmask
=
ColormapChangeMask
|
EnterWindowMask
|
57
PropertyChangeMask
|
SubstructureRedirectMask
|
58
KeyPressMask
|
ButtonPressMask
|
ButtonReleaseMask
;
59
#ifdef EWMH
60
attrmask
|=
StructureNotifyMask
;
61
#endif
62
#ifdef CAPTIVE
63
if
(
CLarg
.is_captive) {
64
attrmask
|=
StructureNotifyMask
;
65
}
66
#endif
67
XSelectInput
(
dpy
, scr->
Root
,
attrmask
);
68
69
// Make sure we flush out any errors that may have caused. This
70
// ensures our RedirectError flag will be set if the server sent us
71
// one.
72
XSync
(
dpy
, 0);
73
74
// Go ahead and set our normal-operation error handler.
75
XSetErrorHandler
(
TwmErrorHandler
);
76
77
// So, did we fail?
78
if
(
RedirectError
) {
79
fprintf
(
stderr
,
"%s: another window manager is already running"
,
80
ProgramName
);
81
if
(
CLarg
.
MultiScreen
&&
NumScreens
> 0) {
82
fprintf
(
stderr
,
" on screen %d?\n"
, scr->
screen
);
83
}
84
else
{
85
fprintf
(
stderr
,
"?\n"
);
86
}
87
88
// XSetErrorHandler() isn't local to the Screen; it's for the
89
// whole connection. We wind up in a slightly weird state
90
// once we've set it up, but decided we aren't taking over
91
// this screen, but resetting it would be a little weird too,
92
// because maybe we have taken over some other screen. So,
93
// just throw up our hands.
94
return
false
;
95
}
96
97
// Nope, it's ours!
98
return
true
;
99
}
100
101
102
103
/**
104
* Temporary error handler used during startup. We expect an
105
* error if we fail to take over some of the XSelectInput() events
106
* we're trying to (which only 1 thing at a time is allowed to).
107
* Probably that would be a BadAccess error type? But really, any error
108
* means we're in trouble and should skip over the display, so we don't
109
* check any more deeply...
110
*/
111
static
int
112
CatchRedirectError
(
Display
*
display
,
XErrorEvent
*
event
)
113
{
114
// Set the global flag
115
RedirectError
=
true
;
116
return
0;
117
}
118
119
120
/**
121
* Error handler used in normal operation. Or, perhaps, error ignorer
122
* used in normal operation. If run with `-v`, we'll print out a lot of
123
* the errors we might get, though we always skip several.
124
*/
125
static
int
126
TwmErrorHandler
(
Display
*
display
,
XErrorEvent
*
event
)
127
{
128
if
(!
CLarg
.
PrintErrorMessages
) {
129
// Not `-v`? Always be silent.
130
return
0;
131
}
132
133
// If a client dies and we try to touch it before we notice, we get a
134
// BadWindow error for most operations, except a few (GetGeometry
135
// being the big one?) where we'll get a BadDrawable. This isn't
136
// really an "error", just a harmless race.
137
if
(
event
->error_code ==
BadWindow
138
|| (
event
->request_code ==
X_GetGeometry
&&
event
->error_code !=
BadDrawable
)) {
139
return
0;
140
}
141
142
// Else, we're `-v`'d, and it wasn't one of our 'expected' bits, so
143
// talk about it.
144
XmuPrintDefaultErrorMessage
(
display
,
event
,
stderr
);
145
return
0;
146
}
PlaceX
static int PlaceX
Definition
add_window.c:82
CLarg
ctwm_cl_args CLarg
Definition
clargs.c:27
ctwm.h
ProgramName
char * ProgramName
Definition
ctwm_main.c:146
dpy
Display * dpy
Definition
ctwm_main.c:84
NumScreens
int NumScreens
How many Screens are on our display.
Definition
ctwm_main.c:89
TwmErrorHandler
static int TwmErrorHandler(Display *display, XErrorEvent *event)
Error handler used in normal operation.
Definition
ctwm_takeover.c:126
takeover_screen
bool takeover_screen(ScreenInfo *scr)
Take over as WM for a screen.
Definition
ctwm_takeover.c:29
RedirectError
static bool RedirectError
Flag for "we got an error trying to take over".
Definition
ctwm_takeover.c:17
CatchRedirectError
static int CatchRedirectError(Display *display, XErrorEvent *event)
Temporary error handler used during startup.
Definition
ctwm_takeover.c:112
ctwm_takeover.h
EwmhInitScreenEarly
bool EwmhInitScreenEarly(ScreenInfo *scr)
Definition
ewmh.c:307
ScreenInfo::Root
Window Root
Root window for the current vscreen.
Definition
screen.h:194
screen.h
ScreenInfo
Info and control for each X Screen we control.
Definition
screen.h:96
ScreenInfo::screen
int screen
Which screen (i.e., the x after the dot in ":0.x")
Definition
screen.h:97
_ctwm_cl_args::PrintErrorMessages
bool PrintErrorMessages
Definition
ctwm.h:393
_ctwm_cl_args::MultiScreen
bool MultiScreen
Definition
ctwm.h:387
Generated by
1.10.0