diff options
| author | Hiltjo Posthuma <hiltjo@codemadness.org> | 2015-10-20 23:34:49 +0200 | 
|---|---|---|
| committer | Hiltjo Posthuma <hiltjo@codemadness.org> | 2015-10-20 23:38:31 +0200 | 
| commit | 646b351cc79845f4cc77415dfff474b9ae0053d9 (patch) | |
| tree | d3de639691f7f845a705007e93560160d3b3ee5c | |
| parent | e3b7e1d620e18818222c1e5033356ae29dd49e7f (diff) | |
sync updated drw code from dmenu
important:
- drw_rect: didn't use w and h, change the dwm code accordingly.
- drw_text: text is NULL is not allowed, use drw_rect().
| -rw-r--r-- | drw.c | 251 | ||||
| -rw-r--r-- | drw.h | 34 | ||||
| -rw-r--r-- | dwm.c | 10 | ||||
| -rw-r--r-- | util.c | 26 | ||||
| -rw-r--r-- | util.h | 1 | 
5 files changed, 164 insertions, 158 deletions
| @@ -9,7 +9,7 @@  #include "util.h"  #define UTF_INVALID 0xFFFD -#define UTF_SIZ 4 +#define UTF_SIZ     4  static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};  static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; @@ -17,50 +17,55 @@ static const long utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000  static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};  static long -utf8decodebyte(const char c, size_t *i) { -	for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) -		if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) +utf8decodebyte(const char c, size_t *i) +{ +	for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) +		if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])  			return (unsigned char)c & ~utfmask[*i];  	return 0;  }  static size_t -utf8validate(long *u, size_t i) { -	if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) +utf8validate(long *u, size_t i) +{ +	if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))  		*u = UTF_INVALID; -	for(i = 1; *u > utfmax[i]; ++i) +	for (i = 1; *u > utfmax[i]; ++i)  		;  	return i;  }  static size_t -utf8decode(const char *c, long *u, size_t clen) { +utf8decode(const char *c, long *u, size_t clen) +{  	size_t i, j, len, type;  	long udecoded;  	*u = UTF_INVALID; -	if(!clen) +	if (!clen)  		return 0;  	udecoded = utf8decodebyte(c[0], &len); -	if(!BETWEEN(len, 1, UTF_SIZ)) +	if (!BETWEEN(len, 1, UTF_SIZ))  		return 1; -	for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { +	for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {  		udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); -		if(type != 0) +		if (type)  			return j;  	} -	if(j < len) +	if (j < len)  		return 0;  	*u = udecoded;  	utf8validate(u, len); +  	return len;  }  Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { -	Drw *drw = (Drw *)calloc(1, sizeof(Drw)); -	if(!drw) -		return NULL; +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ +	Drw *drw; + +	drw = ecalloc(1, sizeof(Drw));  	drw->dpy = dpy;  	drw->screen = screen;  	drw->root = root; @@ -70,26 +75,27 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h  	drw->gc = XCreateGC(dpy, root, 0, NULL);  	drw->fontcount = 0;  	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); +  	return drw;  }  void -drw_resize(Drw *drw, unsigned int w, unsigned int h) { -	if(!drw) -		return; +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{  	drw->w = w;  	drw->h = h; -	if(drw->drawable != 0) +	if (drw->drawable)  		XFreePixmap(drw->dpy, drw->drawable);  	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));  }  void -drw_free(Drw *drw) { +drw_free(Drw *drw) +{  	size_t i; -	for (i = 0; i < drw->fontcount; i++) { + +	for (i = 0; i < drw->fontcount; i++)  		drw_font_free(drw->fonts[i]); -	}  	XFreePixmap(drw->dpy, drw->drawable);  	XFreeGC(drw->dpy, drw->gc);  	free(drw); @@ -99,14 +105,11 @@ drw_free(Drw *drw) {   * drw_font_create instead.   */  static Fnt * -drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { +drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) +{  	Fnt *font; - -	if (!(fontname || fontpattern)) -		die("No font specified.\n"); - -	if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) -		return NULL; +	XftFont *xfont = NULL; +	FcPattern *pattern = NULL;  	if (fontname) {  		/* Using the pattern found at font->xfont->pattern does not yield same @@ -115,46 +118,50 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) {  		 * behaviour whereas the former just results in  		 * missing-character-rectangles being drawn, at least with some fonts.  		 */ -		if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || -		    !(font->pattern = FcNameParse((FcChar8 *) fontname))) { -			if (font->xfont) { -				XftFontClose(drw->dpy, font->xfont); -				font->xfont = NULL; -			} +		if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {  			fprintf(stderr, "error, cannot load font: '%s'\n", fontname); +			return NULL; +		} +		if (!(pattern = FcNameParse((FcChar8 *) fontname))) { +			fprintf(stderr, "error, cannot load font: '%s'\n", fontname); +			XftFontClose(drw->dpy, xfont); +			return NULL;  		}  	} else if (fontpattern) { -		if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { +		if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {  			fprintf(stderr, "error, cannot load font pattern.\n"); -		} else { -			font->pattern = NULL; +			return NULL;  		} +	} else { +		die("no font specified.\n");  	} -	if (!font->xfont) { -		free(font); -		return NULL; -	} - -	font->ascent = font->xfont->ascent; -	font->descent = font->xfont->descent; +	font = ecalloc(1, sizeof(Fnt)); +	font->xfont = xfont; +	font->pattern = pattern; +	font->ascent = xfont->ascent; +	font->descent = xfont->descent;  	font->h = font->ascent + font->descent;  	font->dpy = drw->dpy; +  	return font;  }  Fnt* -drw_font_create(Drw *drw, const char *fontname) { +drw_font_create(Drw *drw, const char *fontname) +{  	return drw_font_xcreate(drw, fontname, NULL);  }  void -drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { +drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) +{  	size_t i;  	Fnt *font; +  	for (i = 0; i < fontcount; i++) {  		if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { -			die("Font cache exhausted.\n"); +			die("font cache exhausted.\n");  		} else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) {  			drw->fonts[drw->fontcount++] = font;  		} @@ -162,68 +169,62 @@ drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) {  }  void -drw_font_free(Fnt *font) { -	if(!font) +drw_font_free(Fnt *font) +{ +	if (!font)  		return; -	if(font->pattern) +	if (font->pattern)  		FcPatternDestroy(font->pattern);  	XftFontClose(font->dpy, font->xfont);  	free(font);  }  Clr * -drw_clr_create(Drw *drw, const char *clrname) { +drw_clr_create(Drw *drw, const char *clrname) +{  	Clr *clr; -	Colormap cmap; -	Visual *vis; - -	if(!drw) -		return NULL; -	clr = (Clr *)calloc(1, sizeof(Clr)); -	if(!clr) -		return NULL; -	cmap = DefaultColormap(drw->dpy, drw->screen); -	vis = DefaultVisual(drw->dpy, drw->screen); -	if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) + +	clr = ecalloc(1, sizeof(Clr)); +	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), +	                       DefaultColormap(drw->dpy, drw->screen), +	                       clrname, &clr->rgb))  		die("error, cannot allocate color '%s'\n", clrname);  	clr->pix = clr->rgb.pixel; +  	return clr;  }  void -drw_clr_free(Clr *clr) { -	if(clr) -		free(clr); +drw_clr_free(Clr *clr) +{ +	free(clr);  }  void -drw_setscheme(Drw *drw, ClrScheme *scheme) { -	if(drw && scheme) -		drw->scheme = scheme; +drw_setscheme(Drw *drw, ClrScheme *scheme) +{ +	drw->scheme = scheme;  }  void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) { -	int dx; - -	if(!drw || !drw->fontcount || !drw->scheme) +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) +{ +	if (!drw->scheme)  		return;  	XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); -	dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; -	if(filled) -		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx+1, dx+1); -	else if(empty) -		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx, dx); +	if (filled) +		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); +	else if (empty) +		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);  }  int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) { +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) +{  	char buf[1024];  	int tx, ty, th;  	Extnts tex; -	Colormap cmap; -	Visual *vis; -	XftDraw *d; +	XftDraw *d = NULL;  	Fnt *curfont, *nextfont;  	size_t i, len;  	int utf8strlen, utf8charlen, render; @@ -235,23 +236,18 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex  	XftResult result;  	int charexists = 0; +	if (!drw->scheme || !drw->fontcount) +		return 0; +  	if (!(render = x || y || w || h)) {  		w = ~w; -	} - -	if (!drw || !drw->scheme) { -		return 0; -	} else if (render) { -		XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->pix : drw->scheme->bg->pix); +	} else { +		XSetForeground(drw->dpy, drw->gc, invert ? +		               drw->scheme->fg->pix : drw->scheme->bg->pix);  		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); -	} - -	if (!text || !drw->fontcount) { -		return 0; -	} else if (render) { -		cmap = DefaultColormap(drw->dpy, drw->screen); -		vis = DefaultVisual(drw->dpy, drw->screen); -		d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); +		d = XftDrawCreate(drw->dpy, drw->drawable, +		                  DefaultVisual(drw->dpy, drw->screen), +		                  DefaultColormap(drw->dpy, drw->screen));  	}  	curfont = drw->fonts[0]; @@ -274,24 +270,23 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex  				}  			} -			if (!charexists || (nextfont && nextfont != curfont)) { +			if (!charexists || (nextfont && nextfont != curfont))  				break; -			} else { +			else  				charexists = 0; -			}  		}  		if (utf8strlen) {  			drw_font_getexts(curfont, utf8str, utf8strlen, &tex);  			/* shorten text if necessary */ -			for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) +			for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--)  				drw_font_getexts(curfont, utf8str, len, &tex);  			if (len) {  				memcpy(buf, utf8str, len);  				buf[len] = '\0'; -				if(len < utf8strlen) -					for(i = len; i && i > len - 3; buf[--i] = '.'); +				if (len < utf8strlen) +					for (i = len; i && i > len - 3; buf[--i] = '.');  				if (render) {  					th = curfont->ascent + curfont->descent; @@ -299,7 +294,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex  					tx = x + (h / 2);  					XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len);  				} -  				x += tex.w;  				w -= tex.w;  			} @@ -316,18 +310,16 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex  			 */  			charexists = 1; -			if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { +			if (drw->fontcount >= DRW_FONT_CACHE_SIZE)  				continue; -			}  			fccharset = FcCharSetCreate();  			FcCharSetAddChar(fccharset, utf8codepoint);  			if (!drw->fonts[0]->pattern) {  				/* Refer to the comment in drw_font_xcreate for more -				 * information. -				 */ -				die("The first font in the cache must be loaded from a font string.\n"); +				 * information. */ +				die("the first font in the cache must be loaded from a font string.\n");  			}  			fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); @@ -346,65 +338,60 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex  				if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) {  					drw->fonts[drw->fontcount++] = curfont;  				} else { -					if (curfont) { -						drw_font_free(curfont); -					} +					drw_font_free(curfont);  					curfont = drw->fonts[0];  				}  			}  		}  	} - -	if (render) { +	if (d)  		XftDrawDestroy(d); -	}  	return x;  }  void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { -	if(!drw) -		return; +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{  	XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);  	XSync(drw->dpy, False);  } -  void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { +drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) +{  	XGlyphInfo ext; -	if(!font || !text) -		return;  	XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);  	tex->h = font->h;  	tex->w = ext.xOff;  }  unsigned int -drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { +drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) +{  	Extnts tex; -	if(!font) -		return -1;  	drw_font_getexts(font, text, len, &tex); +  	return tex.w;  }  Cur * -drw_cur_create(Drw *drw, int shape) { -	Cur *cur = (Cur *)calloc(1, sizeof(Cur)); +drw_cur_create(Drw *drw, int shape) +{ +	Cur *cur; -	if(!drw || !cur) -		return NULL; +	cur = ecalloc(1, sizeof(Cur));  	cur->cursor = XCreateFontCursor(drw->dpy, shape); +  	return cur;  }  void -drw_cur_free(Drw *drw, Cur *cursor) { -	if(!drw || !cursor) +drw_cur_free(Drw *drw, Cur *cursor) +{ +	if (!cursor)  		return;  	XFreeCursor(drw->dpy, cursor->cursor);  	free(cursor); @@ -43,32 +43,32 @@ typedef struct {  } Extnts;  /* Drawable abstraction */ -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); -void drw_resize(Drw *drw, unsigned int w, unsigned int h); -void drw_free(Drw *drw); +Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); +void drw_resize(Drw *, unsigned int, unsigned int); +void drw_free(Drw *);  /* Fnt abstraction */ -Fnt *drw_font_create(Drw *drw, const char *fontname); -void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); -void drw_font_free(Fnt *font); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *extnts); -unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int len); +Fnt *drw_font_create(Drw *, const char *); +void drw_load_fonts(Drw *, const char *[], size_t); +void drw_font_free(Fnt *); +void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); +unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int);  /* Colour abstraction */ -Clr *drw_clr_create(Drw *drw, const char *clrname); -void drw_clr_free(Clr *clr); +Clr *drw_clr_create(Drw *, const char *); +void drw_clr_free(Clr *);  /* Cursor abstraction */ -Cur *drw_cur_create(Drw *drw, int shape); -void drw_cur_free(Drw *drw, Cur *cursor); +Cur *drw_cur_create(Drw *, int); +void drw_cur_free(Drw *, Cur *);  /* Drawing context manipulation */ -void drw_setfont(Drw *drw, Fnt *font); -void drw_setscheme(Drw *drw, ClrScheme *scheme); +void drw_setfont(Drw *, Fnt *); +void drw_setscheme(Drw *, ClrScheme *);  /* Drawing functions */ -void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert); -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert); +void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); +int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int);  /* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); +void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); @@ -689,10 +689,12 @@ dirtomon(int dir) {  void  drawbar(Monitor *m) { -	int x, xx, w; +	int x, xx, w, dx;  	unsigned int i, occ = 0, urg = 0;  	Client *c; +	dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; +  	for(c = m->clients; c; c = c->next) {  		occ |= c->tags;  		if(c->isurgent) @@ -703,7 +705,7 @@ drawbar(Monitor *m) {  		w = TEXTW(tags[i]);  		drw_setscheme(drw, m->tagset[m->seltags] & 1 << i ? &scheme[SchemeSel] : &scheme[SchemeNorm]);  		drw_text(drw, x, 0, w, bh, tags[i], urg & 1 << i); -		drw_rect(drw, x, 0, w, bh, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, +		drw_rect(drw, x + 1, 1, dx, dx, m == selmon && selmon->sel && selmon->sel->tags & 1 << i,  		           occ & 1 << i, urg & 1 << i);  		x += w;  	} @@ -728,11 +730,11 @@ drawbar(Monitor *m) {  		if(m->sel) {  			drw_setscheme(drw, m == selmon ? &scheme[SchemeSel] : &scheme[SchemeNorm]);  			drw_text(drw, x, 0, w, bh, m->sel->name, 0); -			drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, 0); +			drw_rect(drw, x + 1, 1, dx, dx, m->sel->isfixed, m->sel->isfloating, 0);  		}  		else {  			drw_setscheme(drw, &scheme[SchemeNorm]); -			drw_text(drw, x, 0, w, bh, NULL, 0); +			drw_rect(drw, x, 0, w, bh, 1, 0, 1);  		}  	}  	drw_map(drw, m->barwin, 0, 0, m->ww, bh); @@ -2,16 +2,32 @@  #include <stdarg.h>  #include <stdio.h>  #include <stdlib.h> +#include <string.h>  #include "util.h" +void * +ecalloc(size_t nmemb, size_t size) +{ +	void *p; + +	if (!(p = calloc(nmemb, size))) +		perror(NULL); +	return p; +} +  void -die(const char *errstr, ...) { +die(const char *fmt, ...) {  	va_list ap; -	va_start(ap, errstr); -	vfprintf(stderr, errstr, ap); +	va_start(ap, fmt); +	vfprintf(stderr, fmt, ap);  	va_end(ap); -	exit(EXIT_FAILURE); -} +	if (fmt[0] && fmt[strlen(fmt)-1] == ':') { +		fputc(' ', stderr); +		perror(NULL); +	} + +	exit(1); +} @@ -5,3 +5,4 @@  #define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B))  void die(const char *errstr, ...); +void *ecalloc(size_t, size_t); | 
