quake-style console with xterm
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

initial revision

jcs bebb83c8

+281
+43
Makefile
··· 1 + # $Id: Makefile,v 1.1 2008/10/02 05:25:26 jcs Exp $ 2 + # vim:ts=8 3 + 4 + CC = cc 5 + CFLAGS = -g -O2 -Wall -Wunused -Wmissing-prototypes -Wstrict-prototypes 6 + 7 + PREFIX = /usr/local 8 + BINDIR = $(DESTDIR)$(PREFIX)/bin 9 + 10 + INSTALL_PROGRAM = install -s 11 + 12 + X11BASE = /usr/X11R6 13 + INCLUDES= -I$(X11BASE)/include 14 + LDPATH = -L$(X11BASE)/lib 15 + LIBS = -lX11 16 + 17 + PROG = qconsole 18 + OBJS = qconsole.o 19 + 20 + VERS := `grep Id qconsole.c | sed -e 's/.*,v //' -e 's/ .*//'` 21 + 22 + all: $(PROG) 23 + 24 + $(PROG): $(OBJS) 25 + $(CC) $(OBJS) $(LDPATH) $(LIBS) -o $@ 26 + 27 + $(OBJS): *.o: *.c 28 + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ 29 + 30 + install: all 31 + $(INSTALL_PROGRAM) $(PROG) $(BINDIR) 32 + 33 + clean: 34 + rm -f $(PROG) $(OBJS) 35 + 36 + release: all 37 + @mkdir $(PROG)-${VERS} 38 + @cp Makefile *.c $(PROG)-$(VERS)/ 39 + @tar -czf ../$(PROG)-$(VERS).tar.gz $(PROG)-$(VERS) 40 + @rm -rf $(PROG)-$(VERS)/ 41 + @echo "made release ${VERS}" 42 + 43 + .PHONY: all install clean
+238
qconsole.c
··· 1 + /* vim:ts=8 2 + * $Id: qconsole.c,v 1.1 2008/10/02 05:25:26 jcs Exp $ 3 + * 4 + * qconsole 5 + * 6 + * Copyright (c) 2005, 2008 joshua stein <jcs@jcs.org> 7 + * 8 + * Redistribution and use in source and binary forms, with or without 9 + * modification, are permitted provided that the following conditions 10 + * are met: 11 + * 12 + * 1. Redistributions of source code must retain the above copyright 13 + * notice, this list of conditions and the following disclaimer. 14 + * 2. Redistributions in binary form must reproduce the above copyright 15 + * notice, this list of conditions and the following disclaimer in the 16 + * documentation and/or other materials provided with the distribution. 17 + * 3. The name of the author may not be used to endorse or promote products 18 + * derived from this software without specific prior written permission. 19 + * 20 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 + */ 31 + 32 + #include <err.h> 33 + #include <getopt.h> 34 + #include <signal.h> 35 + #include <stdio.h> 36 + #include <stdlib.h> 37 + #include <string.h> 38 + #include <time.h> 39 + #include <unistd.h> 40 + #include <sys/types.h> 41 + #include <sys/wait.h> 42 + 43 + #include <X11/Xlib.h> 44 + #include <X11/Xutil.h> 45 + 46 + /* so our window manager knows us */ 47 + char* win_name = "qconsole"; 48 + 49 + struct xinfo { 50 + Display* dpy; 51 + int dpy_width, dpy_height; 52 + int screen; 53 + Window win; 54 + int width; 55 + int height; 56 + } x; 57 + 58 + pid_t xterm_pid = 0; 59 + int shutting_down = 0; 60 + 61 + extern char *__progname; 62 + 63 + void xterm_handler(int sig); 64 + void exit_handler(int sig); 65 + void draw_window(void); 66 + void scroll_down(void); 67 + void usage(void); 68 + 69 + int 70 + main(int argc, char* argv[]) 71 + { 72 + XEvent event; 73 + 74 + signal(SIGCHLD, xterm_handler); 75 + 76 + signal(SIGINT, exit_handler); 77 + signal(SIGTERM, exit_handler); 78 + 79 + draw_window(); 80 + 81 + /* all set, fire up xterm */ 82 + xterm_handler(0); 83 + 84 + for (;;) { 85 + bzero(&event, sizeof(XEvent)); 86 + XNextEvent (x.dpy, &event); 87 + 88 + if (event.type == ReparentNotify) { 89 + XReparentEvent *e = (XReparentEvent *) &event; 90 + 91 + printf("got notify signal, win is %d\n", 92 + e->window); 93 + 94 + XMoveWindow(x.dpy, e->window, 0, 0); 95 + XResizeWindow(x.dpy, e->window, x.width, x.height); 96 + XSetInputFocus(x.dpy, e->window, RevertToParent, 97 + CurrentTime); 98 + 99 + scroll_down(); 100 + } else 101 + printf("unknown event type 0x%x for win %d\n", 102 + event.type, event.xany.window); 103 + } 104 + 105 + exit(1); 106 + } 107 + 108 + void 109 + draw_window(void) 110 + { 111 + int rc; 112 + char *display = NULL; 113 + XSetWindowAttributes attributes; 114 + XTextProperty win_name_prop; 115 + 116 + bzero(&x, sizeof(struct xinfo)); 117 + 118 + if (!(x.dpy = XOpenDisplay(display))) 119 + errx(1, "Unable to open display %s", XDisplayName(display)); 120 + /* NOTREACHED */ 121 + 122 + x.screen = DefaultScreen(x.dpy); 123 + 124 + x.width = x.dpy_width = DisplayWidth(x.dpy, x.screen); 125 + x.dpy_height = DisplayHeight(x.dpy, x.screen); 126 + 127 + x.height = x.dpy_height / 5; 128 + 129 + x.win = XCreateSimpleWindow(x.dpy, RootWindow(x.dpy, x.screen), 130 + 0, -(x.height), 131 + x.width, x.height, 132 + 0, 133 + BlackPixel(x.dpy, x.screen), 134 + BlackPixel(x.dpy, x.screen)); 135 + 136 + if (!(rc = XStringListToTextProperty(&win_name, 1, &win_name_prop))) 137 + errx(1, "XStringListToTextProperty"); 138 + /* NOTREACHED */ 139 + 140 + XSetWMName(x.dpy, x.win, &win_name_prop); 141 + 142 + /* remove all window manager decorations and force our position/size */ 143 + /* XXX: apparently this is not very nice */ 144 + attributes.override_redirect = True; 145 + XChangeWindowAttributes(x.dpy, x.win, CWOverrideRedirect, &attributes); 146 + 147 + XMapWindow(x.dpy, x.win); 148 + 149 + XFlush(x.dpy); 150 + XSync(x.dpy, False); 151 + 152 + /* we want to know when we're exposed */ 153 + XSelectInput(x.dpy, x.win, SubstructureNotifyMask); 154 + } 155 + 156 + void 157 + exit_handler(int sig) 158 + { 159 + shutting_down = 1; 160 + 161 + if (xterm_pid) 162 + kill(xterm_pid, SIGKILL); 163 + 164 + XCloseDisplay(x.dpy); 165 + 166 + exit(0); 167 + /* NOTREACHED */ 168 + } 169 + void 170 + xterm_handler(int sig) 171 + { 172 + char *pargv[8] = { 173 + "xterm", "-bg", "black", "-fg", "gray", "-into", "", 174 + NULL 175 + }; 176 + pid_t pid; 177 + 178 + if (shutting_down) 179 + return; 180 + 181 + printf("in xterm_handler\n"); 182 + 183 + if (xterm_pid) { 184 + int s; 185 + 186 + XUnmapSubwindows(x.dpy, x.win); 187 + 188 + printf("waiting\n"); 189 + wait(&s); 190 + printf("done\n"); 191 + xterm_pid = 0; 192 + } 193 + 194 + if (!xterm_pid) { 195 + switch (pid = fork()) { 196 + case -1: 197 + errx(1, "Unable to fork"); 198 + case 0: 199 + asprintf(&pargv[6], "%d", x.win); 200 + execvp("xterm", pargv); 201 + exit(0); 202 + 203 + default: 204 + xterm_pid = pid; 205 + } 206 + } 207 + } 208 + 209 + void 210 + scroll_down(void) 211 + { 212 + int cur_x, cur_y, j; 213 + unsigned width, height, bw, depth; 214 + Window root; 215 + 216 + XGetGeometry(x.dpy, x.win, &root, 217 + &cur_x, &cur_y, &width, &height, &bw, &depth); 218 + 219 + printf("currently at %d/%d\n", cur_x, cur_y); 220 + 221 + for (j = cur_y; j <= 0;) { 222 + printf("moving to %d/%d\n", 0, j); 223 + XMoveWindow(x.dpy, x.win, 0, j); 224 + XFlush(x.dpy); 225 + XSync(x.dpy, False); 226 + j -= (cur_y / 20) - 1; 227 + } 228 + 229 + XMoveWindow(x.dpy, x.win, 0, 0); 230 + } 231 + 232 + void 233 + usage(void) 234 + { 235 + fprintf(stderr, "usage: %s %s\n", __progname, 236 + "[-display host:dpy] [-width <pixels>] [time time2 ...]"); 237 + exit(1); 238 + }