-
Notifications
You must be signed in to change notification settings - Fork 0
/
misc.c
97 lines (87 loc) · 2.57 KB
/
misc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* evilwm - Minimalist Window Manager for X
* Copyright (C) 1999-2011 Ciaran Anscomb <[email protected]>
* see README for license and other details. */
#include <X11/Xproto.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include "evilwm.h"
#include "log.h"
int need_client_tidy = 0;
int ignore_xerror = 0;
/* Now do this by fork()ing twice so we don't have to worry about SIGCHLDs */
void spawn(const char *const cmd[]) {
ScreenInfo *current_screen = find_current_screen();
pid_t pid;
if (current_screen && current_screen->display)
putenv(current_screen->display);
if (!(pid = fork())) {
setsid();
switch (fork()) {
/* execvp()'s prototype is (char *const *) suggesting that it
* modifies the contents of the strings. The prototype is this
* way due to SUS maintaining compatability with older code.
* However, execvp guarantees not to modify argv, so the following
* cast is valid. */
case 0: execvp(cmd[0], (char *const *)cmd);
default: _exit(0);
}
}
if (pid > 0)
wait(NULL);
}
void handle_signal(int signo) {
(void)signo; /* unused */
wm_exit = 1;
}
int handle_xerror(Display *dsply, XErrorEvent *e) {
Client *c;
(void)dsply; /* unused */
LOG_ENTER("handle_xerror(error=%d, request=%d/%d, resourceid=%lx)", e->error_code, e->request_code, e->minor_code, e->resourceid);
if (ignore_xerror) {
LOG_DEBUG("ignoring...\n");
LOG_LEAVE();
return 0;
}
/* If this error actually occurred while setting up the new
* window, best let make_new_client() know not to bother */
if (initialising != None && e->resourceid == initialising) {
LOG_DEBUG("error caught while initialising window=%lx\n", initialising);
initialising = None;
LOG_LEAVE();
return 0;
}
if (e->error_code == BadAccess && e->request_code == X_ChangeWindowAttributes) {
LOG_ERROR("root window unavailable (maybe another wm is running?)\n");
exit(1);
}
c = find_client(e->resourceid);
if (c) {
LOG_DEBUG("flagging client for removal\n");
c->remove = 1;
need_client_tidy = 1;
} else {
LOG_DEBUG("unknown error: not handling\n");
}
LOG_LEAVE();
return 0;
}
/* Remove all enter events from the queue except the last of any corresponding
* to "except"s parent. */
void discard_enter_events(Client *except) {
XEvent tmp, putback_ev;
int putback = 0;
XSync(dpy, False);
while (XCheckMaskEvent(dpy, EnterWindowMask, &tmp)) {
if (tmp.xcrossing.window == except->parent) {
memcpy(&putback_ev, &tmp, sizeof(XEvent));
putback = 1;
}
}
if (putback) {
XPutBackEvent(dpy, &putback_ev);
}
}