about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAnselm R. Garbe <garbeam@wmii.de>2006-07-10 19:46:24 +0200
committerAnselm R. Garbe <garbeam@wmii.de>2006-07-10 19:46:24 +0200
commit39677ec76616fe4165ef92afb14db2bef2488e30 (patch)
tree7ea1c021042b7d7da53660aa127af37847273a91
parent8a34fa50f75f4d6d8af234ac0c4f6d40b988d700 (diff)
downloaddwm-39677ec76616fe4165ef92afb14db2bef2488e30.tar.gz
several new changes, made gridmenu working
-rw-r--r--Makefile14
-rw-r--r--config.h8
-rw-r--r--draw.c41
-rw-r--r--draw.h31
-rw-r--r--gridmenu.c239
-rw-r--r--util.c59
-rw-r--r--util.h47
-rw-r--r--wm.c15
-rw-r--r--wm.h8
9 files changed, 256 insertions, 206 deletions
diff --git a/Makefile b/Makefile
index 1eb6c50..152f276 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,12 @@ include config.mk
 
 WMSRC = wm.c draw.c util.c
 WMOBJ = ${WMSRC:.c=.o}
+MENSRC = gridmenu.c draw.c util.c
+MENOBJ = ${MENSRC:.c=.o}
 MAN = gridwm.1
 BIN = gridwm gridmenu     
 
-all: config gridwm
+all: config gridwm gridmenu
 	@echo finished
 
 config:
@@ -22,18 +24,22 @@ config:
 	@echo CC $<
 	@${CC} -c ${CFLAGS} $<
 
-${WMOBJ}: wm.h draw.h config.h
+${WMOBJ}: wm.h draw.h config.h util.h
+
+gridmenu: ${MENOBJ}
+	@echo LD $@
+	@${CC} -o $@ ${MENOBJ} ${LDFLAGS}
 
 gridwm: ${WMOBJ}
 	@echo LD $@
 	@${CC} -o $@ ${WMOBJ} ${LDFLAGS}
 
 clean:
-	rm -f gridwm *.o
+	rm -f gridwm gridmenu *.o core
 
 dist: clean
 	mkdir -p gridwm-${VERSION}
-	cp -R Makefile README LICENSE config.mk ${WMSRC} ${MAN} gridwm-${VERSION}
+	cp -R Makefile README LICENSE config.mk *.h *.c ${MAN} gridwm-${VERSION}
 	tar -cf gridwm-${VERSION}.tar gridwm-${VERSION}
 	gzip gridwm-${VERSION}.tar
 	rm -rf gridwm-${VERSION}
diff --git a/config.h b/config.h
index 036a41b..6a768b6 100644
--- a/config.h
+++ b/config.h
@@ -3,7 +3,7 @@
  * See LICENSE file for license details.
  */
 
-#define FONT	"fixed"
-#define FGCOLOR	"#000000"
-#define BGCOLOR	"#ffaa00"
-#define BOCOLOR	"#000000"
+#define FONT		"-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*"
+#define FGCOLOR		"#000000"
+#define BGCOLOR		"#ffaa00"
+#define BORDERCOLOR	"#000000"
diff --git a/draw.c b/draw.c
index 85ff41b..cf7f14e 100644
--- a/draw.c
+++ b/draw.c
@@ -14,7 +14,7 @@ drawborder(Display *dpy, Brush *b)
 {
 	XPoint points[5];
 	XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter);
-	XSetForeground(dpy, b->gc, b->color.border);
+	XSetForeground(dpy, b->gc, b->border);
 	points[0].x = b->rect.x;
 	points[0].y = b->rect.y;
 	points[1].x = b->rect.width - 1;
@@ -29,54 +29,54 @@ drawborder(Display *dpy, Brush *b)
 }
 
 void
-draw(Display *dpy, Brush *b)
+draw(Display *dpy, Brush *b, Bool border, const char *text)
 {
 	unsigned int x, y, w, h, len;
 	static char buf[256];
 	XGCValues gcv;
 
-	XSetForeground(dpy, b->gc, b->color.bg);
+	XSetForeground(dpy, b->gc, b->bg);
 	XFillRectangles(dpy, b->drawable, b->gc, &b->rect, 1);
 
-	if(b->border)
+	if(border)
 		drawborder(dpy, b);
 
-	if(!b->text)
+	if(!text)
 		return;
 
-	len = strlen(b->text);
+	len = strlen(text);
 	if(len >= sizeof(buf))
 		len = sizeof(buf) - 1;
-	memcpy(buf, b->text, len);
+	memcpy(buf, text, len);
 	buf[len] = 0;
 
-	h = b->font->ascent + b->font->descent;
-	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font->ascent;
+	h = b->font.ascent + b->font.descent;
+	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font.ascent;
 	x = b->rect.x + (h / 2);
 
 	/* shorten text if necessary */
-	while(len && (w = textwidth_l(b->font, buf, len)) > b->rect.width - h)
+	while(len && (w = textwidth_l(&b->font, buf, len)) > b->rect.width - h)
 		buf[--len] = 0;
 
 	if(w > b->rect.width)
 		return; /* too long */
 
-	gcv.foreground = b->color.fg;
-	gcv.background = b->color.bg;
-	if(b->font->set) {
+	gcv.foreground = b->fg;
+	gcv.background = b->bg;
+	if(b->font.set) {
 		XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv);
-		XmbDrawImageString(dpy, b->drawable, b->font->set, b->gc,
+		XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc,
 				x, y, buf, len);
 	}
 	else {
-		gcv.font = b->font->xfont->fid;
+		gcv.font = b->font.xfont->fid;
 		XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv);
 		XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len);
 	}
 }
 
 static unsigned long
-xloadcolor(Display *dpy, Colormap cmap, const char *colstr)
+xloadcolors(Display *dpy, Colormap cmap, const char *colstr)
 {
 	XColor color;
 	XAllocNamedColor(dpy, cmap, colstr, &color, &color);
@@ -84,13 +84,13 @@ xloadcolor(Display *dpy, Colormap cmap, const char *colstr)
 }
 
 void
-loadcolor(Display *dpy, int screen, Color *c,
+loadcolors(Display *dpy, int screen, Brush *b,
 		const char *bg, const char *fg, const char *border)
 {
 	Colormap cmap = DefaultColormap(dpy, screen);
-	c->bg = xloadcolor(dpy, cmap, bg);
-	c->fg = xloadcolor(dpy, cmap, fg);
-	c->border = xloadcolor(dpy, cmap, border);
+	b->bg = xloadcolors(dpy, cmap, bg);
+	b->fg = xloadcolors(dpy, cmap, fg);
+	b->border = xloadcolors(dpy, cmap, border);
 }
 
 unsigned int
@@ -160,4 +160,5 @@ loadfont(Display *dpy, Fnt *font, const char *fontstr)
 		font->ascent = font->xfont->ascent;
 		font->descent = font->xfont->descent;
 	}
+	font->height = font->ascent + font->descent;
 }
diff --git a/draw.h b/draw.h
index d3f9872..710087f 100644
--- a/draw.h
+++ b/draw.h
@@ -3,4 +3,33 @@
  * See LICENSE file for license details.
  */
 
-extern void error(char *errstr, ...);
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+
+typedef struct Brush Brush;
+typedef struct Fnt Fnt;
+
+struct Fnt {
+	XFontStruct *xfont;
+	XFontSet set;
+	int ascent;
+	int descent;
+	int height;
+};
+
+struct Brush {
+	GC gc;
+	Drawable drawable;
+	XRectangle rect;
+	Fnt font;
+	unsigned long bg;
+	unsigned long fg;
+	unsigned long border;
+};
+
+extern void draw(Display *dpy, Brush *b, Bool border, const char *text);
+extern void loadcolors(Display *dpy, int screen, Brush *b,
+		const char *bg, const char *fg, const char *bo);
+extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
+extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
+extern unsigned int textwidth(Fnt *font, char *text);
diff --git a/gridmenu.c b/gridmenu.c
index 962fa22..b4e08d4 100644
--- a/gridmenu.c
+++ b/gridmenu.c
@@ -4,6 +4,10 @@
  * See LICENSE file for license details.
  */
 
+#include "config.h"
+#include "draw.h"
+#include "util.h"
+
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -12,14 +16,10 @@
 #include <sys/wait.h>
 #include <time.h>
 #include <unistd.h>
-#include <X11/Xlib.h>
 #include <X11/cursorfont.h>
 #include <X11/Xutil.h>
 #include <X11/keysym.h>
 
-#include <blitz.h>
-#include <cext.h>
-
 typedef struct Item Item;
 
 struct Item {
@@ -28,37 +28,40 @@ struct Item {
 	char *text;
 };
 
-static char *title = nil;
+static Display *dpy;
+static Window root;
+static Window win;
+static XRectangle rect;
 static Bool done = False;
-static int ret = 0;
+
+static Item *allitem = 0;	/* first of all items */
+static Item *item = 0;	/* first of pattern matching items */
+static Item *sel = 0;
+static Item *nextoff = 0;
+static Item *prevoff = 0;
+static Item *curroff = 0;
+
+static int screen;
+static char *title = 0;
 static char text[4096];
-static BlitzColor selcolor;
-static BlitzColor normcolor;
-static Window win;
-static XRectangle mrect;
-static Item *allitem = nil;	/* first of all items */
-static Item *item = nil;	/* first of pattern matching items */
-static Item *sel = nil;
-static Item *nextoff = nil;
-static Item *prevoff = nil;
-static Item *curroff = nil;
+static int ret = 0;
 static int nitem = 0;
 static unsigned int cmdw = 0;
 static unsigned int twidth = 0;
 static unsigned int cwidth = 0;
-static Blitz blz = {0};
-static BlitzBrush brush = {0};
 static const int seek = 30;		/* 30px */
 
+static Brush brush = {0};
+
 static void draw_menu(void);
-static void handle_kpress(XKeyEvent * e);
+static void kpress(XKeyEvent * e);
 
-static char version[] = "wmiimenu - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n";
+static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
 
 static void
 usage()
 {
-	fprintf(stderr, "%s", "usage: wmiimenu [-v] [-t <title>]\n");
+	fprintf(stderr, "%s", "usage: gridmenu [-v] [-t <title>]\n");
 	exit(1);
 }
 
@@ -71,21 +74,21 @@ update_offsets()
 		return;
 
 	for(nextoff = curroff; nextoff; nextoff=nextoff->right) {
-		tw = blitz_textwidth(brush.font, nextoff->text);
-		if(tw > mrect.width / 3)
-			tw = mrect.width / 3;
-		w += tw + mrect.height;
-		if(w > mrect.width)
+		tw = textwidth(&brush.font, nextoff->text);
+		if(tw > rect.width / 3)
+			tw = rect.width / 3;
+		w += tw + brush.font.height;
+		if(w > rect.width)
 			break;
 	}
 
 	w = cmdw + 2 * seek;
 	for(prevoff = curroff; prevoff && prevoff->left; prevoff=prevoff->left) {
-		tw = blitz_textwidth(brush.font, prevoff->left->text);
-		if(tw > mrect.width / 3)
-			tw = mrect.width / 3;
-		w += tw + mrect.height;
-		if(w > mrect.width)
+		tw = textwidth(&brush.font, prevoff->left->text);
+		if(tw > rect.width / 3)
+			tw = rect.width / 3;
+		w += tw + brush.font.height;
+		if(w > rect.width)
 			break;
 	}
 }
@@ -104,7 +107,7 @@ update_items(char *pattern)
 	else
 		cmdw = twidth;
 
-	item = j = nil;
+	item = j = 0;
 	nitem = 0;
 
 	for(i = allitem; i; i=i->next)
@@ -114,7 +117,7 @@ update_items(char *pattern)
 			else
 				j->right = i;
 			i->left = j;
-			i->right = nil;
+			i->right = 0;
 			j = i;
 			nitem++;
 		}
@@ -126,7 +129,7 @@ update_items(char *pattern)
 			else
 				j->right = i;
 			i->left = j;
-			i->right = nil;
+			i->right = 0;
 			j = i;
 			nitem++;
 		}
@@ -141,72 +144,62 @@ static void
 draw_menu()
 {
 	unsigned int offx = 0;
-
 	Item *i;
 
-	brush.align = WEST;
-
-	brush.rect = mrect;
+	brush.rect = rect;
 	brush.rect.x = 0;
 	brush.rect.y = 0;
-	brush.color = normcolor;
-	brush.border = False;
-	blitz_draw_tile(&brush);
+	draw(dpy, &brush, False, 0);
 
 	/* print command */
 	if(!title || text[0]) {
-		brush.color = normcolor;
 		cmdw = cwidth;
 		if(cmdw && item)
 			brush.rect.width = cmdw;
-		blitz_draw_label(&brush, text);
+		draw(dpy, &brush, False, text);
 	}
 	else {
 		cmdw = twidth;
-		brush.color = selcolor;
 		brush.rect.width = cmdw;
-		blitz_draw_label(&brush, title);
+		draw(dpy, &brush, False, title);
 	}
 	offx += brush.rect.width;
 
-	brush.align = CENTER;
 	if(curroff) {
-		brush.color = normcolor;
 		brush.rect.x = offx;
 		brush.rect.width = seek;
 		offx += brush.rect.width;
-		blitz_draw_label(&brush, (curroff && curroff->left) ? "<" : nil);
+		draw(dpy, &brush, False, (curroff && curroff->left) ? "<" : 0);
 
 		/* determine maximum items */
 		for(i = curroff; i != nextoff; i=i->right) {
-			brush.color = normcolor;
 			brush.border = False;
 			brush.rect.x = offx;
-			brush.rect.width = blitz_textwidth(brush.font, i->text);
-			if(brush.rect.width > mrect.width / 3)
-				brush.rect.width = mrect.width / 3;
-			brush.rect.width += mrect.height;
+			brush.rect.width = textwidth(&brush.font, i->text);
+			if(brush.rect.width > rect.width / 3)
+				brush.rect.width = rect.width / 3;
+			brush.rect.width += brush.font.height;
 			if(sel == i) {
-				brush.color = selcolor;
-				brush.border = True;
+				swap((void **)&brush.fg, (void **)&brush.bg);
+				draw(dpy, &brush, True, i->text);
+				swap((void **)&brush.fg, (void **)&brush.bg);
 			}
-			blitz_draw_label(&brush, i->text);
+			else
+				draw(dpy, &brush, False, i->text);
 			offx += brush.rect.width;
 		}
 
-		brush.color = normcolor;
-		brush.border = False;
-		brush.rect.x = mrect.width - seek;
+		brush.rect.x = rect.width - seek;
 		brush.rect.width = seek;
-		blitz_draw_label(&brush, nextoff ? ">" : nil);
+		draw(dpy, &brush, False, nextoff ? ">" : 0);
 	}
-	XCopyArea(blz.dpy, brush.drawable, win, brush.gc, 0, 0, mrect.width,
-			mrect.height, 0, 0);
-	XSync(blz.dpy, False);
+	XCopyArea(dpy, brush.drawable, win, brush.gc, 0, 0, rect.width,
+			rect.height, 0, 0);
+	XFlush(dpy);
 }
 
 static void
-handle_kpress(XKeyEvent * e)
+kpress(XKeyEvent * e)
 {
 	KeySym ksym;
 	char buf[32];
@@ -272,7 +265,7 @@ handle_kpress(XKeyEvent * e)
 	case XK_Tab:
 		if(!sel)
 			return;
-		cext_strlcpy(text, sel->text, sizeof(text));
+		strncpy(text, sel->text, sizeof(text));
 		update_items(text);
 		break;
 	case XK_Right:
@@ -314,9 +307,9 @@ handle_kpress(XKeyEvent * e)
 		if((num == 1) && !iscntrl((int) buf[0])) {
 			buf[num] = 0;
 			if(len > 0)
-				cext_strlcat(text, buf, sizeof(text));
+				strncat(text, buf, sizeof(text));
 			else
-				cext_strlcpy(text, buf, sizeof(text));
+				strncpy(text, buf, sizeof(text));
 			update_items(text);
 		}
 	}
@@ -326,24 +319,24 @@ handle_kpress(XKeyEvent * e)
 static char *
 read_allitems()
 {
-	static char *maxname = nil;
+	static char *maxname = 0;
 	char *p, buf[1024];
 	unsigned int len = 0, max = 0;
 	Item *i, *new;
 
-	i = nil;
+	i = 0;
 	while(fgets(buf, sizeof(buf), stdin)) {
 		len = strlen(buf);
 		if (buf[len - 1] == '\n')
 			buf[len - 1] = 0;
-		p = cext_estrdup(buf);
+		p = estrdup(buf);
 		if(max < len) {
 			maxname = p;
 			max = len;
 		}
 
-		new = cext_emalloc(sizeof(Item));
-		new->next = new->left = new->right = nil;
+		new = emalloc(sizeof(Item));
+		new->next = new->left = new->right = 0;
 		new->text = p;
 		if(!i)
 			allitem = new;
@@ -360,10 +353,7 @@ main(int argc, char *argv[])
 {
 	int i;
 	XSetWindowAttributes wa;
-	char *maxname, *p;
-	BlitzFont font = {0};
-	GC gc;
-	Drawable pmap;
+	char *maxname;
 	XEvent ev;
 
 	/* command line args */
@@ -388,93 +378,70 @@ main(int argc, char *argv[])
 			usage();
 	}
 
-	blz.dpy = XOpenDisplay(0);
-	if(!blz.dpy) {
-		fprintf(stderr, "%s", "wmiimenu: cannot open dpy\n");
-		exit(1);
-	}
-	blz.screen = DefaultScreen(blz.dpy);
-	blz.root = RootWindow(blz.dpy, blz.screen);
+	dpy = XOpenDisplay(0);
+	if(!dpy)
+		error("gridmenu: cannot open dpy\n");
+	screen = DefaultScreen(dpy);
+	root = RootWindow(dpy, screen);
 
 	maxname = read_allitems();
 
 	/* grab as early as possible, but after reading all items!!! */
-	while(XGrabKeyboard
-			(blz.dpy, blz.root, True, GrabModeAsync,
+	while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
 			 GrabModeAsync, CurrentTime) != GrabSuccess)
 		usleep(1000);
 
-	font.fontstr = getenv("WMII_FONT");
-	if (!font.fontstr)
-		font.fontstr = cext_estrdup(BLITZ_FONT);
-	blitz_loadfont(&blz, &font);
-
-	if((p = getenv("WMII_NORMCOLORS")))
-		cext_strlcpy(normcolor.colstr, p, sizeof(normcolor.colstr));
-	if(strlen(normcolor.colstr) != 23)
-		cext_strlcpy(normcolor.colstr, BLITZ_NORMCOLORS, sizeof(normcolor.colstr));
-	blitz_loadcolor(&blz, &normcolor);
-
-	if((p = getenv("WMII_SELCOLORS")))
-		cext_strlcpy(selcolor.colstr, p, sizeof(selcolor.colstr));
-	if(strlen(selcolor.colstr) != 23)
-		cext_strlcpy(selcolor.colstr, BLITZ_SELCOLORS, sizeof(selcolor.colstr));
-	blitz_loadcolor(&blz, &selcolor);
+	/* style */
+	loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
+	loadfont(dpy, &brush.font, FONT);
 
 	wa.override_redirect = 1;
 	wa.background_pixmap = ParentRelative;
 	wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask
 		| SubstructureRedirectMask | SubstructureNotifyMask;
 
-	mrect.width = DisplayWidth(blz.dpy, blz.screen);
-	mrect.height = font.ascent + font.descent + 4;
-	mrect.y = DisplayHeight(blz.dpy, blz.screen) - mrect.height;
-	mrect.x = 0;
+	rect.width = DisplayWidth(dpy, screen);
+	rect.height = brush.font.height + 4;
+	rect.y = DisplayHeight(dpy, screen) - rect.height;
+	rect.x = 0;
 
-	win = XCreateWindow(blz.dpy, blz.root, mrect.x, mrect.y,
-			mrect.width, mrect.height, 0, DefaultDepth(blz.dpy, blz.screen),
-			CopyFromParent, DefaultVisual(blz.dpy, blz.screen),
+	win = XCreateWindow(dpy, root, rect.x, rect.y,
+			rect.width, rect.height, 0, DefaultDepth(dpy, screen),
+			CopyFromParent, DefaultVisual(dpy, screen),
 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
-	XDefineCursor(blz.dpy, win, XCreateFontCursor(blz.dpy, XC_xterm));
-	XSync(blz.dpy, False);
+	XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm));
+	XFlush(dpy);
 
 	/* pixmap */
-	gc = XCreateGC(blz.dpy, win, 0, 0);
-	pmap = XCreatePixmap(blz.dpy, win, mrect.width, mrect.height,
-			DefaultDepth(blz.dpy, blz.screen));
-
-	XSync(blz.dpy, False);
-
-	brush.blitz = &blz;
-	brush.color = normcolor;
-	brush.drawable = pmap;
-	brush.gc = gc;
-	brush.font = &font;
+	brush.gc = XCreateGC(dpy, win, 0, 0);
+	brush.drawable = XCreatePixmap(dpy, win, rect.width, rect.height,
+			DefaultDepth(dpy, screen));
+	XFlush(dpy);
 
 	if(maxname)
-		cwidth = blitz_textwidth(brush.font, maxname) + mrect.height;
-	if(cwidth > mrect.width / 3)
-		cwidth = mrect.width / 3;
+		cwidth = textwidth(&brush.font, maxname) + brush.font.height;
+	if(cwidth > rect.width / 3)
+		cwidth = rect.width / 3;
 
 	if(title) {
-		twidth = blitz_textwidth(brush.font, title) + mrect.height;
-		if(twidth > mrect.width / 3)
-			twidth = mrect.width / 3;
+		twidth = textwidth(&brush.font, title) + brush.font.height;
+		if(twidth > rect.width / 3)
+			twidth = rect.width / 3;
 	}
 
 	cmdw = title ? twidth : cwidth;
 
 	text[0] = 0;
 	update_items(text);
-	XMapRaised(blz.dpy, win);
+	XMapRaised(dpy, win);
 	draw_menu();
-	XSync(blz.dpy, False);
+	XFlush(dpy);
 
 	/* main event loop */
-	while(!XNextEvent(blz.dpy, &ev)) {
+	while(!XNextEvent(dpy, &ev)) {
 		switch (ev.type) {
 			case KeyPress:
-				handle_kpress(&ev.xkey);
+				kpress(&ev.xkey);
 				break;
 			case Expose:
 				if(ev.xexpose.count == 0) {
@@ -488,11 +455,11 @@ main(int argc, char *argv[])
 			break;
 	}
 
-	XUngrabKeyboard(blz.dpy, CurrentTime);
-	XFreePixmap(blz.dpy, pmap);
-	XFreeGC(blz.dpy, gc);
-	XDestroyWindow(blz.dpy, win);
-	XCloseDisplay(blz.dpy);
+	XUngrabKeyboard(dpy, CurrentTime);
+	XFreePixmap(dpy, brush.drawable);
+	XFreeGC(dpy, brush.gc);
+	XDestroyWindow(dpy, win);
+	XCloseDisplay(dpy);
 
 	return ret;
 }
diff --git a/util.c b/util.c
index 3553f5d..99842e9 100644
--- a/util.c
+++ b/util.c
@@ -6,6 +6,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 void
 error(char *errstr, ...) {
@@ -16,3 +17,61 @@ error(char *errstr, ...) {
 	exit(1);
 }
 
+static void
+bad_malloc(unsigned int size)
+{
+	fprintf(stderr, "fatal: could not malloc() %d bytes\n",
+			(int) size);
+	exit(1);
+}
+
+void *
+emallocz(unsigned int size)
+{
+	void *res = calloc(1, size);
+	if(!res)
+		bad_malloc(size);
+	return res;
+}
+
+void *
+emalloc(unsigned int size)
+{
+	void *res = malloc(size);
+	if(!res)
+		bad_malloc(size);
+	return res;
+}
+
+void *
+erealloc(void *ptr, unsigned int size)
+{
+	void *res = realloc(ptr, size);
+	if(!res)
+		bad_malloc(size);
+	return res;
+}
+
+char *
+estrdup(const char *str)
+{
+	void *res = strdup(str);
+	if(!res)
+		bad_malloc(strlen(str));
+	return res;
+}
+
+void
+failed_assert(char *a, char *file, int line)
+{
+	fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line);
+	abort();
+}
+
+void
+swap(void **p1, void **p2)
+{
+	void *tmp = *p1;
+	*p1 = *p2;
+	*p2 = tmp;
+}
diff --git a/util.h b/util.h
index be296e8..8ba444b 100644
--- a/util.h
+++ b/util.h
@@ -3,39 +3,14 @@
  * See LICENSE file for license details.
  */
 
-#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
-
-typedef struct Brush Brush;
-typedef struct Color Color;
-typedef struct Fnt Fnt;
-
-struct Color {
-	unsigned long bg;
-	unsigned long fg;
-	unsigned long border;
-};
-
-struct Fnt {
-	XFontStruct *xfont;
-	XFontSet set;
-	int ascent;
-	int descent;
-};
-
-struct Brush {
-	GC gc;
-	Drawable drawable;
-	XRectangle rect;
-	Bool border;
-	Fnt *font;
-	Color color;
-	const char *text;
-};
-
-extern void draw(Display *dpy, Brush *b);
-extern void loadcolor(Display *dpy, int screen, Color *c,
-		const char *bg, const char *fg, const char *bo);
-extern unsigned int textwidth_l(Fnt *font, char *text, unsigned int len);
-extern unsigned int textwidth(Fnt *font, char *text);
-extern void loadfont(Display *dpy, Fnt *font, const char *fontstr);
+extern void error(char *errstr, ...);
+extern void *emallocz(unsigned int size);
+extern void *emalloc(unsigned int size);
+extern void *erealloc(void *ptr, unsigned int size);
+extern char *estrdup(const char *str);
+#define eassert(a) do { \
+		if(!(a)) \
+			failed_assert(#a, __FILE__, __LINE__); \
+	} while (0)
+void failed_assert(char *a, char *file, int line);
+void swap(void **p1, void **p2);
diff --git a/wm.c b/wm.c
index 4c4a513..c8bb0a4 100644
--- a/wm.c
+++ b/wm.c
@@ -13,15 +13,20 @@
 
 #include "wm.h"
 
+/* X structs */
 Display *dpy;
 Window root;
 XRectangle rect;
-int screen, sel_screen;
+Pixmap pmap;
 Atom wm_atom[WMLast];
 Atom net_atom[NetLast];
 Cursor cursor[CurLast];
+
+int screen, sel_screen;
 unsigned int kmask, numlock_mask;
-Pixmap pmap;
+
+/* draw structs */
+Brush brush = {0};
 
 enum { WM_PROTOCOL_DELWIN = 1 };
 
@@ -208,7 +213,7 @@ main(int argc, char *argv[])
 	XSetErrorHandler(startup_error_handler);
 	/* this causes an error if some other WM is running */
 	XSelectInput(dpy, root, SubstructureRedirectMask);
-	XSync(dpy, False);
+	XFlush(dpy);
 
 	if(other_wm_running)
 		error("gridwm: another window manager is already running\n");
@@ -246,6 +251,10 @@ main(int argc, char *argv[])
 	wa.cursor = cursor[CurNormal];
 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
 
+	/* style */
+	loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR);
+	loadfont(dpy, &brush.font, FONT);
+
 	scan_wins();
 
 	cleanup();
diff --git a/wm.h b/wm.h
index 70f7ec7..6bf0d5e 100644
--- a/wm.h
+++ b/wm.h
@@ -3,6 +3,7 @@
  * See LICENSE file for license details.
  */
 
+#include "config.h"
 #include "draw.h"
 #include "util.h"
 
@@ -48,11 +49,14 @@ struct Tag {
 extern Display *dpy;
 extern Window root;
 extern XRectangle rect;
-extern int screen, sel_screen;
-extern unsigned int kmask, numlock_mask;
 extern Atom wm_atom[WMLast];
 extern Atom net_atom[NetLast];
 extern Cursor cursor[CurLast];
 extern Pixmap pmap;
 
+extern int screen, sel_screen;
+extern unsigned int kmask, numlock_mask;
+
+extern Brush brush;
+
 /* wm.c */
mmitter Kartik Agaram <vc@akkartik.com> 2018-07-27 13:30:19 -0700 4445 - support labels' href='/akkartik/mu/commit/subx/026labels.cc?h=hlt&id=071afeff5d99732b2f50f2a5009dc6f2e8303909'>071afeff ^
03e72be6 ^



03e72be6 ^
94ad882e ^
420cb686 ^
f02ca8df ^



f02ca8df ^
94ad882e ^
420cb686 ^




f3901d90 ^
94ad882e ^
420cb686 ^
87d5bdb9 ^




bccaa722 ^
94ad882e ^

bccaa722 ^
87d5bdb9 ^
94ad882e ^
bccaa722 ^
87d5bdb9 ^
a6061b9f ^


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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275