File: misc.c

package info (click to toggle)
evilwm 1.0.0-1
  • links: PTS
  • area: main
  • in suites: lenny, squeeze, wheezy
  • size: 180 kB
  • ctags: 245
  • sloc: ansic: 1,976; makefile: 90; sh: 28
file content (86 lines) | stat: -rw-r--r-- 2,538 bytes parent folder | download
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
/* evilwm - Minimalist Window Manager for X
 * Copyright (C) 1999-2007 Ciaran Anscomb <evilwm@6809.org.uk>
 * see README for license and other details. */

#include <X11/Xproto.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.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()) {
			/* Expect compiler warnings because of half-broken SUS
			 * execvp prototype:  "char *const argv[]" should have
			 * been "const char *const argv[]", but the committee
			 * favored legacy code over modern code, and modern
			 * compilers bark at our extra const. (LD) */
			case 0: execvp(cmd[0], cmd+1);
			default: _exit(0);
		}
	}
	if (pid > 0)
		wait(NULL);
}

void handle_signal(int signo) {
	int i;
	(void)signo;  /* unused */
	/* SIGCHLD check no longer necessary */
	/* Quit Nicely */
	while(head_client) remove_client(head_client);
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
	if (font) XFreeFont(dpy, font);
	for (i = 0; i < num_screens; i++) {
		XFreeGC(dpy, screens[i].invert_gc);
		XInstallColormap(dpy, DefaultColormap(dpy, i));
	}
	free(screens);
	XCloseDisplay(dpy);
	exit(0);
}

int handle_xerror(Display *dsply, XErrorEvent *e) {
	Client *c;
	(void)dsply;  /* unused */

	if (ignore_xerror) {
		LOG_DEBUG("handle_xerror() ignored an XErrorEvent: %d\n", e->error_code);
		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("\t **SAVED?** handle_xerror() caught error %d while initialising\n", e->error_code);
		initialising = None;
		return 0;
	}
	LOG_DEBUG("**ERK** handle_xerror() caught an XErrorEvent: error_code=%d request_code=%d minor_code=%d\n",
			e->error_code, e->request_code, e->minor_code);
	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("\thandle_xerror() : flagging client for removal\n");
		c->remove = 1;
		need_client_tidy = 1;
	}
	return 0;
}