decoupled draw.c from dmenu & dinput
Connor Lane Smith cls@lubutu.com
Thu, 24 Jun 2010 16:18:18 +0100
M
dinput.c
→
dinput.c
@@ -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 @@ dc.x = 0;
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 @@ numlockmask = (1 << i);
} 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 @@ DefaultDepth(dpy, screen), CopyFromParent,
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); }
M
draw.c
→
draw.c
@@ -14,126 +14,123 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b))
#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); +setupdraw(DC *dc, Window w) { + XWindowAttributes wa; - /* 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); + 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; }
M
draw.h
→
draw.h
@@ -9,6 +9,7 @@ int x, y, w, h;
unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; + Display *dpy; GC gc; struct { XFontStruct *xfont;@@ -20,25 +21,14 @@ } font;
} 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;