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