1 |
jer 14/01/22 14:46:23 |
2 |
|
3 |
Modified: dmenu-4.5-xft-2.patch |
4 |
Added: dmenu-4.5-xft-3.patch |
5 |
Log: |
6 |
Clean up patch. Revision bump for a slightly different patch by Hans-Peter Deifel (bug #498924). |
7 |
|
8 |
(Portage version: 2.2.8-r1/cvs/Linux x86_64, signed Manifest commit with key A792A613) |
9 |
|
10 |
Revision Changes Path |
11 |
1.2 x11-misc/dmenu/files/dmenu-4.5-xft-2.patch |
12 |
|
13 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-2.patch?rev=1.2&view=markup |
14 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-2.patch?rev=1.2&content-type=text/plain |
15 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-2.patch?r1=1.1&r2=1.2 |
16 |
|
17 |
Index: dmenu-4.5-xft-2.patch |
18 |
=================================================================== |
19 |
RCS file: /var/cvsroot/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-2.patch,v |
20 |
retrieving revision 1.1 |
21 |
retrieving revision 1.2 |
22 |
diff -u -r1.1 -r1.2 |
23 |
--- dmenu-4.5-xft-2.patch 23 May 2013 03:31:13 -0000 1.1 |
24 |
+++ dmenu-4.5-xft-2.patch 22 Jan 2014 14:46:23 -0000 1.2 |
25 |
@@ -1,6 +1,6 @@ |
26 |
---- a/dmenu-4.5/config.mk 2012-01-08 12:18:43.000000000 +0000 |
27 |
-+++ b/dmenu-4.5/config.mk 2013-05-17 10:47:11.964786792 +0100 |
28 |
-@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib |
29 |
+--- a/config.mk |
30 |
++++ b/config.mk |
31 |
+@@ -12,9 +12,13 @@ |
32 |
XINERAMALIBS = -lXinerama |
33 |
XINERAMAFLAGS = -DXINERAMA |
34 |
|
35 |
@@ -16,9 +16,9 @@ |
36 |
|
37 |
# flags |
38 |
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} |
39 |
---- a/dmenu-4.5/dmenu.1 2012-01-08 12:18:43.000000000 +0000 |
40 |
-+++ b/dmenu-4.5/dmenu.1 2013-05-17 10:47:11.964786792 +0100 |
41 |
-@@ -53,7 +53,7 @@ dmenu lists items vertically, with the g |
42 |
+--- a/dmenu.1 |
43 |
++++ b/dmenu.1 |
44 |
+@@ -53,7 +53,7 @@ |
45 |
defines the prompt to be displayed to the left of the input field. |
46 |
.TP |
47 |
.BI \-fn " font" |
48 |
@@ -27,8 +27,8 @@ |
49 |
.TP |
50 |
.BI \-nb " color" |
51 |
defines the normal background color. |
52 |
---- a/dmenu-4.5/dmenu.c 2012-01-08 12:18:43.000000000 +0000 |
53 |
-+++ b/dmenu-4.5/dmenu.c 2013-05-17 10:47:11.964786792 +0100 |
54 |
+--- a/dmenu.c |
55 |
++++ b/dmenu.c |
56 |
@@ -17,6 +17,7 @@ |
57 |
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) |
58 |
#define MIN(a,b) ((a) < (b) ? (a) : (b)) |
59 |
@@ -37,7 +37,7 @@ |
60 |
|
61 |
typedef struct Item Item; |
62 |
struct Item { |
63 |
-@@ -26,6 +27,7 @@ struct Item { |
64 |
+@@ -26,6 +27,7 @@ |
65 |
|
66 |
static void appenditem(Item *item, Item **list, Item **last); |
67 |
static void calcoffsets(void); |
68 |
@@ -45,7 +45,7 @@ |
69 |
static char *cistrstr(const char *s, const char *sub); |
70 |
static void drawmenu(void); |
71 |
static void grabkeyboard(void); |
72 |
-@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb |
73 |
+@@ -50,10 +52,12 @@ |
74 |
static const char *selbgcolor = "#005577"; |
75 |
static const char *selfgcolor = "#eeeeee"; |
76 |
static unsigned int lines = 0; |
77 |
@@ -60,7 +60,7 @@ |
78 |
static DC *dc; |
79 |
static Item *items = NULL; |
80 |
static Item *matches, *matchend; |
81 |
-@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { |
82 |
+@@ -104,7 +108,9 @@ |
83 |
usage(); |
84 |
|
85 |
dc = initdc(); |
86 |
@@ -71,7 +71,7 @@ |
87 |
|
88 |
if(fast) { |
89 |
grabkeyboard(); |
90 |
-@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { |
91 |
+@@ -117,7 +123,8 @@ |
92 |
setup(); |
93 |
run(); |
94 |
|
95 |
@@ -81,7 +81,7 @@ |
96 |
} |
97 |
|
98 |
void |
99 |
-@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) |
100 |
+@@ -160,6 +167,15 @@ |
101 |
} |
102 |
|
103 |
void |
104 |
@@ -97,7 +97,7 @@ |
105 |
drawmenu(void) { |
106 |
int curpos; |
107 |
Item *item; |
108 |
-@@ -167,7 +183,7 @@ drawmenu(void) { |
109 |
+@@ -167,7 +183,7 @@ |
110 |
dc->x = 0; |
111 |
dc->y = 0; |
112 |
dc->h = bh; |
113 |
@@ -106,7 +106,7 @@ |
114 |
|
115 |
if(prompt) { |
116 |
dc->w = promptw; |
117 |
-@@ -178,7 +194,7 @@ drawmenu(void) { |
118 |
+@@ -178,7 +194,7 @@ |
119 |
dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; |
120 |
drawtext(dc, text, normcol); |
121 |
if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) |
122 |
@@ -115,7 +115,7 @@ |
123 |
|
124 |
if(lines > 0) { |
125 |
/* draw vertical list */ |
126 |
-@@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) { |
127 |
+@@ -321,7 +337,8 @@ |
128 |
sel = matchend; |
129 |
break; |
130 |
case XK_Escape: |
131 |
@@ -125,7 +125,7 @@ |
132 |
case XK_Home: |
133 |
if(sel == matches) { |
134 |
cursor = 0; |
135 |
-@@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { |
136 |
+@@ -359,7 +376,8 @@ |
137 |
case XK_Return: |
138 |
case XK_KP_Enter: |
139 |
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); |
140 |
@@ -135,7 +135,7 @@ |
141 |
case XK_Right: |
142 |
if(text[cursor] != '\0') { |
143 |
cursor = nextrune(+1); |
144 |
-@@ -490,7 +508,7 @@ void |
145 |
+@@ -490,7 +508,7 @@ |
146 |
run(void) { |
147 |
XEvent ev; |
148 |
|
149 |
@@ -144,7 +144,7 @@ |
150 |
if(XFilterEvent(&ev, win)) |
151 |
continue; |
152 |
switch(ev.type) { |
153 |
-@@ -524,11 +542,6 @@ setup(void) { |
154 |
+@@ -524,11 +542,6 @@ |
155 |
XineramaScreenInfo *info; |
156 |
#endif |
157 |
|
158 |
@@ -156,7 +156,7 @@ |
159 |
clip = XInternAtom(dc->dpy, "CLIPBOARD", False); |
160 |
utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); |
161 |
|
162 |
-@@ -582,7 +595,7 @@ setup(void) { |
163 |
+@@ -582,7 +595,7 @@ |
164 |
|
165 |
/* create menu window */ |
166 |
swa.override_redirect = True; |
167 |
@@ -165,8 +165,8 @@ |
168 |
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; |
169 |
win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, |
170 |
DefaultDepth(dc->dpy, screen), CopyFromParent, |
171 |
---- a/dmenu-4.5/draw.c 2012-01-08 12:18:43.000000000 +0000 |
172 |
-+++ b/dmenu-4.5/draw.c 2013-05-17 10:47:54.491105887 +0100 |
173 |
+--- a/draw.c |
174 |
++++ b/draw.c |
175 |
@@ -9,9 +9,6 @@ |
176 |
|
177 |
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
178 |
@@ -177,7 +177,7 @@ |
179 |
|
180 |
void |
181 |
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { |
182 |
-@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned |
183 |
+@@ -23,7 +20,7 @@ |
184 |
} |
185 |
|
186 |
void |
187 |
@@ -186,7 +186,7 @@ |
188 |
char buf[BUFSIZ]; |
189 |
size_t mn, n = strlen(text); |
190 |
|
191 |
-@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig |
192 |
+@@ -35,19 +32,24 @@ |
193 |
if(mn < n) |
194 |
for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); |
195 |
|
196 |
@@ -216,7 +216,7 @@ |
197 |
XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); |
198 |
XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); |
199 |
} |
200 |
-@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { |
201 |
+@@ -69,16 +71,33 @@ |
202 |
} |
203 |
|
204 |
void |
205 |
@@ -255,7 +255,7 @@ |
206 |
} |
207 |
|
208 |
unsigned long |
209 |
-@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { |
210 |
+@@ -91,6 +110,20 @@ |
211 |
return color.pixel; |
212 |
} |
213 |
|
214 |
@@ -276,7 +276,7 @@ |
215 |
DC * |
216 |
initdc(void) { |
217 |
DC *dc; |
218 |
-@@ -109,23 +142,11 @@ initdc(void) { |
219 |
+@@ -109,23 +142,11 @@ |
220 |
|
221 |
void |
222 |
initfont(DC *dc, const char *fontstr) { |
223 |
@@ -301,7 +301,7 @@ |
224 |
if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { |
225 |
n = XFontsOfFontSet(dc->font.set, &xfonts, &names); |
226 |
for(i = 0; i < n; i++) { |
227 |
-@@ -133,15 +154,21 @@ loadfont(DC *dc, const char *fontstr) { |
228 |
+@@ -133,15 +154,21 @@ |
229 |
dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); |
230 |
dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); |
231 |
} |
232 |
@@ -327,7 +327,7 @@ |
233 |
} |
234 |
|
235 |
void |
236 |
-@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w |
237 |
+@@ -151,20 +178,29 @@ |
238 |
|
239 |
void |
240 |
resizedc(DC *dc, unsigned int w, unsigned int h) { |
241 |
@@ -360,8 +360,8 @@ |
242 |
XmbTextExtents(dc->font.set, text, len, NULL, &r); |
243 |
return r.width; |
244 |
} |
245 |
---- a/dmenu-4.5/draw.h 2012-01-08 12:18:43.000000000 +0000 |
246 |
-+++ b/dmenu-4.5/draw.h 2013-05-17 10:47:11.964786792 +0100 |
247 |
+--- a/draw.h |
248 |
++++ b/draw.h |
249 |
@@ -1,9 +1,6 @@ |
250 |
/* See LICENSE file for copyright and license details. */ |
251 |
|
252 |
@@ -373,7 +373,7 @@ |
253 |
|
254 |
typedef struct { |
255 |
int x, y, w, h; |
256 |
-@@ -11,6 +8,7 @@ typedef struct { |
257 |
+@@ -11,6 +8,7 @@ |
258 |
Display *dpy; |
259 |
GC gc; |
260 |
Pixmap canvas; |
261 |
@@ -381,7 +381,7 @@ |
262 |
struct { |
263 |
int ascent; |
264 |
int descent; |
265 |
-@@ -18,15 +16,24 @@ typedef struct { |
266 |
+@@ -18,15 +16,24 @@ |
267 |
int width; |
268 |
XFontSet set; |
269 |
XFontStruct *xfont; |
270 |
|
271 |
|
272 |
|
273 |
1.1 x11-misc/dmenu/files/dmenu-4.5-xft-3.patch |
274 |
|
275 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-3.patch?rev=1.1&view=markup |
276 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/dmenu/files/dmenu-4.5-xft-3.patch?rev=1.1&content-type=text/plain |
277 |
|
278 |
Index: dmenu-4.5-xft-3.patch |
279 |
=================================================================== |
280 |
--- a/config.mk |
281 |
+++ b/config.mk |
282 |
@@ -12,9 +12,13 @@ |
283 |
XINERAMALIBS = -lXinerama |
284 |
XINERAMAFLAGS = -DXINERAMA |
285 |
|
286 |
+# Xft, comment if you don't want it |
287 |
+XFTINC = $(shell pkg-config --cflags xft) |
288 |
+XFTLIBS = $(shell pkg-config --libs xft) |
289 |
+ |
290 |
# includes and libs |
291 |
-INCS = -I${X11INC} |
292 |
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} |
293 |
+INCS = -I${X11INC} ${XFTINC} |
294 |
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} |
295 |
|
296 |
# flags |
297 |
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} |
298 |
--- a/dmenu.1 |
299 |
+++ b/dmenu.1 |
300 |
@@ -53,7 +53,7 @@ |
301 |
defines the prompt to be displayed to the left of the input field. |
302 |
.TP |
303 |
.BI \-fn " font" |
304 |
-defines the font or font set used. |
305 |
+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) |
306 |
.TP |
307 |
.BI \-nb " color" |
308 |
defines the normal background color. |
309 |
--- a/dmenu.c |
310 |
+++ b/dmenu.c |
311 |
@@ -17,6 +17,7 @@ |
312 |
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) |
313 |
#define MIN(a,b) ((a) < (b) ? (a) : (b)) |
314 |
#define MAX(a,b) ((a) > (b) ? (a) : (b)) |
315 |
+#define DEFFONT "fixed" /* xft example: "Monospace-11" */ |
316 |
|
317 |
typedef struct Item Item; |
318 |
struct Item { |
319 |
@@ -26,6 +27,7 @@ |
320 |
|
321 |
static void appenditem(Item *item, Item **list, Item **last); |
322 |
static void calcoffsets(void); |
323 |
+static void cleanup(void); |
324 |
static char *cistrstr(const char *s, const char *sub); |
325 |
static void drawmenu(void); |
326 |
static void grabkeyboard(void); |
327 |
@@ -50,10 +52,12 @@ |
328 |
static const char *selbgcolor = "#005577"; |
329 |
static const char *selfgcolor = "#eeeeee"; |
330 |
static unsigned int lines = 0; |
331 |
-static unsigned long normcol[ColLast]; |
332 |
-static unsigned long selcol[ColLast]; |
333 |
+static ColorSet *normcol; |
334 |
+static ColorSet *selcol; |
335 |
static Atom clip, utf8; |
336 |
static Bool topbar = True; |
337 |
+static Bool running = True; |
338 |
+static int ret = 0; |
339 |
static DC *dc; |
340 |
static Item *items = NULL; |
341 |
static Item *matches, *matchend; |
342 |
@@ -104,7 +108,9 @@ |
343 |
usage(); |
344 |
|
345 |
dc = initdc(); |
346 |
- initfont(dc, font); |
347 |
+ initfont(dc, font ? font : DEFFONT); |
348 |
+ normcol = initcolor(dc, normfgcolor, normbgcolor); |
349 |
+ selcol = initcolor(dc, selfgcolor, selbgcolor); |
350 |
|
351 |
if(fast) { |
352 |
grabkeyboard(); |
353 |
@@ -117,7 +123,8 @@ |
354 |
setup(); |
355 |
run(); |
356 |
|
357 |
- return 1; /* unreachable */ |
358 |
+ cleanup(); |
359 |
+ return ret; |
360 |
} |
361 |
|
362 |
void |
363 |
@@ -160,6 +167,15 @@ |
364 |
} |
365 |
|
366 |
void |
367 |
+cleanup(void) { |
368 |
+ freecol(dc, normcol); |
369 |
+ freecol(dc, selcol); |
370 |
+ XDestroyWindow(dc->dpy, win); |
371 |
+ XUngrabKeyboard(dc->dpy, CurrentTime); |
372 |
+ freedc(dc); |
373 |
+} |
374 |
+ |
375 |
+void |
376 |
drawmenu(void) { |
377 |
int curpos; |
378 |
Item *item; |
379 |
@@ -167,7 +183,7 @@ |
380 |
dc->x = 0; |
381 |
dc->y = 0; |
382 |
dc->h = bh; |
383 |
- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); |
384 |
+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); |
385 |
|
386 |
if(prompt) { |
387 |
dc->w = promptw; |
388 |
@@ -178,7 +194,7 @@ |
389 |
dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; |
390 |
drawtext(dc, text, normcol); |
391 |
if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) |
392 |
- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); |
393 |
+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); |
394 |
|
395 |
if(lines > 0) { |
396 |
/* draw vertical list */ |
397 |
@@ -321,7 +337,9 @@ |
398 |
sel = matchend; |
399 |
break; |
400 |
case XK_Escape: |
401 |
- exit(EXIT_FAILURE); |
402 |
+ ret = EXIT_FAILURE; |
403 |
+ running = False; |
404 |
+ break; |
405 |
case XK_Home: |
406 |
if(sel == matches) { |
407 |
cursor = 0; |
408 |
@@ -359,7 +377,9 @@ |
409 |
case XK_Return: |
410 |
case XK_KP_Enter: |
411 |
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); |
412 |
- exit(EXIT_SUCCESS); |
413 |
+ ret = EXIT_SUCCESS; |
414 |
+ running = False; |
415 |
+ break; |
416 |
case XK_Right: |
417 |
if(text[cursor] != '\0') { |
418 |
cursor = nextrune(+1); |
419 |
@@ -490,7 +510,7 @@ |
420 |
run(void) { |
421 |
XEvent ev; |
422 |
|
423 |
- while(!XNextEvent(dc->dpy, &ev)) { |
424 |
+ while(running && !XNextEvent(dc->dpy, &ev)) { |
425 |
if(XFilterEvent(&ev, win)) |
426 |
continue; |
427 |
switch(ev.type) { |
428 |
@@ -524,11 +544,6 @@ |
429 |
XineramaScreenInfo *info; |
430 |
#endif |
431 |
|
432 |
- normcol[ColBG] = getcolor(dc, normbgcolor); |
433 |
- normcol[ColFG] = getcolor(dc, normfgcolor); |
434 |
- selcol[ColBG] = getcolor(dc, selbgcolor); |
435 |
- selcol[ColFG] = getcolor(dc, selfgcolor); |
436 |
- |
437 |
clip = XInternAtom(dc->dpy, "CLIPBOARD", False); |
438 |
utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); |
439 |
|
440 |
@@ -582,7 +597,7 @@ |
441 |
|
442 |
/* create menu window */ |
443 |
swa.override_redirect = True; |
444 |
- swa.background_pixel = normcol[ColBG]; |
445 |
+ swa.background_pixel = normcol->BG; |
446 |
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; |
447 |
win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, |
448 |
DefaultDepth(dc->dpy, screen), CopyFromParent, |
449 |
--- a/draw.c |
450 |
+++ b/draw.c |
451 |
@@ -9,9 +9,6 @@ |
452 |
|
453 |
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
454 |
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
455 |
-#define DEFAULTFN "fixed" |
456 |
- |
457 |
-static Bool loadfont(DC *dc, const char *fontstr); |
458 |
|
459 |
void |
460 |
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { |
461 |
@@ -23,7 +20,7 @@ |
462 |
} |
463 |
|
464 |
void |
465 |
-drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { |
466 |
+drawtext(DC *dc, const char *text, ColorSet *col) { |
467 |
char buf[BUFSIZ]; |
468 |
size_t mn, n = strlen(text); |
469 |
|
470 |
@@ -35,19 +32,24 @@ |
471 |
if(mn < n) |
472 |
for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); |
473 |
|
474 |
- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); |
475 |
+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); |
476 |
drawtextn(dc, buf, mn, col); |
477 |
} |
478 |
|
479 |
void |
480 |
-drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { |
481 |
+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { |
482 |
int x = dc->x + dc->font.height/2; |
483 |
int y = dc->y + dc->font.ascent+1; |
484 |
|
485 |
- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); |
486 |
- if(dc->font.set) |
487 |
+ XSetForeground(dc->dpy, dc->gc, col->FG); |
488 |
+ if(dc->font.xft_font) { |
489 |
+ if (!dc->xftdraw) |
490 |
+ eprintf("error, xft drawable does not exist"); |
491 |
+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, |
492 |
+ dc->font.xft_font, x, y, (unsigned char*)text, n); |
493 |
+ } else if(dc->font.set) { |
494 |
XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); |
495 |
- else { |
496 |
+ } else { |
497 |
XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); |
498 |
XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); |
499 |
} |
500 |
@@ -69,16 +71,33 @@ |
501 |
} |
502 |
|
503 |
void |
504 |
+freecol(DC *dc, ColorSet *col) { |
505 |
+ if(col) { |
506 |
+ if(&col->FG_xft) |
507 |
+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), |
508 |
+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); |
509 |
+ free(col); |
510 |
+ } |
511 |
+} |
512 |
+ |
513 |
+void |
514 |
freedc(DC *dc) { |
515 |
+ if(dc->font.xft_font) { |
516 |
+ XftFontClose(dc->dpy, dc->font.xft_font); |
517 |
+ XftDrawDestroy(dc->xftdraw); |
518 |
+ } |
519 |
if(dc->font.set) |
520 |
XFreeFontSet(dc->dpy, dc->font.set); |
521 |
- if(dc->font.xfont) |
522 |
+ if(dc->font.xfont) |
523 |
XFreeFont(dc->dpy, dc->font.xfont); |
524 |
- if(dc->canvas) |
525 |
+ if(dc->canvas) |
526 |
XFreePixmap(dc->dpy, dc->canvas); |
527 |
- XFreeGC(dc->dpy, dc->gc); |
528 |
- XCloseDisplay(dc->dpy); |
529 |
- free(dc); |
530 |
+ if(dc->gc) |
531 |
+ XFreeGC(dc->dpy, dc->gc); |
532 |
+ if(dc->dpy) |
533 |
+ XCloseDisplay(dc->dpy); |
534 |
+ if(dc) |
535 |
+ free(dc); |
536 |
} |
537 |
|
538 |
unsigned long |
539 |
@@ -91,6 +110,20 @@ |
540 |
return color.pixel; |
541 |
} |
542 |
|
543 |
+ColorSet * |
544 |
+initcolor(DC *dc, const char * foreground, const char * background) { |
545 |
+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); |
546 |
+ if(!col) |
547 |
+ eprintf("error, cannot allocate memory for color set"); |
548 |
+ col->BG = getcolor(dc, background); |
549 |
+ col->FG = getcolor(dc, foreground); |
550 |
+ if(dc->font.xft_font) |
551 |
+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), |
552 |
+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) |
553 |
+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); |
554 |
+ return col; |
555 |
+} |
556 |
+ |
557 |
DC * |
558 |
initdc(void) { |
559 |
DC *dc; |
560 |
@@ -109,23 +142,11 @@ |
561 |
|
562 |
void |
563 |
initfont(DC *dc, const char *fontstr) { |
564 |
- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { |
565 |
- if(fontstr != NULL) |
566 |
- fprintf(stderr, "cannot load font '%s'\n", fontstr); |
567 |
- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) |
568 |
- eprintf("cannot load font '%s'\n", DEFAULTFN); |
569 |
- } |
570 |
- dc->font.height = dc->font.ascent + dc->font.descent; |
571 |
-} |
572 |
- |
573 |
-Bool |
574 |
-loadfont(DC *dc, const char *fontstr) { |
575 |
char *def, **missing, **names; |
576 |
int i, n; |
577 |
XFontStruct **xfonts; |
578 |
|
579 |
- if(!*fontstr) |
580 |
- return False; |
581 |
+ missing = NULL; |
582 |
if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { |
583 |
n = XFontsOfFontSet(dc->font.set, &xfonts, &names); |
584 |
for(i = 0; i < n; i++) { |
585 |
@@ -133,15 +154,21 @@ |
586 |
dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); |
587 |
dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); |
588 |
} |
589 |
- } |
590 |
- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { |
591 |
- dc->font.ascent = dc->font.xfont->ascent; |
592 |
+ } else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { |
593 |
+ dc->font.ascent = dc->font.xfont->ascent; |
594 |
dc->font.descent = dc->font.xfont->descent; |
595 |
dc->font.width = dc->font.xfont->max_bounds.width; |
596 |
+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { |
597 |
+ dc->font.ascent = dc->font.xft_font->ascent; |
598 |
+ dc->font.descent = dc->font.xft_font->descent; |
599 |
+ dc->font.width = dc->font.xft_font->max_advance_width; |
600 |
+ } else { |
601 |
+ eprintf("cannot load font '%s'\n", fontstr); |
602 |
} |
603 |
if(missing) |
604 |
XFreeStringList(missing); |
605 |
- return dc->font.set || dc->font.xfont; |
606 |
+ dc->font.height = dc->font.ascent + dc->font.descent; |
607 |
+ return; |
608 |
} |
609 |
|
610 |
void |
611 |
@@ -151,20 +178,29 @@ |
612 |
|
613 |
void |
614 |
resizedc(DC *dc, unsigned int w, unsigned int h) { |
615 |
+ int screen = DefaultScreen(dc->dpy); |
616 |
if(dc->canvas) |
617 |
XFreePixmap(dc->dpy, dc->canvas); |
618 |
|
619 |
dc->w = w; |
620 |
dc->h = h; |
621 |
dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, |
622 |
- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); |
623 |
+ DefaultDepth(dc->dpy, screen)); |
624 |
+ if(dc->font.xft_font && !(dc->xftdraw)) { |
625 |
+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); |
626 |
+ if(!(dc->xftdraw)) |
627 |
+ eprintf("error, cannot create xft drawable\n"); |
628 |
+ } |
629 |
} |
630 |
|
631 |
int |
632 |
textnw(DC *dc, const char *text, size_t len) { |
633 |
- if(dc->font.set) { |
634 |
+ if(dc->font.xft_font) { |
635 |
+ XGlyphInfo gi; |
636 |
+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); |
637 |
+ return gi.width; |
638 |
+ } else if(dc->font.set) { |
639 |
XRectangle r; |
640 |
- |
641 |
XmbTextExtents(dc->font.set, text, len, NULL, &r); |
642 |
return r.width; |
643 |
} |
644 |
--- a/draw.h |
645 |
+++ b/draw.h |
646 |
@@ -1,9 +1,6 @@ |
647 |
/* See LICENSE file for copyright and license details. */ |
648 |
|
649 |
-#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) |
650 |
-#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) |
651 |
- |
652 |
-enum { ColBG, ColFG, ColBorder, ColLast }; |
653 |
+#include <X11/Xft/Xft.h> |
654 |
|
655 |
typedef struct { |
656 |
int x, y, w, h; |
657 |
@@ -11,6 +8,7 @@ |
658 |
Display *dpy; |
659 |
GC gc; |
660 |
Pixmap canvas; |
661 |
+ XftDraw *xftdraw; |
662 |
struct { |
663 |
int ascent; |
664 |
int descent; |
665 |
@@ -18,15 +16,24 @@ |
666 |
int width; |
667 |
XFontSet set; |
668 |
XFontStruct *xfont; |
669 |
+ XftFont *xft_font; |
670 |
} font; |
671 |
} DC; /* draw context */ |
672 |
|
673 |
+typedef struct { |
674 |
+ unsigned long FG; |
675 |
+ XftColor FG_xft; |
676 |
+ unsigned long BG; |
677 |
+} ColorSet; |
678 |
+ |
679 |
void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); |
680 |
-void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); |
681 |
-void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); |
682 |
+void drawtext(DC *dc, const char *text, ColorSet *col); |
683 |
+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); |
684 |
+void freecol(DC *dc, ColorSet *col); |
685 |
void eprintf(const char *fmt, ...); |
686 |
void freedc(DC *dc); |
687 |
unsigned long getcolor(DC *dc, const char *colstr); |
688 |
+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); |
689 |
DC *initdc(void); |
690 |
void initfont(DC *dc, const char *fontstr); |
691 |
void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); |