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)))