Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:updated urls in info.html; replaced wmutil with muswm; key forwarding added to tmuxwm
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2510850a6251b7e9ffe60864fa11bc1229a4fc6d53351714af21a94c1d37c2db
User & Date: jmcclure 2018-04-15 01:37:23
Context
2018-04-15
01:43
Fixed info link to reflect wmutil -> muswm change check-in: cf14cdcd1d user: jmcclure tags: trunk
01:37
updated urls in info.html; replaced wmutil with muswm; key forwarding added to tmuxwm check-in: 2510850a62 user: jmcclure tags: trunk
2018-01-04
21:35
Added auth to xserver check-in: c6253f5282 user: jmcclure tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.

1
2


3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

CC       ?= gcc


PREFIX   ?= /usr

all:
	$(CC) -o xi xi.c $(CFLAGS) $(LDFLAGS)
	$(CC) -o wmutil wmutil.c $(CFLAGS) $(LDFLAGS) -lX11
	$(CC) -o tmuxwm tmuxwm.c $(CFLAGS) $(LDFLAGS) -lX11
	strip xi wmutil tmuxwm

install:
	install -Dm0755 xi $(DESTDIR)$(PREFIX)/bin/xi
	install -Dm0755 wmutil $(DESTDIR)$(PREFIX)/bin/wmutil
	install -Dm0755 tmuxwm $(DESTDIR)$(PREFIX)/bin/tmuxwm

clean:
	rm -f xi wmutil tmuxwm

|
>
>
|





<







|
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18

CC       = gcc
CFLAGS   = -march=native -O2 -pipe -fstack-protector-strong -fno-plt
LDFLAGS  = -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now
PREFIX   = /usr

all:
	$(CC) -o xi xi.c $(CFLAGS) $(LDFLAGS)
	$(CC) -o wmutil wmutil.c $(CFLAGS) $(LDFLAGS) -lX11
	$(CC) -o tmuxwm tmuxwm.c $(CFLAGS) $(LDFLAGS) -lX11


install:
	install -Dm0755 xi $(DESTDIR)$(PREFIX)/bin/xi
	install -Dm0755 wmutil $(DESTDIR)$(PREFIX)/bin/wmutil
	install -Dm0755 tmuxwm $(DESTDIR)$(PREFIX)/bin/tmuxwm

clean:
	rm -f xi wmutil tmuxwm tmuxwm2

Changes to info.html.

1
2
3
4
5
6
7
8
9
10
11
<div class="fossil-doc" data-title="Minimalist X Windows Session">

<section id="intro">
<h2>Overview</h2>
<dl>
<dt><a href="https://repo.jessemcclure.org/xtools/file/xi.c">xi</a></dt><dd>Minimal xinit replacement</dd>
<dt><a href="https://repo.jessemcclure.org/xtools/file/tmuxwm.c">tmuxwm</a></dt><dd>Tmux oriented fullsreen window manager</dd>
<dt><a href="https://repo.jessemcclure.org/xtools/file/wmutil.c">wmutil</a></dt><dd>Window manager utilities intended to be bound to keys</dd>
</dl>

</div>





|
|
|



1
2
3
4
5
6
7
8
9
10
11
<div class="fossil-doc" data-title="Minimalist X Windows Session">

<section id="intro">
<h2>Overview</h2>
<dl>
<dt><a href="https://code.jessemcclure.org/xtools/file/xi.c">xi</a></dt><dd>Minimal xinit replacement</dd>
<dt><a href="https://code.jessemcclure.org/xtools/file/tmuxwm.c">tmuxwm</a></dt><dd>Tmux oriented fullsreen window manager</dd>
<dt><a href="https://code.jessemcclure.org/xtools/file/wmutil.c">wmutil</a></dt><dd>Window manager utilities intended to be bound to keys</dd>
</dl>

</div>

Added muswm.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
/* MUSWM.C
 * Copyright Jesse McClure 2015-2018
 */

#include <X11/Xlib.h>

int main(int argc, const char **argv) {
	Display *dpy;
	if(!(dpy = XOpenDisplay(0x0))) return 1;
	Window root = DefaultRootWindow(dpy);
	XGrabButton(dpy, AnyButton, Mod4Mask, root, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
	XEvent ev;
	Window win;
	int button, ex, ey, sw, sh;
	sw = DisplayWidth(dpy, DefaultScreen(dpy));
	sh = DisplayHeight(dpy, DefaultScreen(dpy));
	XWindowAttributes wa;
	while (!XNextEvent(dpy,&ev)) {
		win = ev.xbutton.subwindow;
		if (ev.xbutton.button) button = ev.xbutton.button;
		ex = ev.xbutton.x_root;
		ey = ev.xbutton.y_root;
		if (button == 2)
			XMoveResizeWindow(dpy, win, 0, 0, sw, sh);
		else if (button < 4) switch (ev.type) {
		case ButtonPress:
			XGrabPointer(dpy, ev.xbutton.subwindow, True, PointerMotionMask|ButtonReleaseMask,
				GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
			XGetWindowAttributes(dpy, ev.xbutton.subwindow, &wa);
			wa.x -= ex; wa.width -= ex;
			wa.y -= ey; wa.height -= ey;
			button = ev.xbutton.button;
			break;
		case ButtonRelease:
			XUngrabPointer(dpy, CurrentTime);
		case MotionNotify:
			while (XCheckTypedEvent(dpy, MotionNotify, &ev));
			if (button == 1) XMoveWindow(dpy, ev.xmotion.window, wa.x + ex, wa.y + ey);
			else if (button == 3) XResizeWindow(dpy, ev.xmotion.window, wa.width + ex, wa.height + ey);
		}
	}
	return 0;
}

Changes to tmuxwm.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
98

99
100
101
102
103
104
105




106

107



108


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132


133
134














135
136
137
138
139
140
141
/* tmuxwm.c
 * --------
 * Minimalist WM with tmux session
 * --------
 *
 * Copyright (c) 2017 Jesse McClure <code@jessemcclure.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 */

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>


typedef struct Bind { KeySym sym; int mod; const char * const *args; } Bind;
typedef const char * const Arg[];

Arg tmux_client = (Arg) { "urxvt", "-e", "tmux", "new-session", "-AD", "-s", "TmuxWM", NULL };

static void cycle(void);

#include <X11/XF86keysym.h>
static Bind bind[] = {
	{ XK_Return, ShiftMask | Mod4Mask, tmux_client },
	{ XK_Return,             Mod4Mask, (Arg) { "tmux", "new-window", NULL } },
	{ XK_Tab,                Mod4Mask, (Arg) { "tmux", "next-window", NULL } },
	{ XK_space,              Mod4Mask, (Arg) { "plumb", NULL } },
	{ XK_1,                  Mod4Mask, (Arg) { "tmux", "select-window", "-t", "1", NULL } },
	{ XK_2,                  Mod4Mask, (Arg) { "tmux", "select-window", "-t", "2", NULL } },
	{ XK_3,                  Mod4Mask, (Arg) { "tmux", "select-window", "-t", "3", NULL } },
	{ XK_4,                  Mod4Mask, (Arg) { "tmux", "select-window", "-t", "4", NULL } },
	{ XK_5,                  Mod4Mask, (Arg) { "tmux", "select-window", "-t", "5", NULL } },
	/* Launchers / Misc */
	{ XK_w,                  Mod4Mask, (Arg) { "qutebrowser", NULL} },
	{ XK_F4,                 Mod1Mask, (Arg) { "wmutil", "kill", NULL} },
	{ XK_Up,                 Mod4Mask, (Arg) { "wmutil", "move", "Y", "-10", NULL} },
	{ XK_Down,               Mod4Mask, (Arg) { "wmutil", "move", "Y", "+10", NULL} },
	{ XK_Left,               Mod4Mask, (Arg) { "wmutil", "move", "X", "-10", NULL} },
	{ XK_Right,              Mod4Mask, (Arg) { "wmutil", "move", "X", "+10", NULL} },
	{ XK_Up,     ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "H", "-10", NULL} },
	{ XK_Down,   ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "H", "+10", NULL} },
	{ XK_Left,   ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "W", "-10", NULL} },
	{ XK_Right,  ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "W", "+10", NULL} },
	{ XF86XK_AudioRaiseVolume,      0, (Arg) { "amixer", "set", "Master", "2+", NULL} },
	{ XF86XK_AudioLowerVolume,      0, (Arg) { "amixer", "set", "Master", "2-", NULL} },
	{ XF86XK_AudioMute,             0, (Arg) { "amixer", "set", "Master", "toggle", NULL} },
	{ XF86XK_ScreenSaver,           0, (Arg) { "slock", NULL} },
};

static void configurerequest(XEvent *);
static void enternotify(XEvent *);
static void keypress(XEvent *);
static void maprequest(XEvent *);
static void unmapnotify(XEvent *);

static Display *dpy;
static Window root;
static int sw, sh;
static void (*handler[LASTEvent])(XEvent *) = {
	[ConfigureRequest]   = configurerequest,
	[EnterNotify]        = enternotify,
	[KeyPress]           = keypress,
	[MapRequest]         = maprequest,
};

static int xerror(Display *d, XErrorEvent *e) {
	char msg[256];
	XGetErrorText(d, e->error_code, msg, sizeof(msg));
	return fprintf(stderr,"[X11 %d:%d] %s\n", e->request_code, e->error_code, msg);
}

static int spawn(Arg args) {
	if (fork() != 0) return 1;
	close(ConnectionNumber(dpy));
	setsid();
	if (fork() != 0) exit(0);
	return execvp(args[0], (char * const *) args);
}

int main(int argc, const char **argv) {
	signal(SIGCHLD, SIG_IGN);
	if(!(dpy = XOpenDisplay(0x0))) return 1;
	XSetErrorHandler(xerror);

	root = DefaultRootWindow(dpy);
	XSetWindowBackground(dpy, root, 0x060812);
	XDefineCursor(dpy, root, XCreateFontCursor(dpy, 68));
	sw = DisplayWidth(dpy, DefaultScreen(dpy));
	sh = DisplayHeight(dpy, DefaultScreen(dpy));
	int i;
	XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), Mod1Mask, root, True, GrabModeAsync, GrabModeAsync);




	for (i = 0; i < sizeof(bind)/sizeof(bind[0]); ++i)

		XGrabKey(dpy, XKeysymToKeycode(dpy, bind[i].sym), bind[i].mod, root, True, GrabModeAsync, GrabModeAsync);



	XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask);


	XEvent ev;
	spawn(tmux_client);
	while (!XNextEvent(dpy,&ev))
		if (handler[ev.type]) handler[ev.type](&ev);
	return 0;
}

void configurerequest(XEvent *ev) {
	XConfigureRequestEvent *e = &ev->xconfigurerequest;
	int bpx = (e->x == 0 && e->y == 0 && e->width == sw && e->height == sh ? 0 : 2);
	XWindowChanges wc = { e->x, e->y, e->width, e->height, bpx, e->detail, Above };
	XConfigureWindow(dpy, e->window, e->value_mask | CWBorderWidth, &wc);
}

void enternotify(XEvent *ev) {
	XSetInputFocus(dpy, ev->xcrossing.window, RevertToPointerRoot, CurrentTime);
	XRaiseWindow(dpy, ev->xcrossing.window);
}

void keypress(XEvent *ev) {
	XKeyEvent *e = &ev->xkey;
	KeySym sym = XkbKeycodeToKeysym(dpy, e->keycode, 0, 0);
	int i;
	if (e->state == Mod1Mask && sym == XK_Tab) XCirculateSubwindowsUp(dpy, root);


	else for (i = 0; i < sizeof(bind)/sizeof(bind[0]); ++i)
		if (bind[i].sym == sym && bind[i].mod == e->state) spawn(bind[i].args);














}

void maprequest(XEvent *ev) {
	XMapRequestEvent *e = &ev->xmaprequest;
	XWindowAttributes wa;
	if (!XGetWindowAttributes(dpy, e->window, &wa) || wa.override_redirect) return;
	XWMHints *wmHint = XGetWMHints(dpy,e->window);
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
>



<






>

|
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|


















<
<
<
<
<
<
|




|


|
<

<
>





<

>
>
>
>
|
>
|
>
>
>
|
>
>

<














<







>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* TMUXWM.C




 * Copyright Jesse McClure 2015-2018












 * Compile: gcc -o tmuxwm tmuxwm.c -lX11
 */

#include <stdlib.h>

#include <signal.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <X11/XF86keysym.h>

static struct { KeySym sym; char **args; }  bind[] = {

	/* No keysym = start with WM.  First is Mod+Shift+Enter bound */
	{ 0,                        (char *[]) { "st", "-e", "tmux", "new-session", "-AD", "-s", "TmuxWM", NULL } },
	{ 0,                        (char *[]) { "setxkbmap", "-option", "caps:escape", NULL } },
























	{ XF86XK_AudioRaiseVolume,  (char *[]) { "amixer", "set", "Master", "2+", NULL} },
	{ XF86XK_AudioLowerVolume,  (char *[]) { "amixer", "set", "Master", "2-", NULL} },
	{ XF86XK_AudioMute,         (char *[]) { "amixer", "set", "Master", "toggle", NULL} },
	{ XF86XK_ScreenSaver,       (char *[]) { "slock", NULL} },
};

static void configurerequest(XEvent *);
static void enternotify(XEvent *);
static void keypress(XEvent *);
static void maprequest(XEvent *);
static void unmapnotify(XEvent *);

static Display *dpy;
static Window root;
static int sw, sh;
static void (*handler[LASTEvent])(XEvent *) = {
	[ConfigureRequest]   = configurerequest,
	[EnterNotify]        = enternotify,
	[KeyPress]           = keypress,
	[MapRequest]         = maprequest,
};







static int spawn(char *const *args) {
	if (fork() != 0) return 1;
	close(ConnectionNumber(dpy));
	setsid();
	if (fork() != 0) exit(0);
	return execvp(args[0], args);
}

static int init() {

	if(!(dpy = XOpenDisplay(0x0))) return 1;

	signal(SIGCHLD, SIG_IGN);
	root = DefaultRootWindow(dpy);
	XSetWindowBackground(dpy, root, 0x060812);
	XDefineCursor(dpy, root, XCreateFontCursor(dpy, 68));
	sw = DisplayWidth(dpy, DefaultScreen(dpy));
	sh = DisplayHeight(dpy, DefaultScreen(dpy));

	XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), Mod1Mask, root, True, GrabModeAsync, GrabModeAsync);
	XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Return), Mod4Mask | ShiftMask, root, True, GrabModeAsync, GrabModeAsync);
	XGrabKey(dpy, AnyKey, Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
	XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask);
	int i;
	for (i = 0; i < sizeof(bind) / sizeof(bind[0]); i++) {
		if (bind[i].sym == 0) spawn(bind[i].args);
		else XGrabKey(dpy, XKeysymToKeycode(dpy, bind[i].sym), 0, root, True, GrabModeAsync, GrabModeAsync);
	}
	return 0;
}

int main() {
	if (init() != 0) return 1;
	XEvent ev;

	while (!XNextEvent(dpy,&ev))
		if (handler[ev.type]) handler[ev.type](&ev);
	return 0;
}

void configurerequest(XEvent *ev) {
	XConfigureRequestEvent *e = &ev->xconfigurerequest;
	int bpx = (e->x == 0 && e->y == 0 && e->width == sw && e->height == sh ? 0 : 2);
	XWindowChanges wc = { e->x, e->y, e->width, e->height, bpx, e->detail, Above };
	XConfigureWindow(dpy, e->window, e->value_mask | CWBorderWidth, &wc);
}

void enternotify(XEvent *ev) {
	XSetInputFocus(dpy, ev->xcrossing.window, RevertToPointerRoot, CurrentTime);

}

void keypress(XEvent *ev) {
	XKeyEvent *e = &ev->xkey;
	KeySym sym = XkbKeycodeToKeysym(dpy, e->keycode, 0, 0);
	int i;
	if (e->state == Mod1Mask && sym == XK_Tab) XCirculateSubwindowsUp(dpy, root);
	else if (e->state == (Mod4Mask|ShiftMask) && sym == XK_Return) spawn(bind[0].args);
	else if (e->state == 0) {
		for (i = 0; i < sizeof(bind) / sizeof(bind[0]); i++)
			if (bind[i].sym == sym) spawn(bind[i].args);
	}
	else if (e->state == Mod4Mask) {
		XEvent xev;
		xev.type = KeyPress;
		xev.xkey.window = e->subwindow;
		xev.xkey.time = CurrentTime;
		xev.xkey.state = ControlMask;
		xev.xkey.keycode = XKeysymToKeycode(dpy, XK_space);
		XSendEvent(dpy, e->subwindow, True, KeyPressMask, &xev);
		xev.xkey.state = 0;
		xev.xkey.keycode = e->keycode;
		XSendEvent(dpy, e->subwindow, True, KeyPressMask, &xev);
		XFlush(dpy);
	}
}

void maprequest(XEvent *ev) {
	XMapRequestEvent *e = &ev->xmaprequest;
	XWindowAttributes wa;
	if (!XGetWindowAttributes(dpy, e->window, &wa) || wa.override_redirect) return;
	XWMHints *wmHint = XGetWMHints(dpy,e->window);

Deleted wmutil.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
/* wmutil.c
 * --------
 * Window Manager Utilities
 * --------
 *
 * Copyright (c) 2017 Jesse McClure <code@jessemcclure.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

static Display *dpy;
static Window root;
static int sw, sh;

void send_message(Window win, const char *type, const char *msg) {
	XEvent ev;
	ev.type = ClientMessage;
	ev.xclient.window = win;
	ev.xclient.message_type = XInternAtom(dpy, type, False);
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = XInternAtom(dpy, msg, False);;
	ev.xclient.data.l[1] = CurrentTime;
	XSendEvent(dpy, win, False, NoEventMask, &ev);
}

void kill(Window win) {
	send_message(win, "WM_PROTOCOLS", "WM_DELETE_WINDOW");
}

void external(Window win) {
	// TODO
}

void move_resize(Window win, const char *arg, int delta) {
	XWindowAttributes wa;
	XGetWindowAttributes(dpy, win, &wa);
	switch (arg[0]) {
		case 'h': case 'H': wa.height += delta; break;
		case 'w': case 'W': wa.width += delta; break;
		case 'x': case 'X': wa.x += delta; break;
		case 'y': case 'Y': wa.y += delta; break;
	}
	XMoveResizeWindow(dpy, win, wa.x, wa.y, wa.width, wa.height);
}

int main(int argc, char *const argv[]) {
	if (!(dpy = XOpenDisplay(0x0)) || argc < 2) return 1;
	root = DefaultRootWindow(dpy);
	sw = DisplayWidth(dpy, DefaultScreen(dpy));
	sh = DisplayHeight(dpy, DefaultScreen(dpy));
	Window win;
	int ig;
	if ((win=atoi(argv[1])) && argc > 2) argv++;
	else XGetInputFocus(dpy, &win, &ig);
	switch (argv[1][0]) {
		case 'e': case 'x': external(win); break;
		case 'k': kill(win); break;
		case 'm': if (argc > 3) move_resize(win, argv[2], atoi(argv[3])); break;
		case 's': if (argc > 3) send_message(win, argv[2], argv[3]); break;
	}
	XCloseDisplay(dpy);
	return 0;
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































Changes to xi.c.

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
		return 1;
	}
	char dpy[] = { ':', '0' + vtstat.v_active, 0 };
	char tty[] = { 'v', 't', '0' + vtstat.v_active, 0 };
	char xauth[PATH_MAX];
	snprintf(xauth, PATH_MAX, "%s/%s", getenv("HOME"), ".Xauthority");

	struct sigaction sa = { 0, 0, 0, 0, 0 };
	sa.sa_handler = handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGUSR1, &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);

	int xpid = server(dpy, tty, xauth);
	while (!xrunning) pause();
	int cpid = client(dpy, (argc > 1 ? argv[1] : ".xirc" ), xauth);
	while (xrunning) pause();

	kill(cpid, SIGTERM);
	waitpid(cpid, NULL, 0);
	kill(xpid, SIGTERM);
	waitpid(xpid, NULL, 0);
	return 0;
}







|









|








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
		return 1;
	}
	char dpy[] = { ':', '0' + vtstat.v_active, 0 };
	char tty[] = { 'v', 't', '0' + vtstat.v_active, 0 };
	char xauth[PATH_MAX];
	snprintf(xauth, PATH_MAX, "%s/%s", getenv("HOME"), ".Xauthority");

	struct sigaction sa;
	sa.sa_handler = handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGUSR1, &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);

	int xpid = server(dpy, tty, xauth);
	while (!xrunning) pause();
	int cpid = client(dpy, (argc > 1 ? argv[1] : "xterm" ), xauth);
	while (xrunning) pause();

	kill(cpid, SIGTERM);
	waitpid(cpid, NULL, 0);
	kill(xpid, SIGTERM);
	waitpid(xpid, NULL, 0);
	return 0;
}