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: |
2510850a6251b7e9ffe60864fa11bc12 |
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
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 .. 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 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 .. 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 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;
}
|