Dmenu-4.0-xft.diff
Jump to navigation
Jump to search
diff -r cdaa1062e534 config.h --- a/config.h Fri May 22 06:02:00 2009 -0400 +++ b/config.h Wed May 27 20:39:52 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 cdaa1062e534 config.mk --- a/config.mk Fri May 22 06:02:00 2009 -0400 +++ b/config.mk Wed May 27 20:39:52 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 cdaa1062e534 dmenu.c --- a/dmenu.c Fri May 22 06:02:00 2009 -0400 +++ b/dmenu.c Wed May 27 20:39:52 2009 -0400 @@ -10,6 +10,9 @@ #include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> +#ifdef XFT +#include <X11/Xft/Xft.h> +#endif #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #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; @@ -160,10 +175,12 @@ free(allitems); allitems = itm; } - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); - else - XFreeFont(dpy, dc.font.xfont); + if(!dc.font.xftfont) { + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else + XFreeFont(dpy, dc.font.xfont); + } XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); XDestroyWindow(dpy, win); @@ -232,11 +249,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 +284,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 +311,22 @@ void initfont(const char *fontstr) { +#ifdef XFT + dc.font.xftfont = 0; + if(cistrstr(fontstr,"xft:")) { + dc.font.xftfont = XftFontOpenXlfd(dpy, screen, fontstr+4); + if(!dc.font.xftfont) + dc.font.xftfont = XftFontOpenName(dpy, screen, fontstr+4); + if(!dc.font.xftfont) + eprint("error, cannot load font: '%s'\n", fontstr+4); + dc.font.extents = malloc(sizeof(XGlyphInfo)); + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) fontstr+4, strlen(fontstr+4), 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 +359,9 @@ dc.font.descent = dc.font.xfont->descent; } dc.font.height = dc.font.ascent + dc.font.descent; +#ifdef XFT + } +#endif } void @@ -585,11 +641,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 +664,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 +700,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 +728,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 +744,9 @@ return r.width; } return XTextWidth(dc.font.xfont, text, len); +#ifdef XFT + } +#endif } int @@ -691,14 +782,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 <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); + " [-sb <color>] [-bh <height>] [-p <prompt>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL)))