Gentoo Archives: gentoo-commits

From: "Jeroen Roovers (jer)" <jer@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in x11-misc/dmenu/files: dmenu-4.5-xft.patch
Date: Wed, 08 Feb 2012 01:08:47
Message-Id: 20120208010837.29C7A2004C@flycatcher.gentoo.org
1 jer 12/02/08 01:08:37
2
3 Added: dmenu-4.5-xft.patch
4 Log:
5 Add XFT (x11-libs/libXft) support.
6
7 (Portage version: 2.2.0_alpha85/cvs/Linux x86_64)
8
9 Revision Changes Path
10 1.1 x11-misc/dmenu/files/dmenu-4.5-xft.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft.patch?rev=1.1&content-type=text/plain
14
15 Index: dmenu-4.5-xft.patch
16 ===================================================================
17 http://tools.suckless.org/dmenu/patches/xft
18 Adapted to use pkg-config instead of hard-coding libs and cflags
19
20 diff -upr a/config.mk b/config.mk
21 --- a/config.mk 2012-01-10 19:03:22.000000000 +0200
22 +++ b/config.mk 2012-01-10 19:03:38.000000000 +0200
23 @@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib
24 XINERAMALIBS = -lXinerama
25 XINERAMAFLAGS = -DXINERAMA
26
27 +# Xft, comment if you don't want it
28 +XFTINC = $(shell pkg-config --cflags xft)
29 +XFTLIBS = $(shell pkg-config --libs xft)
30 +
31 # includes and libs
32 -INCS = -I${X11INC}
33 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
34 +INCS = -I${X11INC} ${XFTINC}
35 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS}
36
37 # flags
38 CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
39 diff -upr a/dmenu.1 b/dmenu.1
40 --- a/dmenu.1 2012-01-10 19:14:19.000000000 +0200
41 +++ b/dmenu.1 2012-01-10 19:14:23.000000000 +0200
42 @@ -53,7 +53,7 @@ dmenu lists items vertically, with the g
43 defines the prompt to be displayed to the left of the input field.
44 .TP
45 .BI \-fn " font"
46 -defines the font or font set used.
47 +defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font)
48 .TP
49 .BI \-nb " color"
50 defines the normal background color.
51 diff -upr a/dmenu.c b/dmenu.c
52 --- a/dmenu.c 2012-01-10 19:14:19.000000000 +0200
53 +++ b/dmenu.c 2012-01-10 19:24:39.000000000 +0200
54 @@ -17,6 +17,7 @@
55 * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
56 #define MIN(a,b) ((a) < (b) ? (a) : (b))
57 #define MAX(a,b) ((a) > (b) ? (a) : (b))
58 +#define DEFFONT "fixed" /* xft example: "Monospace-11" */
59
60 typedef struct Item Item;
61 struct Item {
62 @@ -26,6 +27,7 @@ struct Item {
63
64 static void appenditem(Item *item, Item **list, Item **last);
65 static void calcoffsets(void);
66 +static void cleanup(void);
67 static char *cistrstr(const char *s, const char *sub);
68 static void drawmenu(void);
69 static void grabkeyboard(void);
70 @@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb
71 static const char *selbgcolor = "#005577";
72 static const char *selfgcolor = "#eeeeee";
73 static unsigned int lines = 0;
74 -static unsigned long normcol[ColLast];
75 -static unsigned long selcol[ColLast];
76 +static ColorSet *normcol;
77 +static ColorSet *selcol;
78 static Atom clip, utf8;
79 static Bool topbar = True;
80 +static Bool running = True;
81 +static int ret = 0;
82 static DC *dc;
83 static Item *items = NULL;
84 static Item *matches, *matchend;
85 @@ -104,7 +108,9 @@ main(int argc, char *argv[]) {
86 usage();
87
88 dc = initdc();
89 - initfont(dc, font);
90 + initfont(dc, font ? font : DEFFONT);
91 + normcol = initcolor(dc, normfgcolor, normbgcolor);
92 + selcol = initcolor(dc, selfgcolor, selbgcolor);
93
94 if(fast) {
95 grabkeyboard();
96 @@ -117,7 +123,8 @@ main(int argc, char *argv[]) {
97 setup();
98 run();
99
100 - return 1; /* unreachable */
101 + cleanup();
102 + return ret;
103 }
104
105 void
106 @@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub)
107 }
108
109 void
110 +cleanup(void) {
111 + freecol(dc, normcol);
112 + freecol(dc, selcol);
113 + XDestroyWindow(dc->dpy, win);
114 + XUngrabKeyboard(dc->dpy, CurrentTime);
115 + freedc(dc);
116 +}
117 +
118 +void
119 drawmenu(void) {
120 int curpos;
121 Item *item;
122 @@ -167,7 +183,7 @@ drawmenu(void) {
123 dc->x = 0;
124 dc->y = 0;
125 dc->h = bh;
126 - drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));
127 + drawrect(dc, 0, 0, mw, mh, True, normcol->BG);
128
129 if(prompt) {
130 dc->w = promptw;
131 @@ -178,7 +194,7 @@ drawmenu(void) {
132 dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
133 drawtext(dc, text, normcol);
134 if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
135 - drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));
136 + drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG);
137
138 if(lines > 0) {
139 /* draw vertical list */
140 @@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) {
141 sel = matchend;
142 break;
143 case XK_Escape:
144 - exit(EXIT_FAILURE);
145 + ret = EXIT_FAILURE;
146 + running = False;
147 case XK_Home:
148 if(sel == matches) {
149 cursor = 0;
150 @@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) {
151 case XK_Return:
152 case XK_KP_Enter:
153 puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
154 - exit(EXIT_SUCCESS);
155 + ret = EXIT_SUCCESS;
156 + running = False;
157 case XK_Right:
158 if(text[cursor] != '\0') {
159 cursor = nextrune(+1);
160 @@ -490,7 +508,7 @@ void
161 run(void) {
162 XEvent ev;
163
164 - while(!XNextEvent(dc->dpy, &ev)) {
165 + while(running && !XNextEvent(dc->dpy, &ev)) {
166 if(XFilterEvent(&ev, win))
167 continue;
168 switch(ev.type) {
169 @@ -524,11 +542,6 @@ setup(void) {
170 XineramaScreenInfo *info;
171 #endif
172
173 - normcol[ColBG] = getcolor(dc, normbgcolor);
174 - normcol[ColFG] = getcolor(dc, normfgcolor);
175 - selcol[ColBG] = getcolor(dc, selbgcolor);
176 - selcol[ColFG] = getcolor(dc, selfgcolor);
177 -
178 clip = XInternAtom(dc->dpy, "CLIPBOARD", False);
179 utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False);
180
181 @@ -582,7 +595,7 @@ setup(void) {
182
183 /* create menu window */
184 swa.override_redirect = True;
185 - swa.background_pixel = normcol[ColBG];
186 + swa.background_pixel = normcol->BG;
187 swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
188 win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0,
189 DefaultDepth(dc->dpy, screen), CopyFromParent,
190 diff -upr a/draw.c b/draw.c
191 --- a/draw.c 2012-01-10 19:14:19.000000000 +0200
192 +++ b/draw.c 2012-01-10 19:14:23.000000000 +0200
193 @@ -9,9 +9,6 @@
194
195 #define MAX(a, b) ((a) > (b) ? (a) : (b))
196 #define MIN(a, b) ((a) < (b) ? (a) : (b))
197 -#define DEFAULTFN "fixed"
198 -
199 -static Bool loadfont(DC *dc, const char *fontstr);
200
201 void
202 drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) {
203 @@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned
204 }
205
206 void
207 -drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
208 +drawtext(DC *dc, const char *text, ColorSet *col) {
209 char buf[BUFSIZ];
210 size_t mn, n = strlen(text);
211
212 @@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig
213 if(mn < n)
214 for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
215
216 - drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
217 + drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG);
218 drawtextn(dc, buf, mn, col);
219 }
220
221 void
222 -drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) {
223 +drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) {
224 int x = dc->x + dc->font.height/2;
225 int y = dc->y + dc->font.ascent+1;
226
227 - XSetForeground(dc->dpy, dc->gc, FG(dc, col));
228 - if(dc->font.set)
229 + XSetForeground(dc->dpy, dc->gc, col->FG);
230 + if(dc->font.xft_font) {
231 + if (!dc->xftdraw)
232 + eprintf("error, xft drawable does not exist");
233 + XftDrawStringUtf8(dc->xftdraw, &col->FG_xft,
234 + dc->font.xft_font, x, y, (unsigned char*)text, n);
235 + } else if(dc->font.set) {
236 XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
237 - else {
238 + } else {
239 XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
240 XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
241 }
242 @@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) {
243 }
244
245 void
246 +freecol(DC *dc, ColorSet *col) {
247 + if(col) {
248 + if(&col->FG_xft)
249 + XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
250 + DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft);
251 + free(col);
252 + }
253 +}
254 +
255 +void
256 freedc(DC *dc) {
257 + if(dc->font.xft_font) {
258 + XftFontClose(dc->dpy, dc->font.xft_font);
259 + XftDrawDestroy(dc->xftdraw);
260 + }
261 if(dc->font.set)
262 XFreeFontSet(dc->dpy, dc->font.set);
263 - if(dc->font.xfont)
264 + if(dc->font.xfont)
265 XFreeFont(dc->dpy, dc->font.xfont);
266 - if(dc->canvas)
267 + if(dc->canvas)
268 XFreePixmap(dc->dpy, dc->canvas);
269 - XFreeGC(dc->dpy, dc->gc);
270 - XCloseDisplay(dc->dpy);
271 - free(dc);
272 + if(dc->gc)
273 + XFreeGC(dc->dpy, dc->gc);
274 + if(dc->dpy)
275 + XCloseDisplay(dc->dpy);
276 + if(dc)
277 + free(dc);
278 }
279
280 unsigned long
281 @@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) {
282 return color.pixel;
283 }
284
285 +ColorSet *
286 +initcolor(DC *dc, const char * foreground, const char * background) {
287 + ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet));
288 + if(!col)
289 + eprintf("error, cannot allocate memory for color set");
290 + col->BG = getcolor(dc, background);
291 + col->FG = getcolor(dc, foreground);
292 + if(dc->font.xft_font)
293 + if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
294 + DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft))
295 + eprintf("error, cannot allocate xft font color '%s'\n", foreground);
296 + return col;
297 +}
298 +
299 DC *
300 initdc(void) {
301 DC *dc;
302 @@ -109,39 +142,33 @@ initdc(void) {
303
304 void
305 initfont(DC *dc, const char *fontstr) {
306 - if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) {
307 - if(fontstr != NULL)
308 - fprintf(stderr, "cannot load font '%s'\n", fontstr);
309 - if(fontstr == NULL || !loadfont(dc, DEFAULTFN))
310 - eprintf("cannot load font '%s'\n", DEFAULTFN);
311 - }
312 - dc->font.height = dc->font.ascent + dc->font.descent;
313 -}
314 -
315 -Bool
316 -loadfont(DC *dc, const char *fontstr) {
317 char *def, **missing, **names;
318 int i, n;
319 XFontStruct **xfonts;
320
321 - if(!*fontstr)
322 - return False;
323 - if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
324 + missing = NULL;
325 + if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
326 + dc->font.ascent = dc->font.xfont->ascent;
327 + dc->font.descent = dc->font.xfont->descent;
328 + dc->font.width = dc->font.xfont->max_bounds.width;
329 + } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
330 n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
331 for(i = 0; i < n; i++) {
332 dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent);
333 dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
334 dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width);
335 }
336 - }
337 - else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
338 - dc->font.ascent = dc->font.xfont->ascent;
339 - dc->font.descent = dc->font.xfont->descent;
340 - dc->font.width = dc->font.xfont->max_bounds.width;
341 + } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) {
342 + dc->font.ascent = dc->font.xft_font->ascent;
343 + dc->font.descent = dc->font.xft_font->descent;
344 + dc->font.width = dc->font.xft_font->max_advance_width;
345 + } else {
346 + eprintf("cannot load font '%s'\n", fontstr);
347 }
348 if(missing)
349 XFreeStringList(missing);
350 - return dc->font.set || dc->font.xfont;
351 + dc->font.height = dc->font.ascent + dc->font.descent;
352 + return;
353 }
354
355 void
356 @@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w
357
358 void
359 resizedc(DC *dc, unsigned int w, unsigned int h) {
360 + int screen = DefaultScreen(dc->dpy);
361 if(dc->canvas)
362 XFreePixmap(dc->dpy, dc->canvas);
363
364 dc->w = w;
365 dc->h = h;
366 dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
367 - DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
368 + DefaultDepth(dc->dpy, screen));
369 + if(dc->font.xft_font && !(dc->xftdraw)) {
370 + dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen));
371 + if(!(dc->xftdraw))
372 + eprintf("error, cannot create xft drawable\n");
373 + }
374 }
375
376 int
377 textnw(DC *dc, const char *text, size_t len) {
378 - if(dc->font.set) {
379 + if(dc->font.xft_font) {
380 + XGlyphInfo gi;
381 + XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi);
382 + return gi.width;
383 + } else if(dc->font.set) {
384 XRectangle r;
385 -
386 XmbTextExtents(dc->font.set, text, len, NULL, &r);
387 return r.width;
388 }
389 diff -upr a/draw.h b/draw.h
390 --- a/draw.h 2012-01-10 19:14:19.000000000 +0200
391 +++ b/draw.h 2012-01-10 19:14:23.000000000 +0200
392 @@ -1,9 +1,6 @@
393 /* See LICENSE file for copyright and license details. */
394
395 -#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG])
396 -#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG])
397 -
398 -enum { ColBG, ColFG, ColBorder, ColLast };
399 +#include <X11/Xft/Xft.h>
400
401 typedef struct {
402 int x, y, w, h;
403 @@ -11,6 +8,7 @@ typedef struct {
404 Display *dpy;
405 GC gc;
406 Pixmap canvas;
407 + XftDraw *xftdraw;
408 struct {
409 int ascent;
410 int descent;
411 @@ -18,15 +16,24 @@ typedef struct {
412 int width;
413 XFontSet set;
414 XFontStruct *xfont;
415 + XftFont *xft_font;
416 } font;
417 } DC; /* draw context */
418
419 +typedef struct {
420 + unsigned long FG;
421 + XftColor FG_xft;
422 + unsigned long BG;
423 +} ColorSet;
424 +
425 void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color);
426 -void drawtext(DC *dc, const char *text, unsigned long col[ColLast]);
427 -void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]);
428 +void drawtext(DC *dc, const char *text, ColorSet *col);
429 +void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col);
430 +void freecol(DC *dc, ColorSet *col);
431 void eprintf(const char *fmt, ...);
432 void freedc(DC *dc);
433 unsigned long getcolor(DC *dc, const char *colstr);
434 +ColorSet *initcolor(DC *dc, const char *foreground, const char *background);
435 DC *initdc(void);
436 void initfont(DC *dc, const char *fontstr);
437 void mapdc(DC *dc, Window win, unsigned int w, unsigned int h);