ports/143951: [PATCH] Add support for Xft fonts to x11/dmenu

Ashish SHUKLA wahjava at gmail.com
Mon Feb 15 11:10:02 UTC 2010


>Number:         143951
>Category:       ports
>Synopsis:       [PATCH] Add support for Xft fonts to x11/dmenu
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 15 11:10:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Ashish SHUKLA
>Release:        FreeBSD 8.0-RELEASE amd64
>Organization:
N/A
>Environment:
System: FreeBSD chateau.d.if 8.0-RELEASE FreeBSD 8.0-RELEASE #1: Fri Nov 27 11:09:44 IST 2009 root at chateau.d.if:/usr/obj/usr/src/sys/CHATEAU amd64


>Description:
The attached diff adds support for Xft fonts to dmenu with the help of the diff available at following URL:

http://www.haskell.org/haskellwiki/Dmenu-4.0-xft.diff

A sample Xmonad configuration depicting its use is available at following URL:

http://www.haskell.org/haskellwiki/John-yates-xmonad.hs
>How-To-Repeat:
>Fix:
diff -urN /usr/ports/x11/dmenu/Makefile dmenu/Makefile
--- /usr/ports/x11/dmenu/Makefile	2009-04-28 00:46:36.000000000 +0530
+++ dmenu/Makefile	2010-02-15 16:02:25.000000000 +0530
@@ -7,6 +7,7 @@
 
 PORTNAME=	dmenu
 PORTVERSION=	4.0
+PORTREVISION=	1
 CATEGORIES=	x11
 MASTER_SITES=	http://code.suckless.org/dl/tools/ \
 		http://schot.a-eskwadraat.nl/files/
@@ -14,9 +15,18 @@
 MAINTAINER=	schot at a-eskwadraat.nl
 COMMENT=	X11 menu application (not only) for the dwm window manager
 
+OPTIONS=	XFT	"XFT support" On
+
 USE_XORG=	x11 xinerama
 
 MAN1=		dmenu.1
 PLIST_FILES=	bin/dmenu bin/dmenu_path bin/dmenu_run
 
+.include <bsd.port.options.mk>
+
+.if defined(WITH_XFT)
+MAKE_ARGS+=	-DXFT
+USE_XORG+=	xft
+.endif
+
 .include <bsd.port.mk>
diff -urN /usr/ports/x11/dmenu/files/patch-config.h dmenu/files/patch-config.h
--- /usr/ports/x11/dmenu/files/patch-config.h	1970-01-01 05:30:00.000000000 +0530
+++ dmenu/files/patch-config.h	2010-02-15 15:26:40.000000000 +0530
@@ -0,0 +1,11 @@
+
+$FreeBSD$
+
+--- config.h.orig
++++ config.h
+@@ -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 -urN /usr/ports/x11/dmenu/files/patch-config.mk dmenu/files/patch-config.mk
--- /usr/ports/x11/dmenu/files/patch-config.mk	2009-04-28 00:46:36.000000000 +0530
+++ dmenu/files/patch-config.mk	2010-02-15 15:56:22.000000000 +0530
@@ -1,6 +1,9 @@
---- config.mk.orig	2009-04-18 13:50:04.000000000 +0200
-+++ config.mk	2009-04-21 13:15:36.000000000 +0200
-@@ -4,11 +4,11 @@
+
+$FreeBSD$
+
+--- config.mk.orig
++++ config.mk
+@@ -4,28 +4,35 @@
  # Customize below to fit your system
  
  # paths
@@ -16,14 +19,26 @@
  
  # Xinerama, comment if you don't want it
  XINERAMALIBS = -L${X11LIB} -lXinerama
-@@ -19,13 +19,13 @@
- LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
+ XINERAMAFLAGS = -DXINERAMA
+ 
++.if defined(XFT)
++# Xft, comment if you don't want it
++XFTINCS = `pkg-config --cflags xft`
++XFTLIBS = `pkg-config --libs xft`
++XFTFLAGS = -DXFT
++.endif
++
+ # 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}
 -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
 -LDFLAGS = -s ${LIBS}
-+CPPFLAGS+= -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
++CPPFLAGS+= -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XFTFLAGS}
 +CFLAGS+= -std=c99 ${INCS} ${CPPFLAGS}
 +LDFLAGS+= ${LIBS}
  
diff -urN /usr/ports/x11/dmenu/files/patch-dmenu.c dmenu/files/patch-dmenu.c
--- /usr/ports/x11/dmenu/files/patch-dmenu.c	1970-01-01 05:30:00.000000000 +0530
+++ dmenu/files/patch-dmenu.c	2010-02-15 16:01:17.000000000 +0530
@@ -0,0 +1,247 @@
+
+$FreeBSD$
+
+--- dmenu.c.orig
++++ dmenu.c
+@@ -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,16 @@
+ 		free(allitems);
+ 		allitems = itm;
+ 	}
+-	if(dc.font.set)
+-		XFreeFontSet(dpy, dc.font.set);
+-	else
+-		XFreeFont(dpy, dc.font.xfont);
++#ifdef XFT
++	if(!dc.font.xftfont) {
++#endif
++		if(dc.font.set)
++			XFreeFontSet(dpy, dc.font.set);
++		else
++			XFreeFont(dpy, dc.font.xfont);
++#ifdef XFT
++	}
++#endif
+ 	XFreePixmap(dpy, dc.drawable);
+ 	XFreeGC(dpy, dc.gc);
+ 	XDestroyWindow(dpy, win);
+@@ -232,11 +253,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 +288,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 +315,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 +363,9 @@
+ 		dc.font.descent = dc.font.xfont->descent;
+ 	}
+ 	dc.font.height = dc.font.ascent + dc.font.descent;
++#ifdef XFT
++	}
++#endif
+ }
+ 
+ void
+@@ -585,11 +645,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 +668,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 +704,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 +732,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 +748,9 @@
+ 		return r.width;
+ 	}
+ 	return XTextWidth(dc.font.xfont, text, len);
++#ifdef XFT
++	}
++#endif
+ }
+ 
+ int
+@@ -691,14 +786,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)))
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list