diff -r 9b203c5c180d config.h --- a/config.h Sat Apr 18 12:50:12 2009 +0100 +++ b/config.h Tue May 19 23:31:17 2009 -0400 @@ -5,5 +5,4 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; static unsigned int spaceitem = 30; /* px between menu items */ diff -r 9b203c5c180d config.mk --- a/config.mk Sat Apr 18 12:50:12 2009 +0100 +++ b/config.mk Tue May 19 23:31:17 2009 -0400 @@ -14,12 +14,17 @@ XINERAMALIBS = -L${X11LIB} -lXinerama XINERAMAFLAGS = -DXINERAMA +# Xft, comment if you don't want it +#XFTINCS = `pkg-config --cflags xft` +#XFTLIBS = `pkg-config --libs xft` +#XFTFLAGS = -DXFT + # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I. -I/usr/include -I${X11INC} ${XFTINCS} +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XFTFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff -r 9b203c5c180d dmenu.c --- a/dmenu.c Sat Apr 18 12:50:12 2009 +0100 +++ b/dmenu.c Tue May 19 23:31:17 2009 -0400 @@ -10,6 +10,9 @@ #include #include #include +#ifdef XFT +#include +#endif #ifdef XINERAMA #include #endif @@ -28,6 +31,11 @@ unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; +#ifdef XFT + XftColor xftnorm[ColLast]; + XftColor xftsel[ColLast]; + XftDraw *xftdrawable; +#endif GC gc; struct { XFontStruct *xfont; @@ -35,6 +43,10 @@ int ascent; int descent; int height; +#ifdef XFT + XftFont *xftfont; + XGlyphInfo *extents; +#endif } font; } DC; /* draw context */ @@ -54,6 +66,9 @@ static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); static unsigned long getcolor(const char *colstr); +#ifdef XFT +static unsigned long getxftcolor(const char *colstr, XftColor *color); +#endif static Bool grabkeyboard(void); static void initfont(const char *fontstr); static void kpress(XKeyEvent * e); @@ -74,7 +89,7 @@ static int promptw = 0; static int ret = 0; static int screen; -static unsigned int mw, mh; +static unsigned int mw, mh, bh; static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; @@ -232,11 +247,19 @@ memcpy(buf, text, len); if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); +#ifdef XFT + if(dc.font.xftfont) + XftDrawStringUtf8(dc.xftdrawable, &dc.xftnorm[ColFG], dc.font.xftfont, x, y, (unsigned char*) buf, len); + else { +#endif XSetForeground(dpy, dc.gc, col[ColFG]); if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); else XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +#ifdef XFT + } +#endif } void @@ -259,6 +282,18 @@ return color.pixel; } +#ifdef XFT +unsigned long +getxftcolor(const char *colstr, XftColor *color) { + Colormap cmap = DefaultColormap(dpy, screen); + Visual *vis = DefaultVisual(dpy, screen); + + if(!XftColorAllocName(dpy, vis, cmap, colstr, color)) + eprint("error, cannot allocate color '%s'\n", colstr); + return color->pixel; +} +#endif + Bool grabkeyboard(void) { unsigned int len; @@ -274,6 +309,22 @@ void initfont(const char *fontstr) { +#ifdef XFT + dc.font.xftfont = 0; + if(cistrstr(fontstr,"xft:")) { + dc.font.xftfont = XftFontOpenXlfd(dpy, screen, fontstr); + if(!dc.font.xftfont) + dc.font.xftfont = XftFontOpenName(dpy, screen, fontstr); + if(!dc.font.xftfont) + eprint("error, cannot load font: '%s'\n", fontstr); + dc.font.extents = malloc(sizeof(XGlyphInfo)); + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) fontstr, strlen(fontstr), dc.font.extents); + dc.font.height = dc.font.xftfont->ascent + dc.font.xftfont->descent; + dc.font.ascent = dc.font.xftfont->ascent; + dc.font.descent = dc.font.xftfont->descent; + } + else { +#endif char *def, **missing; int i, n; @@ -306,6 +357,9 @@ dc.font.descent = dc.font.xfont->descent; } dc.font.height = dc.font.ascent + dc.font.descent; +#ifdef XFT + } +#endif } void @@ -585,11 +639,21 @@ XFreeModifiermap(modmap); /* style */ + initfont(font); +#ifdef XFT + if(dc.font.xftfont) { + dc.norm[ColBG] = getxftcolor(normbgcolor, &dc.xftnorm[ColBG]); + dc.norm[ColFG] = getxftcolor(normfgcolor, &dc.xftnorm[ColFG]); + dc.sel[ColBG] = getxftcolor(selbgcolor, &dc.xftsel[ColBG]); + } + else { +#endif dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); - initfont(font); +#ifdef XFT + } +#endif /* menu window */ wa.override_redirect = True; @@ -598,6 +662,8 @@ /* menu window geometry */ mh = dc.font.height + 2; + if(mh < bh) + mh = bh; #if XINERAMA if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; @@ -632,8 +698,19 @@ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); +#ifdef XFT + if(dc.font.xftfont) { + dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen)); + if(!dc.xftdrawable) + eprint("error, cannot create drawable\n"); + } + else { +#endif if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); +#ifdef XFT + } +#endif if(maxname) cmdw = textw(maxname); if(cmdw > mw / 3) @@ -649,6 +726,15 @@ int textnw(const char *text, unsigned int len) { +#ifdef XFT + if (dc.font.xftfont) { + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) text, strlen(text), dc.font.extents); + if(dc.font.extents->height > dc.font.height) + dc.font.height = dc.font.extents->height; + return dc.font.extents->xOff; + } + else { +#endif XRectangle r; if(dc.font.set) { @@ -656,6 +742,9 @@ return r.width; } return XTextWidth(dc.font.xfont, text, len); +#ifdef XFT + } +#endif } int @@ -691,14 +780,14 @@ else if(!strcmp(argv[i], "-sb")) { if(++i < argc) selbgcolor = argv[i]; } - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; + else if(!strcmp(argv[i], "-bh")) { + if(++i < argc) bh = atoi(argv[i]); } else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); else eprint("usage: dmenu [-i] [-b] [-fn ] [-nb ] [-nf ]\n" - " [-p ] [-sb ] [-sf ] [-v]\n"); + " [-sb ] [-p ] [-bh ] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL)))