Dmenu-4.0-xft.diff
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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)))