Dmenu-4.0-xft.diff

From HaskellWiki
Revision as of 01:40, 28 May 2009 by Jsyjr (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (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)))