diff options
Diffstat (limited to '')
| -rw-r--r-- | dinput.c | 40 | ||||
| -rw-r--r-- | dmenu.c | 49 | ||||
| -rw-r--r-- | draw.c | 109 | ||||
| -rw-r--r-- | draw.h | 30 | 
4 files changed, 111 insertions, 117 deletions
@@ -38,20 +38,18 @@ static char *prompt = NULL;  static char text[4096];  static int promptw = 0;  static int ret = 0; +static int screen;  static unsigned int cursor = 0;  static unsigned int numlockmask = 0; +static unsigned int mw, mh;  static Bool running = True; -static Window win; - -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -Window parent; +static DC dc; +static Display *dpy; +static Window win, parent;  void  cleanup(void) { -	drawcleanup(); +	cleanupdraw(&dc);  	XDestroyWindow(dpy, win);  	XUngrabKeyboard(dpy, CurrentTime);  } @@ -60,7 +58,7 @@ void  drawcursor(void) {  	XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; -	r.x += textnw(text, cursor) + dc.font.height / 2; +	r.x += textnw(&dc, text, cursor) + dc.font.height / 2;  	XSetForeground(dpy, dc.gc, dc.norm[ColFG]);  	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); @@ -73,15 +71,15 @@ drawinput(void)  	dc.y = 0;  	dc.w = mw;  	dc.h = mh; -	drawtext(NULL, dc.norm); +	drawtext(&dc, NULL, dc.norm);  	/* print prompt? */  	if(prompt) {  		dc.w = promptw; -		drawtext(prompt, dc.sel); +		drawtext(&dc, prompt, dc.sel);  		dc.x += dc.w;  	}  	dc.w = mw - dc.x; -	drawtext(*text ? text : NULL, dc.norm); +	drawtext(&dc, *text ? text : NULL, dc.norm);  	drawcursor();  	XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0);  	XFlush(dpy); @@ -269,15 +267,21 @@ setup(Bool topbar) {  		}  	XFreeModifiermap(modmap); -	initfont(font); +	dc.dpy = dpy; +	dc.norm[ColBG] = getcolor(&dc, normbgcolor); +	dc.norm[ColFG] = getcolor(&dc, normfgcolor); +	dc.sel[ColBG] = getcolor(&dc, selbgcolor); +	dc.sel[ColFG] = getcolor(&dc, selfgcolor); +	initfont(&dc, font); +	fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); -	/* menu window */ +	/* input window */  	wa.override_redirect = True;  	wa.background_pixmap = ParentRelative;  	wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; -	/* menu window geometry */ -	mh = (dc.font.height + 2); +	/* input window geometry */ +	mh = dc.font.height + 2;  #if XINERAMA  	if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {  		i = 0; @@ -309,9 +313,9 @@ setup(Bool topbar) {  			DefaultVisual(dpy, screen),  			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); -	drawsetup(); +	setupdraw(&dc, win);  	if(prompt) -		promptw = MIN(textw(prompt), mw / 5); +		promptw = MIN(textw(&dc, prompt), mw / 5);  	cursor = strlen(text);  	XMapRaised(dpy, win);  } @@ -55,26 +55,24 @@ static char text[4096];  static int cmdw = 0;  static int promptw = 0;  static int ret = 0; +static int screen;  static unsigned int lines = 0;  static unsigned int numlockmask = 0; +static unsigned int mw, mh;  static Bool running = True; +static DC dc; +static Display *dpy;  static Item *allitems = NULL;  /* first of all items */  static Item *item = NULL;      /* first of pattern matching items */  static Item *sel = NULL;  static Item *next = NULL;  static Item *prev = NULL;  static Item *curr = NULL; -static Window win; +static Window win, parent;  static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;  static char *(*fstrstr)(const char *, const char *) = strstr;  static void (*calcoffsets)(void) = calcoffsetsh; -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -Window parent; -  void  appenditem(Item *i, Item **list, Item **last) {  	if(!(*last)) @@ -92,11 +90,11 @@ calcoffsetsh(void) {  	w = promptw + cmdw + (2 * spaceitem);  	for(next = curr; next; next = next->right) -		if((w += MIN(textw(next->text), mw / 3)) > mw) +		if((w += MIN(textw(&dc, next->text), mw / 3)) > mw)  			break;  	w = promptw + cmdw + (2 * spaceitem);  	for(prev = curr; prev && prev->left; prev = prev->left) -		if((w += MIN(textw(prev->left->text), mw / 3)) > mw) +		if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw)  			break;  } @@ -143,7 +141,7 @@ cleanup(void) {  		free(allitems);  		allitems = itm;  	} -	drawcleanup(); +	cleanupdraw(&dc);  	XDestroyWindow(dpy, win);  	XUngrabKeyboard(dpy, CurrentTime);  } @@ -161,18 +159,18 @@ drawmenu(void) {  	dc.y = 0;  	dc.w = mw;  	dc.h = mh; -	drawtext(NULL, dc.norm); +	drawtext(&dc, NULL, dc.norm);  	/* print prompt? */  	if(prompt) {  		dc.w = promptw; -		drawtext(prompt, dc.sel); +		drawtext(&dc, prompt, dc.sel);  		dc.x += dc.w;  	}  	dc.w = mw - dc.x;  	/* print command */  	if(cmdw && item && lines == 0)  		dc.w = cmdw; -	drawtext(*text ? text : NULL, dc.norm); +	drawtext(&dc, *text ? text : NULL, dc.norm);  	if(curr) {  		if(lines > 0)  			drawmenuv(); @@ -189,16 +187,16 @@ drawmenuh(void) {  	dc.x += cmdw;  	dc.w = spaceitem; -	drawtext(curr->left ? "<" : NULL, dc.norm); +	drawtext(&dc, curr->left ? "<" : NULL, dc.norm);  	dc.x += dc.w;  	for(i = curr; i != next; i=i->right) { -		dc.w = MIN(textw(i->text), mw / 3); -		drawtext(i->text, (sel == i) ? dc.sel : dc.norm); +		dc.w = MIN(textw(&dc, i->text), mw / 3); +		drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm);  		dc.x += dc.w;  	}  	dc.w = spaceitem;  	dc.x = mw - dc.w; -	drawtext(next ? ">" : NULL, dc.norm); +	drawtext(&dc, next ? ">" : NULL, dc.norm);  }  void @@ -209,11 +207,11 @@ drawmenuv(void) {  	dc.h = dc.font.height + 2;  	dc.y = dc.h;  	for(i = curr; i != next; i=i->right) { -		drawtext(i->text, (sel == i) ? dc.sel : dc.norm); +		drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm);  		dc.y += dc.h;  	}  	dc.h = mh - dc.y; -	drawtext(NULL, dc.norm); +	drawtext(&dc, NULL, dc.norm);  }  Bool @@ -491,7 +489,12 @@ setup(Bool topbar) {  		}  	XFreeModifiermap(modmap); -	initfont(font); +	dc.dpy = dpy; +	dc.norm[ColBG] = getcolor(&dc, normbgcolor); +	dc.norm[ColFG] = getcolor(&dc, normfgcolor); +	dc.sel[ColBG] = getcolor(&dc, selbgcolor); +	dc.sel[ColFG] = getcolor(&dc, selfgcolor); +	initfont(&dc, font);  	/* menu window */  	wa.override_redirect = True; @@ -531,11 +534,11 @@ setup(Bool topbar) {  			DefaultVisual(dpy, screen),  			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); -	drawsetup(); +	setupdraw(&dc, win);  	if(maxname) -		cmdw = MIN(textw(maxname), mw / 3); +		cmdw = MIN(textw(&dc, maxname), mw / 3);  	if(prompt) -		promptw = MIN(textw(prompt), mw / 5); +		promptw = MIN(textw(&dc, prompt), mw / 5);  	text[0] = '\0';  	match(text);  	XMapRaised(dpy, win); @@ -14,126 +14,123 @@  #define MAX(a, b)               ((a) > (b) ? (a) : (b))  /* variables */ -char *progname; +const char *progname;  void -drawcleanup(void) { -	if(dc.font.set) -		XFreeFontSet(dpy, dc.font.set); +cleanupdraw(DC *dc) { +	if(dc->font.set) +		XFreeFontSet(dc->dpy, dc->font.set);  	else -		XFreeFont(dpy, dc.font.xfont); -	XFreePixmap(dpy, dc.drawable); -	XFreeGC(dpy, dc.gc); +		XFreeFont(dc->dpy, dc->font.xfont); +	XFreePixmap(dc->dpy, dc->drawable); +	XFreeGC(dc->dpy, dc->gc);  }  void -drawsetup(void) { -	/* style */ -	dc.norm[ColBG] = getcolor(normbgcolor); -	dc.norm[ColFG] = getcolor(normfgcolor); -	dc.sel[ColBG] = getcolor(selbgcolor); -	dc.sel[ColFG] = getcolor(selfgcolor); - -	/* pixmap */ -	dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); -	dc.gc = XCreateGC(dpy, parent, 0, NULL); -	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); -	if(!dc.font.set) -		XSetFont(dpy, dc.gc, dc.font.xfont->fid); +setupdraw(DC *dc, Window w) { +	XWindowAttributes wa; + +	XGetWindowAttributes(dc->dpy, w, &wa); +	dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, +		DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); +	dc->gc = XCreateGC(dc->dpy, w, 0, NULL); +	XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); +	if(!dc->font.set) +		XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);  }  void -drawtext(const char *text, unsigned long col[ColLast]) { +drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {  	char buf[256];  	int i, x, y, h, len, olen; -	XRectangle r = { dc.x, dc.y, dc.w, dc.h }; +	XRectangle r = { dc->x, dc->y, dc->w, dc->h }; -	XSetForeground(dpy, dc.gc, col[ColBG]); -	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); +	XSetForeground(dc->dpy, dc->gc, col[ColBG]); +	XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1);  	if(!text)  		return;  	olen = strlen(text); -	h = dc.font.height; -	y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; -	x = dc.x + (h / 2); +	h = dc->font.height; +	y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; +	x = dc->x + (h / 2);  	/* shorten text if necessary */ -	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); +	for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--);  	if(!len)  		return;  	memcpy(buf, text, len);  	if(len < olen)  		for(i = len; i && i > len - 3; buf[--i] = '.'); -	XSetForeground(dpy, dc.gc, col[ColFG]); -	if(dc.font.set) -		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); +	XSetForeground(dc->dpy, dc->gc, col[ColFG]); +	if(dc->font.set) +		XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len);  	else -		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +		XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len);  }  void -eprint(const char *errstr, ...) { +eprint(const char *fmt, ...) {  	va_list ap;  	fprintf(stderr, "%s: ", progname); -	va_start(ap, errstr); -	vfprintf(stderr, errstr, ap); +	va_start(ap, fmt); +	vfprintf(stderr, fmt, ap);  	va_end(ap);  	exit(EXIT_FAILURE);  }  unsigned long -getcolor(const char *colstr) { -	Colormap cmap = DefaultColormap(dpy, screen); +getcolor(DC *dc, const char *colstr) { +	Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy));  	XColor color; -	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) +	if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color))  		eprint("cannot allocate color '%s'\n", colstr);  	return color.pixel;  }  void -initfont(const char *fontstr) { +initfont(DC *dc, const char *fontstr) {  	char *def, **missing = NULL;  	int i, n;  	if(!fontstr || !*fontstr)  		eprint("cannot load null font\n"); -	dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); +	dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def);  	if(missing)  		XFreeStringList(missing); -	if(dc.font.set) { +	if(dc->font.set) {  		XFontStruct **xfonts;  		char **font_names; -		dc.font.ascent = dc.font.descent = 0; -		n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); +		dc->font.ascent = dc->font.descent = 0; +		n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names);  		for(i = 0; i < n; i++) { -			dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); -			dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); +			dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); +			dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent);  			xfonts++;  		}  	}  	else { -		if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) -		&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) +		if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) +		&& !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed")))  			eprint("cannot load font '%s'\n", fontstr); -		dc.font.ascent = dc.font.xfont->ascent; -		dc.font.descent = dc.font.xfont->descent; +		dc->font.ascent = dc->font.xfont->ascent; +		dc->font.descent = dc->font.xfont->descent;  	} -	dc.font.height = dc.font.ascent + dc.font.descent; +	dc->font.height = dc->font.ascent + dc->font.descent;  }  int -textnw(const char *text, unsigned int len) { +textnw(DC *dc, const char *text, unsigned int len) {  	XRectangle r; -	if(dc.font.set) { -		XmbTextExtents(dc.font.set, text, len, NULL, &r); +	if(dc->font.set) { +		XmbTextExtents(dc->font.set, text, len, NULL, &r);  		return r.width;  	} -	return XTextWidth(dc.font.xfont, text, len); +	return XTextWidth(dc->font.xfont, text, len);  }  int -textw(const char *text) { -	return textnw(text, strlen(text)) + dc.font.height; +textw(DC *dc, const char *text) { +	return textnw(dc, text, strlen(text)) + dc->font.height;  } @@ -9,6 +9,7 @@ typedef struct {  	unsigned long norm[ColLast];  	unsigned long sel[ColLast];  	Drawable drawable; +	Display *dpy;  	GC gc;  	struct {  		XFontStruct *xfont; @@ -20,25 +21,14 @@ typedef struct {  } DC; /* draw context */  /* forward declarations */ -void drawcleanup(void); -void drawsetup(void); -void drawtext(const char *text, unsigned long col[ColLast]); -void eprint(const char *errstr, ...); -unsigned long getcolor(const char *colstr); -void initfont(const char *fontstr); -int textnw(const char *text, unsigned int len); -int textw(const char *text); +void cleanupdraw(DC *dc); +void setupdraw(DC *dc, Window w); +void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); +void eprint(const char *fmt, ...); +unsigned long getcolor(DC *dc, const char *colstr); +void initfont(DC *dc, const char *fontstr); +int textnw(DC *dc, const char *text, unsigned int len); +int textw(DC *dc, const char *text);  /* variables */ -extern char *progname; -extern Display *dpy; -extern DC dc; -extern int screen; -extern unsigned int mw, mh; -extern Window parent; - -extern const char *font; -extern const char *normbgcolor; -extern const char *normfgcolor; -extern const char *selbgcolor; -extern const char *selfgcolor; +extern const char *progname;  | 
