several new changes, made gridmenu working 39677ec7
Anselm R. Garbe · 2006-07-10 19:46 9 file(s) · +256 −206
Makefile +10 −4
5 5
6 6
WMSRC = wm.c draw.c util.c
7 7
WMOBJ = ${WMSRC:.c=.o}
8 +
MENSRC = gridmenu.c draw.c util.c
9 +
MENOBJ = ${MENSRC:.c=.o}
8 10
MAN = gridwm.1
9 11
BIN = gridwm gridmenu     
10 12
11 -
all: config gridwm
13 +
all: config gridwm gridmenu
12 14
	@echo finished
13 15
14 16
config:
22 24
	@echo CC $<
23 25
	@${CC} -c ${CFLAGS} $<
24 26
25 -
${WMOBJ}: wm.h draw.h config.h
27 +
${WMOBJ}: wm.h draw.h config.h util.h
28 +
29 +
gridmenu: ${MENOBJ}
30 +
	@echo LD $@
31 +
	@${CC} -o $@ ${MENOBJ} ${LDFLAGS}
26 32
27 33
gridwm: ${WMOBJ}
28 34
	@echo LD $@
29 35
	@${CC} -o $@ ${WMOBJ} ${LDFLAGS}
30 36
31 37
clean:
32 -
	rm -f gridwm *.o
38 +
	rm -f gridwm gridmenu *.o core
33 39
34 40
dist: clean
35 41
	mkdir -p gridwm-${VERSION}
36 -
	cp -R Makefile README LICENSE config.mk ${WMSRC} ${MAN} gridwm-${VERSION}
42 +
	cp -R Makefile README LICENSE config.mk *.h *.c ${MAN} gridwm-${VERSION}
37 43
	tar -cf gridwm-${VERSION}.tar gridwm-${VERSION}
38 44
	gzip gridwm-${VERSION}.tar
39 45
	rm -rf gridwm-${VERSION}
config.h +4 −4
3 3
 * See LICENSE file for license details.
4 4
 */
5 5
6 -
#define FONT	"fixed"
7 -
#define FGCOLOR	"#000000"
8 -
#define BGCOLOR	"#ffaa00"
9 -
#define BOCOLOR	"#000000"
6 +
#define FONT		"-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*"
7 +
#define FGCOLOR		"#000000"
8 +
#define BGCOLOR		"#ffaa00"
9 +
#define BORDERCOLOR	"#000000"
draw.c +21 −20
14 14
{
15 15
	XPoint points[5];
16 16
	XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter);
17 -
	XSetForeground(dpy, b->gc, b->color.border);
17 +
	XSetForeground(dpy, b->gc, b->border);
18 18
	points[0].x = b->rect.x;
19 19
	points[0].y = b->rect.y;
20 20
	points[1].x = b->rect.width - 1;
29 29
}
30 30
31 31
void
32 -
draw(Display *dpy, Brush *b)
32 +
draw(Display *dpy, Brush *b, Bool border, const char *text)
33 33
{
34 34
	unsigned int x, y, w, h, len;
35 35
	static char buf[256];
36 36
	XGCValues gcv;
37 37
38 -
	XSetForeground(dpy, b->gc, b->color.bg);
38 +
	XSetForeground(dpy, b->gc, b->bg);
39 39
	XFillRectangles(dpy, b->drawable, b->gc, &b->rect, 1);
40 40
41 -
	if(b->border)
41 +
	if(border)
42 42
		drawborder(dpy, b);
43 43
44 -
	if(!b->text)
44 +
	if(!text)
45 45
		return;
46 46
47 -
	len = strlen(b->text);
47 +
	len = strlen(text);
48 48
	if(len >= sizeof(buf))
49 49
		len = sizeof(buf) - 1;
50 -
	memcpy(buf, b->text, len);
50 +
	memcpy(buf, text, len);
51 51
	buf[len] = 0;
52 52
53 -
	h = b->font->ascent + b->font->descent;
54 -
	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font->ascent;
53 +
	h = b->font.ascent + b->font.descent;
54 +
	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font.ascent;
55 55
	x = b->rect.x + (h / 2);
56 56
57 57
	/* shorten text if necessary */
58 -
	while(len && (w = textwidth_l(b->font, buf, len)) > b->rect.width - h)
58 +
	while(len && (w = textwidth_l(&b->font, buf, len)) > b->rect.width - h)
59 59
		buf[--len] = 0;
60 60
61 61
	if(w > b->rect.width)
62 62
		return; /* too long */
63 63
64 -
	gcv.foreground = b->color.fg;
65 -
	gcv.background = b->color.bg;
66 -
	if(b->font->set) {
64 +
	gcv.foreground = b->fg;
65 +
	gcv.background = b->bg;
66 +
	if(b->font.set) {
67 67
		XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv);
68 -
		XmbDrawImageString(dpy, b->drawable, b->font->set, b->gc,
68 +
		XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc,
69 69
				x, y, buf, len);
70 70
	}
71 71
	else {
72 -
		gcv.font = b->font->xfont->fid;
72 +
		gcv.font = b->font.xfont->fid;
73 73
		XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv);
74 74
		XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len);
75 75
	}
76 76
}
77 77
78 78
static unsigned long
79 -
xloadcolor(Display *dpy, Colormap cmap, const char *colstr)
79 +
xloadcolors(Display *dpy, Colormap cmap, const char *colstr)
80 80
{
81 81
	XColor color;
82 82
	XAllocNamedColor(dpy, cmap, colstr, &color, &color);
84 84
}
85 85
86 86
void
87 -
loadcolor(Display *dpy, int screen, Color *c,
87 +
loadcolors(Display *dpy, int screen, Brush *b,
88 88
		const char *bg, const char *fg, const char *border)
89 89
{
90 90
	Colormap cmap = DefaultColormap(dpy, screen);
91 -
	c->bg = xloadcolor(dpy, cmap, bg);
92 -
	c->fg = xloadcolor(dpy, cmap, fg);
93 -
	c->border = xloadcolor(dpy, cmap, border);
91 +
	b->bg = xloadcolors(dpy, cmap, bg);
92 +
	b->fg = xloadcolors(dpy, cmap, fg);
93 +
	b->border = xloadcolors(dpy, cmap, border);
94 94
}
95 95
96 96
unsigned int
160 160
		font->ascent = font->xfont->ascent;
161 161
		font->descent = font->xfont->descent;
162 162
	}
163 +
	font->height = font->ascent + font->descent;
163 164
}
draw.h +30 −1
3 3
 * See LICENSE file for license details.
4 4
 */
5 5
6 -
extern void error(char *errstr, ...);
6 +
#include <X11/Xlib.h>
7 +
#include <X11/Xlocale.h>
8 +
9 +
typedef struct Brush Brush;
10 +
typedef struct Fnt Fnt;
11 +
12 +
struct Fnt {
13 +
	XFontStruct *xfont;
14 +
	XFontSet set;
15 +
	int ascent;
16 +
	int descent;
17 +
	int height;
18 +
};
19 +
20 +
struct Brush {
21 +
	GC gc;
22 +
	Drawable drawable;
23 +
	XRectangle rect;
24 +
	Fnt font;
25 +
	unsigned long bg;
26 +
	unsigned long fg;
27 +
	unsigned long border;
28 +
};
29 +
30 +
extern void draw(Display *dpy, Brush *b, Bool border, const char *text);
31 +
extern void loadcolors(Display *dpy, int screen, Brush *b,
32 +
		const char *bg, const char *fg, const char *bo);
33 +
extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
34 +
extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
35 +
extern unsigned int textwidth(Fnt *font, char *text);
gridmenu.c +103 −136
4 4
 * See LICENSE file for license details.
5 5
 */
6 6
7 +
#include "config.h"
8 +
#include "draw.h"
9 +
#include "util.h"
10 +
7 11
#include <ctype.h>
8 12
#include <stdlib.h>
9 13
#include <stdio.h>
12 16
#include <sys/wait.h>
13 17
#include <time.h>
14 18
#include <unistd.h>
15 -
#include <X11/Xlib.h>
16 19
#include <X11/cursorfont.h>
17 20
#include <X11/Xutil.h>
18 21
#include <X11/keysym.h>
19 -
20 -
#include <blitz.h>
21 -
#include <cext.h>
22 22
23 23
typedef struct Item Item;
24 24
28 28
	char *text;
29 29
};
30 30
31 -
static char *title = nil;
31 +
static Display *dpy;
32 +
static Window root;
33 +
static Window win;
34 +
static XRectangle rect;
32 35
static Bool done = False;
33 -
static int ret = 0;
36 +
37 +
static Item *allitem = 0;	/* first of all items */
38 +
static Item *item = 0;	/* first of pattern matching items */
39 +
static Item *sel = 0;
40 +
static Item *nextoff = 0;
41 +
static Item *prevoff = 0;
42 +
static Item *curroff = 0;
43 +
44 +
static int screen;
45 +
static char *title = 0;
34 46
static char text[4096];
35 -
static BlitzColor selcolor;
36 -
static BlitzColor normcolor;
37 -
static Window win;
38 -
static XRectangle mrect;
39 -
static Item *allitem = nil;	/* first of all items */
40 -
static Item *item = nil;	/* first of pattern matching items */
41 -
static Item *sel = nil;
42 -
static Item *nextoff = nil;
43 -
static Item *prevoff = nil;
44 -
static Item *curroff = nil;
47 +
static int ret = 0;
45 48
static int nitem = 0;
46 49
static unsigned int cmdw = 0;
47 50
static unsigned int twidth = 0;
48 51
static unsigned int cwidth = 0;
49 -
static Blitz blz = {0};
50 -
static BlitzBrush brush = {0};
51 52
static const int seek = 30;		/* 30px */
52 53
54 +
static Brush brush = {0};
55 +
53 56
static void draw_menu(void);
54 -
static void handle_kpress(XKeyEvent * e);
57 +
static void kpress(XKeyEvent * e);
55 58
56 -
static char version[] = "wmiimenu - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n";
59 +
static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
57 60
58 61
static void
59 62
usage()
60 63
{
61 -
	fprintf(stderr, "%s", "usage: wmiimenu [-v] [-t <title>]\n");
64 +
	fprintf(stderr, "%s", "usage: gridmenu [-v] [-t <title>]\n");
62 65
	exit(1);
63 66
}
64 67
71 74
		return;
72 75
73 76
	for(nextoff = curroff; nextoff; nextoff=nextoff->right) {
74 -
		tw = blitz_textwidth(brush.font, nextoff->text);
75 -
		if(tw > mrect.width / 3)
76 -
			tw = mrect.width / 3;
77 -
		w += tw + mrect.height;
78 -
		if(w > mrect.width)
77 +
		tw = textwidth(&brush.font, nextoff->text);
78 +
		if(tw > rect.width / 3)
79 +
			tw = rect.width / 3;
80 +
		w += tw + brush.font.height;
81 +
		if(w > rect.width)
79 82
			break;
80 83
	}
81 84
82 85
	w = cmdw + 2 * seek;
83 86
	for(prevoff = curroff; prevoff && prevoff->left; prevoff=prevoff->left) {
84 -
		tw = blitz_textwidth(brush.font, prevoff->left->text);
85 -
		if(tw > mrect.width / 3)
86 -
			tw = mrect.width / 3;
87 -
		w += tw + mrect.height;
88 -
		if(w > mrect.width)
87 +
		tw = textwidth(&brush.font, prevoff->left->text);
88 +
		if(tw > rect.width / 3)
89 +
			tw = rect.width / 3;
90 +
		w += tw + brush.font.height;
91 +
		if(w > rect.width)
89 92
			break;
90 93
	}
91 94
}
104 107
	else
105 108
		cmdw = twidth;
106 109
107 -
	item = j = nil;
110 +
	item = j = 0;
108 111
	nitem = 0;
109 112
110 113
	for(i = allitem; i; i=i->next)
114 117
			else
115 118
				j->right = i;
116 119
			i->left = j;
117 -
			i->right = nil;
120 +
			i->right = 0;
118 121
			j = i;
119 122
			nitem++;
120 123
		}
126 129
			else
127 130
				j->right = i;
128 131
			i->left = j;
129 -
			i->right = nil;
132 +
			i->right = 0;
130 133
			j = i;
131 134
			nitem++;
132 135
		}
141 144
draw_menu()
142 145
{
143 146
	unsigned int offx = 0;
144 -
145 147
	Item *i;
146 148
147 -
	brush.align = WEST;
148 -
149 -
	brush.rect = mrect;
149 +
	brush.rect = rect;
150 150
	brush.rect.x = 0;
151 151
	brush.rect.y = 0;
152 -
	brush.color = normcolor;
153 -
	brush.border = False;
154 -
	blitz_draw_tile(&brush);
152 +
	draw(dpy, &brush, False, 0);
155 153
156 154
	/* print command */
157 155
	if(!title || text[0]) {
158 -
		brush.color = normcolor;
159 156
		cmdw = cwidth;
160 157
		if(cmdw && item)
161 158
			brush.rect.width = cmdw;
162 -
		blitz_draw_label(&brush, text);
159 +
		draw(dpy, &brush, False, text);
163 160
	}
164 161
	else {
165 162
		cmdw = twidth;
166 -
		brush.color = selcolor;
167 163
		brush.rect.width = cmdw;
168 -
		blitz_draw_label(&brush, title);
164 +
		draw(dpy, &brush, False, title);
169 165
	}
170 166
	offx += brush.rect.width;
171 167
172 -
	brush.align = CENTER;
173 168
	if(curroff) {
174 -
		brush.color = normcolor;
175 169
		brush.rect.x = offx;
176 170
		brush.rect.width = seek;
177 171
		offx += brush.rect.width;
178 -
		blitz_draw_label(&brush, (curroff && curroff->left) ? "<" : nil);
172 +
		draw(dpy, &brush, False, (curroff && curroff->left) ? "<" : 0);
179 173
180 174
		/* determine maximum items */
181 175
		for(i = curroff; i != nextoff; i=i->right) {
182 -
			brush.color = normcolor;
183 176
			brush.border = False;
184 177
			brush.rect.x = offx;
185 -
			brush.rect.width = blitz_textwidth(brush.font, i->text);
186 -
			if(brush.rect.width > mrect.width / 3)
187 -
				brush.rect.width = mrect.width / 3;
188 -
			brush.rect.width += mrect.height;
178 +
			brush.rect.width = textwidth(&brush.font, i->text);
179 +
			if(brush.rect.width > rect.width / 3)
180 +
				brush.rect.width = rect.width / 3;
181 +
			brush.rect.width += brush.font.height;
189 182
			if(sel == i) {
190 -
				brush.color = selcolor;
191 -
				brush.border = True;
183 +
				swap((void **)&brush.fg, (void **)&brush.bg);
184 +
				draw(dpy, &brush, True, i->text);
185 +
				swap((void **)&brush.fg, (void **)&brush.bg);
192 186
			}
193 -
			blitz_draw_label(&brush, i->text);
187 +
			else
188 +
				draw(dpy, &brush, False, i->text);
194 189
			offx += brush.rect.width;
195 190
		}
196 191
197 -
		brush.color = normcolor;
198 -
		brush.border = False;
199 -
		brush.rect.x = mrect.width - seek;
192 +
		brush.rect.x = rect.width - seek;
200 193
		brush.rect.width = seek;
201 -
		blitz_draw_label(&brush, nextoff ? ">" : nil);
194 +
		draw(dpy, &brush, False, nextoff ? ">" : 0);
202 195
	}
203 -
	XCopyArea(blz.dpy, brush.drawable, win, brush.gc, 0, 0, mrect.width,
204 -
			mrect.height, 0, 0);
205 -
	XSync(blz.dpy, False);
196 +
	XCopyArea(dpy, brush.drawable, win, brush.gc, 0, 0, rect.width,
197 +
			rect.height, 0, 0);
198 +
	XFlush(dpy);
206 199
}
207 200
208 201
static void
209 -
handle_kpress(XKeyEvent * e)
202 +
kpress(XKeyEvent * e)
210 203
{
211 204
	KeySym ksym;
212 205
	char buf[32];
272 265
	case XK_Tab:
273 266
		if(!sel)
274 267
			return;
275 -
		cext_strlcpy(text, sel->text, sizeof(text));
268 +
		strncpy(text, sel->text, sizeof(text));
276 269
		update_items(text);
277 270
		break;
278 271
	case XK_Right:
314 307
		if((num == 1) && !iscntrl((int) buf[0])) {
315 308
			buf[num] = 0;
316 309
			if(len > 0)
317 -
				cext_strlcat(text, buf, sizeof(text));
310 +
				strncat(text, buf, sizeof(text));
318 311
			else
319 -
				cext_strlcpy(text, buf, sizeof(text));
312 +
				strncpy(text, buf, sizeof(text));
320 313
			update_items(text);
321 314
		}
322 315
	}
326 319
static char *
327 320
read_allitems()
328 321
{
329 -
	static char *maxname = nil;
322 +
	static char *maxname = 0;
330 323
	char *p, buf[1024];
331 324
	unsigned int len = 0, max = 0;
332 325
	Item *i, *new;
333 326
334 -
	i = nil;
327 +
	i = 0;
335 328
	while(fgets(buf, sizeof(buf), stdin)) {
336 329
		len = strlen(buf);
337 330
		if (buf[len - 1] == '\n')
338 331
			buf[len - 1] = 0;
339 -
		p = cext_estrdup(buf);
332 +
		p = estrdup(buf);
340 333
		if(max < len) {
341 334
			maxname = p;
342 335
			max = len;
343 336
		}
344 337
345 -
		new = cext_emalloc(sizeof(Item));
346 -
		new->next = new->left = new->right = nil;
338 +
		new = emalloc(sizeof(Item));
339 +
		new->next = new->left = new->right = 0;
347 340
		new->text = p;
348 341
		if(!i)
349 342
			allitem = new;
360 353
{
361 354
	int i;
362 355
	XSetWindowAttributes wa;
363 -
	char *maxname, *p;
364 -
	BlitzFont font = {0};
365 -
	GC gc;
366 -
	Drawable pmap;
356 +
	char *maxname;
367 357
	XEvent ev;
368 358
369 359
	/* command line args */
388 378
			usage();
389 379
	}
390 380
391 -
	blz.dpy = XOpenDisplay(0);
392 -
	if(!blz.dpy) {
393 -
		fprintf(stderr, "%s", "wmiimenu: cannot open dpy\n");
394 -
		exit(1);
395 -
	}
396 -
	blz.screen = DefaultScreen(blz.dpy);
397 -
	blz.root = RootWindow(blz.dpy, blz.screen);
381 +
	dpy = XOpenDisplay(0);
382 +
	if(!dpy)
383 +
		error("gridmenu: cannot open dpy\n");
384 +
	screen = DefaultScreen(dpy);
385 +
	root = RootWindow(dpy, screen);
398 386
399 387
	maxname = read_allitems();
400 388
401 389
	/* grab as early as possible, but after reading all items!!! */
402 -
	while(XGrabKeyboard
403 -
			(blz.dpy, blz.root, True, GrabModeAsync,
390 +
	while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
404 391
			 GrabModeAsync, CurrentTime) != GrabSuccess)
405 392
		usleep(1000);
406 393
407 -
	font.fontstr = getenv("WMII_FONT");
408 -
	if (!font.fontstr)
409 -
		font.fontstr = cext_estrdup(BLITZ_FONT);
410 -
	blitz_loadfont(&blz, &font);
411 -
412 -
	if((p = getenv("WMII_NORMCOLORS")))
413 -
		cext_strlcpy(normcolor.colstr, p, sizeof(normcolor.colstr));
414 -
	if(strlen(normcolor.colstr) != 23)
415 -
		cext_strlcpy(normcolor.colstr, BLITZ_NORMCOLORS, sizeof(normcolor.colstr));
416 -
	blitz_loadcolor(&blz, &normcolor);
417 -
418 -
	if((p = getenv("WMII_SELCOLORS")))
419 -
		cext_strlcpy(selcolor.colstr, p, sizeof(selcolor.colstr));
420 -
	if(strlen(selcolor.colstr) != 23)
421 -
		cext_strlcpy(selcolor.colstr, BLITZ_SELCOLORS, sizeof(selcolor.colstr));
422 -
	blitz_loadcolor(&blz, &selcolor);
394 +
	/* style */
395 +
	loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
396 +
	loadfont(dpy, &brush.font, FONT);
423 397
424 398
	wa.override_redirect = 1;
425 399
	wa.background_pixmap = ParentRelative;
426 400
	wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask
427 401
		| SubstructureRedirectMask | SubstructureNotifyMask;
428 402
429 -
	mrect.width = DisplayWidth(blz.dpy, blz.screen);
430 -
	mrect.height = font.ascent + font.descent + 4;
431 -
	mrect.y = DisplayHeight(blz.dpy, blz.screen) - mrect.height;
432 -
	mrect.x = 0;
403 +
	rect.width = DisplayWidth(dpy, screen);
404 +
	rect.height = brush.font.height + 4;
405 +
	rect.y = DisplayHeight(dpy, screen) - rect.height;
406 +
	rect.x = 0;
433 407
434 -
	win = XCreateWindow(blz.dpy, blz.root, mrect.x, mrect.y,
435 -
			mrect.width, mrect.height, 0, DefaultDepth(blz.dpy, blz.screen),
436 -
			CopyFromParent, DefaultVisual(blz.dpy, blz.screen),
408 +
	win = XCreateWindow(dpy, root, rect.x, rect.y,
409 +
			rect.width, rect.height, 0, DefaultDepth(dpy, screen),
410 +
			CopyFromParent, DefaultVisual(dpy, screen),
437 411
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
438 -
	XDefineCursor(blz.dpy, win, XCreateFontCursor(blz.dpy, XC_xterm));
439 -
	XSync(blz.dpy, False);
412 +
	XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm));
413 +
	XFlush(dpy);
440 414
441 415
	/* pixmap */
442 -
	gc = XCreateGC(blz.dpy, win, 0, 0);
443 -
	pmap = XCreatePixmap(blz.dpy, win, mrect.width, mrect.height,
444 -
			DefaultDepth(blz.dpy, blz.screen));
445 -
446 -
	XSync(blz.dpy, False);
447 -
448 -
	brush.blitz = &blz;
449 -
	brush.color = normcolor;
450 -
	brush.drawable = pmap;
451 -
	brush.gc = gc;
452 -
	brush.font = &font;
416 +
	brush.gc = XCreateGC(dpy, win, 0, 0);
417 +
	brush.drawable = XCreatePixmap(dpy, win, rect.width, rect.height,
418 +
			DefaultDepth(dpy, screen));
419 +
	XFlush(dpy);
453 420
454 421
	if(maxname)
455 -
		cwidth = blitz_textwidth(brush.font, maxname) + mrect.height;
456 -
	if(cwidth > mrect.width / 3)
457 -
		cwidth = mrect.width / 3;
422 +
		cwidth = textwidth(&brush.font, maxname) + brush.font.height;
423 +
	if(cwidth > rect.width / 3)
424 +
		cwidth = rect.width / 3;
458 425
459 426
	if(title) {
460 -
		twidth = blitz_textwidth(brush.font, title) + mrect.height;
461 -
		if(twidth > mrect.width / 3)
462 -
			twidth = mrect.width / 3;
427 +
		twidth = textwidth(&brush.font, title) + brush.font.height;
428 +
		if(twidth > rect.width / 3)
429 +
			twidth = rect.width / 3;
463 430
	}
464 431
465 432
	cmdw = title ? twidth : cwidth;
466 433
467 434
	text[0] = 0;
468 435
	update_items(text);
469 -
	XMapRaised(blz.dpy, win);
436 +
	XMapRaised(dpy, win);
470 437
	draw_menu();
471 -
	XSync(blz.dpy, False);
438 +
	XFlush(dpy);
472 439
473 440
	/* main event loop */
474 -
	while(!XNextEvent(blz.dpy, &ev)) {
441 +
	while(!XNextEvent(dpy, &ev)) {
475 442
		switch (ev.type) {
476 443
			case KeyPress:
477 -
				handle_kpress(&ev.xkey);
444 +
				kpress(&ev.xkey);
478 445
				break;
479 446
			case Expose:
480 447
				if(ev.xexpose.count == 0) {
488 455
			break;
489 456
	}
490 457
491 -
	XUngrabKeyboard(blz.dpy, CurrentTime);
492 -
	XFreePixmap(blz.dpy, pmap);
493 -
	XFreeGC(blz.dpy, gc);
494 -
	XDestroyWindow(blz.dpy, win);
495 -
	XCloseDisplay(blz.dpy);
458 +
	XUngrabKeyboard(dpy, CurrentTime);
459 +
	XFreePixmap(dpy, brush.drawable);
460 +
	XFreeGC(dpy, brush.gc);
461 +
	XDestroyWindow(dpy, win);
462 +
	XCloseDisplay(dpy);
496 463
497 464
	return ret;
498 465
}
util.c +59 −0
6 6
#include <stdarg.h>
7 7
#include <stdio.h>
8 8
#include <stdlib.h>
9 +
#include <string.h>
9 10
10 11
void
11 12
error(char *errstr, ...) {
16 17
	exit(1);
17 18
}
18 19
20 +
static void
21 +
bad_malloc(unsigned int size)
22 +
{
23 +
	fprintf(stderr, "fatal: could not malloc() %d bytes\n",
24 +
			(int) size);
25 +
	exit(1);
26 +
}
27 +
28 +
void *
29 +
emallocz(unsigned int size)
30 +
{
31 +
	void *res = calloc(1, size);
32 +
	if(!res)
33 +
		bad_malloc(size);
34 +
	return res;
35 +
}
36 +
37 +
void *
38 +
emalloc(unsigned int size)
39 +
{
40 +
	void *res = malloc(size);
41 +
	if(!res)
42 +
		bad_malloc(size);
43 +
	return res;
44 +
}
45 +
46 +
void *
47 +
erealloc(void *ptr, unsigned int size)
48 +
{
49 +
	void *res = realloc(ptr, size);
50 +
	if(!res)
51 +
		bad_malloc(size);
52 +
	return res;
53 +
}
54 +
55 +
char *
56 +
estrdup(const char *str)
57 +
{
58 +
	void *res = strdup(str);
59 +
	if(!res)
60 +
		bad_malloc(strlen(str));
61 +
	return res;
62 +
}
63 +
64 +
void
65 +
failed_assert(char *a, char *file, int line)
66 +
{
67 +
	fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line);
68 +
	abort();
69 +
}
70 +
71 +
void
72 +
swap(void **p1, void **p2)
73 +
{
74 +
	void *tmp = *p1;
75 +
	*p1 = *p2;
76 +
	*p2 = tmp;
77 +
}
util.h +11 −36
3 3
 * See LICENSE file for license details.
4 4
 */
5 5
6 -
#include <X11/Xlib.h>
7 -
#include <X11/Xlocale.h>
8 -
9 -
typedef struct Brush Brush;
10 -
typedef struct Color Color;
11 -
typedef struct Fnt Fnt;
12 -
13 -
struct Color {
14 -
	unsigned long bg;
15 -
	unsigned long fg;
16 -
	unsigned long border;
17 -
};
18 -
19 -
struct Fnt {
20 -
	XFontStruct *xfont;
21 -
	XFontSet set;
22 -
	int ascent;
23 -
	int descent;
24 -
};
25 -
26 -
struct Brush {
27 -
	GC gc;
28 -
	Drawable drawable;
29 -
	XRectangle rect;
30 -
	Bool border;
31 -
	Fnt *font;
32 -
	Color color;
33 -
	const char *text;
34 -
};
35 -
36 -
extern void draw(Display *dpy, Brush *b);
37 -
extern void loadcolor(Display *dpy, int screen, Color *c,
38 -
		const char *bg, const char *fg, const char *bo);
39 -
extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
40 -
extern unsigned int textwidth(Fnt *font, char *text);
41 -
extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
6 +
extern void error(char *errstr, ...);
7 +
extern void *emallocz(unsigned int size);
8 +
extern void *emalloc(unsigned int size);
9 +
extern void *erealloc(void *ptr, unsigned int size);
10 +
extern char *estrdup(const char *str);
11 +
#define eassert(a) do { \
12 +
		if(!(a)) \
13 +
			failed_assert(#a, __FILE__, __LINE__); \
14 +
	} while (0)
15 +
void failed_assert(char *a, char *file, int line);
16 +
void swap(void **p1, void **p2);
wm.c +12 −3
13 13
14 14
#include "wm.h"
15 15
16 +
/* X structs */
16 17
Display *dpy;
17 18
Window root;
18 19
XRectangle rect;
19 -
int screen, sel_screen;
20 +
Pixmap pmap;
20 21
Atom wm_atom[WMLast];
21 22
Atom net_atom[NetLast];
22 23
Cursor cursor[CurLast];
24 +
25 +
int screen, sel_screen;
23 26
unsigned int kmask, numlock_mask;
24 -
Pixmap pmap;
27 +
28 +
/* draw structs */
29 +
Brush brush = {0};
25 30
26 31
enum { WM_PROTOCOL_DELWIN = 1 };
27 32
208 213
	XSetErrorHandler(startup_error_handler);
209 214
	/* this causes an error if some other WM is running */
210 215
	XSelectInput(dpy, root, SubstructureRedirectMask);
211 -
	XSync(dpy, False);
216 +
	XFlush(dpy);
212 217
213 218
	if(other_wm_running)
214 219
		error("gridwm: another window manager is already running\n");
245 250
	wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
246 251
	wa.cursor = cursor[CurNormal];
247 252
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
253 +
254 +
	/* style */
255 +
	loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
256 +
	loadfont(dpy, &brush.font, FONT);
248 257
249 258
	scan_wins();
250 259
wm.h +6 −2
3 3
 * See LICENSE file for license details.
4 4
 */
5 5
6 +
#include "config.h"
6 7
#include "draw.h"
7 8
#include "util.h"
8 9
48 49
extern Display *dpy;
49 50
extern Window root;
50 51
extern XRectangle rect;
51 -
extern int screen, sel_screen;
52 -
extern unsigned int kmask, numlock_mask;
53 52
extern Atom wm_atom[WMLast];
54 53
extern Atom net_atom[NetLast];
55 54
extern Cursor cursor[CurLast];
56 55
extern Pixmap pmap;
56 +
57 +
extern int screen, sel_screen;
58 +
extern unsigned int kmask, numlock_mask;
59 +
60 +
extern Brush brush;
57 61
58 62
/* wm.c */