dmenu

Dmenu fork with xft fonts.
git clone git://r-36.net/dmenu
Log | Files | Refs | README | LICENSE

commit 96c65400ccdcb76cf20ec7721920f944e6b490ec
parent 6c1d0e4d60b239e9533def6feaf8eb2138858c3e
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Thu, 24 Jun 2010 16:18:18 +0100

decoupled draw.c from dmenu & dinput
Diffstat:
dinput.c | 40++++++++++++++++++++++------------------
dmenu.c | 49++++++++++++++++++++++++++-----------------------
draw.c | 109++++++++++++++++++++++++++++++++++++++-----------------------------------------
draw.h | 30++++++++++--------------------
4 files changed, 111 insertions(+), 117 deletions(-)

diff --git a/dinput.c b/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 @@ 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); } diff --git a/dmenu.c b/dmenu.c @@ -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); diff --git a/draw.c b/draw.c @@ -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; } diff --git a/draw.h b/draw.h @@ -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;