1 diff -rup dmenu-4.3.1/config.mk dmenu-xft/config.mk
2 --- dmenu-4.3.1/config.mk 2011-05-18 21:32:16.000000000 +0530
3 +++ dmenu-xft/config.mk 2011-05-20 03:14:15.000000000 +0530
9 -MANPREFIX = ${PREFIX}/share/man
11 +MANPREFIX = ${PREFIX}/share
13 X11INC = /usr/X11R6/include
14 X11LIB = /usr/X11R6/lib
16 +# Xft, comment if you don't want it
17 +XFTINC = /usr/include/freetype2
18 +XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig
21 # Xinerama, comment if you don't want it
22 XINERAMALIBS = -lXinerama
23 XINERAMAFLAGS = -DXINERAMA
27 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
28 +INCS = -I${X11INC} -I${XFTINC}
29 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS}
32 CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
33 diff -rup dmenu-4.3.1/dmenu.c dmenu-xft/dmenu.c
34 --- dmenu-4.3.1/dmenu.c 2011-05-18 21:32:16.000000000 +0530
35 +++ dmenu-xft/dmenu.c 2011-05-20 03:12:16.000000000 +0530
37 #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
38 #define MIN(a,b) ((a) < (b) ? (a) : (b))
39 #define MAX(a,b) ((a) > (b) ? (a) : (b))
40 +#define DEFFONT "fixed" /* xft example: "Monospace-11" */
43 typedef struct Item Item;
45 @@ -49,8 +51,8 @@ static const char *normbgcolor = "#ccccc
46 static const char *normfgcolor = "#000000";
47 static const char *selbgcolor = "#0066ff";
48 static const char *selfgcolor = "#ffffff";
49 -static unsigned long normcol[ColLast];
50 -static unsigned long selcol[ColLast];
51 +static ColorSet *normcol;
52 +static ColorSet *selcol;
54 static Bool topbar = True;
56 @@ -99,7 +101,9 @@ main(int argc, char *argv[]) {
61 + initfont(dc, font ? font : DEFFONT);
62 + normcol = initcolor(dc, normfgcolor, normbgcolor);
63 + selcol = initcolor(dc, selfgcolor, selbgcolor);
67 @@ -151,7 +155,8 @@ drawmenu(void) {
71 - drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));
72 + drawrect(dc, 0, 0, mw, mh, True, normcol->BG);
77 @@ -161,7 +166,7 @@ drawmenu(void) {
78 dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
79 drawtext(dc, text, normcol);
80 if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
81 - drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));
82 + drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG);
86 @@ -495,11 +500,12 @@ setup(void) {
87 XineramaScreenInfo *info;
91 normcol[ColBG] = getcolor(dc, normbgcolor);
92 normcol[ColFG] = getcolor(dc, normfgcolor);
93 selcol[ColBG] = getcolor(dc, selbgcolor);
94 selcol[ColFG] = getcolor(dc, selfgcolor);
97 utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False);
100 Only in dmenu-4.3.1: dmenu_path
101 Only in dmenu-4.3.1: dmenu_run
102 diff -rup dmenu-4.3.1/draw.c dmenu-xft/draw.c
103 --- dmenu-4.3.1/draw.c 2011-05-18 21:32:16.000000000 +0530
104 +++ dmenu-xft/draw.c 2011-05-20 03:16:36.000000000 +0530
108 #include <X11/Xlib.h>
109 +#include <X11/Xft/Xft.h>
112 #define MAX(a, b) ((a) > (b) ? (a) : (b))
113 #define MIN(a, b) ((a) < (b) ? (a) : (b))
114 -#define DEFAULTFN "fixed"
116 -static Bool loadfont(DC *dc, const char *fontstr);
119 drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) {
120 @@ -23,7 +21,7 @@ drawrect(DC *dc, int x, int y, unsigned
124 -drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
125 +drawtext(DC *dc, const char *text, ColorSet *col) {
127 size_t mn, n = strlen(text);
129 @@ -35,19 +33,25 @@ drawtext(DC *dc, const char *text, unsig
131 for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
133 - drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
134 +drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG);
136 drawtextn(dc, buf, mn, col);
140 -drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) {
141 +drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) {
142 int x = dc->x + dc->font.height/2;
143 int y = dc->y + dc->font.ascent+1;
145 - XSetForeground(dc->dpy, dc->gc, FG(dc, col));
147 - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
149 + XSetForeground(dc->dpy, dc->gc, col->FG);
150 + if(dc->font.xft_font) {
152 + eprintf("error, xft drawable does not exist");
153 + XftDrawStringUtf8(dc->xftdraw, &col->FG_xft,
154 + dc->font.xft_font, x, y, (unsigned char*)text, n);
155 + } else if(dc->font.set) {
156 + XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
158 XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
159 XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
161 @@ -68,19 +72,53 @@ eprintf(const char *fmt, ...) {
166 +freecol(DC *dc, ColorSet *col) {
169 + XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
170 + DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft);
178 + if(dc->font.xft_font) {
179 + XftFontClose(dc->dpy, dc->font.xft_font);
180 + XftDrawDestroy(dc->xftdraw);
183 XFreeFontSet(dc->dpy, dc->font.set);
185 XFreeFont(dc->dpy, dc->font.xfont);
187 XFreePixmap(dc->dpy, dc->canvas);
188 - XFreeGC(dc->dpy, dc->gc);
189 - XCloseDisplay(dc->dpy);
192 + XFreeGC(dc->dpy, dc->gc);
194 + XCloseDisplay(dc->dpy);
201 +initcolor(DC *dc, const char * foreground, const char * background) {
202 + ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet));
204 + eprintf("error, cannot allocate memory for color set");
205 + col->BG = getcolor(dc, background);
206 + col->FG = getcolor(dc, foreground);
207 + if(dc->font.xft_font)
208 + if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
209 + DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft))
210 + eprintf("error, cannot allocate xft font color '%s'\n", foreground);
216 getcolor(DC *dc, const char *colstr) {
217 Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy));
218 @@ -95,12 +133,16 @@ DC *
222 - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
223 + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
224 fprintf(stderr, "no locale support\n");
225 if(!(dc = calloc(1, sizeof *dc)))
226 eprintf("cannot malloc %u bytes:", sizeof *dc);
227 if(!(dc->dpy = XOpenDisplay(NULL)))
228 eprintf("cannot open display\n");
229 + dc->font.xft_font = NULL;
230 + dc->xftdraw = NULL;
234 dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL);
235 XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter);
236 @@ -109,23 +151,13 @@ initdc(void) {
239 initfont(DC *dc, const char *fontstr) {
240 - if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) {
241 - if(fontstr != NULL)
242 - fprintf(stderr, "cannot load font '%s'\n", fontstr);
243 - if(fontstr == NULL || !loadfont(dc, DEFAULTFN))
244 - eprintf("cannot load font '%s'\n", DEFAULTFN);
246 - dc->font.height = dc->font.ascent + dc->font.descent;
250 -loadfont(DC *dc, const char *fontstr) {
251 - char *def, **missing;
252 + char *def, **missing=NULL;
257 - if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
258 + if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
259 + dc->font.ascent = dc->font.xfont->ascent;
260 + dc->font.descent = dc->font.xfont->descent;
261 + } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
263 XFontStruct **xfonts;
265 @@ -134,14 +166,16 @@ loadfont(DC *dc, const char *fontstr) {
266 dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent);
267 dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
270 - else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
271 - dc->font.ascent = dc->font.xfont->ascent;
272 - dc->font.descent = dc->font.xfont->descent;
274 + } else if((dc->font.xft_font = XftFontOpenName(dc->dpy,
275 + DefaultScreen(dc->dpy), fontstr))) {
276 + dc->font.ascent = dc->font.xft_font->ascent;
277 + dc->font.descent = dc->font.xft_font->descent;
279 + eprintf("cannot load font '%s'\n", fontstr);
282 XFreeStringList(missing);
283 - return (dc->font.set || dc->font.xfont);
284 + dc->font.height = dc->font.ascent + dc->font.descent;
288 @@ -151,6 +185,7 @@ mapdc(DC *dc, Window win, unsigned int w
291 resizedc(DC *dc, unsigned int w, unsigned int h) {
292 + int screen = DefaultScreen(dc->dpy);
294 XFreePixmap(dc->dpy, dc->canvas);
296 @@ -158,18 +193,30 @@ resizedc(DC *dc, unsigned int w, unsigne
297 DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
300 + if(dc->font.xft_font && !(dc->xftdraw)) {
301 + dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen));
303 + eprintf("error, cannot create xft drawable\n");
309 textnw(DC *dc, const char *text, size_t len) {
311 + if(dc->font.xft_font) {
313 + XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi);
315 + } else if(dc->font.set) {
318 XmbTextExtents(dc->font.set, text, len, NULL, &r);
321 - return XTextWidth(dc->font.xfont, text, len);
324 + return XTextWidth(dc->font.xfont, text, len);
330 textw(DC *dc, const char *text) {
331 diff -rup dmenu-4.3.1/draw.h dmenu-xft/draw.h
332 --- dmenu-4.3.1/draw.h 2011-05-18 21:32:16.000000000 +0530
333 +++ dmenu-xft/draw.h 2011-05-20 03:01:58.000000000 +0530
335 /* See LICENSE file for copyright and license details. */
337 -#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG])
338 -#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG])
340 -enum { ColBG, ColFG, ColBorder, ColLast };
341 +#include <X11/Xft/Xft.h>
358 } DC; /* draw context */
367 void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color);
368 -void drawtext(DC *dc, const char *text, unsigned long col[ColLast]);
369 -void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]);
370 +void drawtext(DC *dc, const char *text, ColorSet *col);
371 +void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col);
372 +void freecol(DC *dc, ColorSet *col);
373 void eprintf(const char *fmt, ...);
375 unsigned long getcolor(DC *dc, const char *colstr);
376 @@ -32,3 +38,5 @@ void mapdc(DC *dc, Window win, unsigned
377 void resizedc(DC *dc, unsigned int w, unsigned int h);
378 int textnw(DC *dc, const char *text, size_t len);
379 int textw(DC *dc, const char *text);
380 +ColorSet *initcolor(DC *dc, const char *foreground, const char *background);