diff options
author | Connor Lane Smith <cls@lubutu.com> | 2010-06-24 16:18:18 +0100 |
---|---|---|
committer | Connor Lane Smith <cls@lubutu.com> | 2010-06-24 16:18:18 +0100 |
commit | 96c65400ccdcb76cf20ec7721920f944e6b490ec (patch) | |
tree | 07e5963037f9369cc97902036324111ac465fe34 | |
parent | 6c1d0e4d60b239e9533def6feaf8eb2138858c3e (diff) |
decoupled draw.c from dmenu & dinput
-rw-r--r-- | dinput.c | 40 | ||||
-rw-r--r-- | dmenu.c | 49 | ||||
-rw-r--r-- | draw.c | 109 | ||||
-rw-r--r-- | draw.h | 30 |
4 files changed, 111 insertions, 117 deletions
@@ -38,20 +38,18 @@ static char *prompt = NULL; | |||
38 | static char text[4096]; | 38 | static char text[4096]; |
39 | static int promptw = 0; | 39 | static int promptw = 0; |
40 | static int ret = 0; | 40 | static int ret = 0; |
41 | static int screen; | ||
41 | static unsigned int cursor = 0; | 42 | static unsigned int cursor = 0; |
42 | static unsigned int numlockmask = 0; | 43 | static unsigned int numlockmask = 0; |
44 | static unsigned int mw, mh; | ||
43 | static Bool running = True; | 45 | static Bool running = True; |
44 | static Window win; | 46 | static DC dc; |
45 | 47 | static Display *dpy; | |
46 | Display *dpy; | 48 | static Window win, parent; |
47 | DC dc; | ||
48 | int screen; | ||
49 | unsigned int mw, mh; | ||
50 | Window parent; | ||
51 | 49 | ||
52 | void | 50 | void |
53 | cleanup(void) { | 51 | cleanup(void) { |
54 | drawcleanup(); | 52 | cleanupdraw(&dc); |
55 | XDestroyWindow(dpy, win); | 53 | XDestroyWindow(dpy, win); |
56 | XUngrabKeyboard(dpy, CurrentTime); | 54 | XUngrabKeyboard(dpy, CurrentTime); |
57 | } | 55 | } |
@@ -60,7 +58,7 @@ void | |||
60 | drawcursor(void) { | 58 | drawcursor(void) { |
61 | XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; | 59 | XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; |
62 | 60 | ||
63 | r.x += textnw(text, cursor) + dc.font.height / 2; | 61 | r.x += textnw(&dc, text, cursor) + dc.font.height / 2; |
64 | 62 | ||
65 | XSetForeground(dpy, dc.gc, dc.norm[ColFG]); | 63 | XSetForeground(dpy, dc.gc, dc.norm[ColFG]); |
66 | XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); | 64 | XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); |
@@ -73,15 +71,15 @@ drawinput(void) | |||
73 | dc.y = 0; | 71 | dc.y = 0; |
74 | dc.w = mw; | 72 | dc.w = mw; |
75 | dc.h = mh; | 73 | dc.h = mh; |
76 | drawtext(NULL, dc.norm); | 74 | drawtext(&dc, NULL, dc.norm); |
77 | /* print prompt? */ | 75 | /* print prompt? */ |
78 | if(prompt) { | 76 | if(prompt) { |
79 | dc.w = promptw; | 77 | dc.w = promptw; |
80 | drawtext(prompt, dc.sel); | 78 | drawtext(&dc, prompt, dc.sel); |
81 | dc.x += dc.w; | 79 | dc.x += dc.w; |
82 | } | 80 | } |
83 | dc.w = mw - dc.x; | 81 | dc.w = mw - dc.x; |
84 | drawtext(*text ? text : NULL, dc.norm); | 82 | drawtext(&dc, *text ? text : NULL, dc.norm); |
85 | drawcursor(); | 83 | drawcursor(); |
86 | XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); | 84 | XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); |
87 | XFlush(dpy); | 85 | XFlush(dpy); |
@@ -269,15 +267,21 @@ setup(Bool topbar) { | |||
269 | } | 267 | } |
270 | XFreeModifiermap(modmap); | 268 | XFreeModifiermap(modmap); |
271 | 269 | ||
272 | initfont(font); | 270 | dc.dpy = dpy; |
271 | dc.norm[ColBG] = getcolor(&dc, normbgcolor); | ||
272 | dc.norm[ColFG] = getcolor(&dc, normfgcolor); | ||
273 | dc.sel[ColBG] = getcolor(&dc, selbgcolor); | ||
274 | dc.sel[ColFG] = getcolor(&dc, selfgcolor); | ||
275 | initfont(&dc, font); | ||
276 | fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); | ||
273 | 277 | ||
274 | /* menu window */ | 278 | /* input window */ |
275 | wa.override_redirect = True; | 279 | wa.override_redirect = True; |
276 | wa.background_pixmap = ParentRelative; | 280 | wa.background_pixmap = ParentRelative; |
277 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; | 281 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; |
278 | 282 | ||
279 | /* menu window geometry */ | 283 | /* input window geometry */ |
280 | mh = (dc.font.height + 2); | 284 | mh = dc.font.height + 2; |
281 | #if XINERAMA | 285 | #if XINERAMA |
282 | if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { | 286 | if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { |
283 | i = 0; | 287 | i = 0; |
@@ -309,9 +313,9 @@ setup(Bool topbar) { | |||
309 | DefaultVisual(dpy, screen), | 313 | DefaultVisual(dpy, screen), |
310 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | 314 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
311 | 315 | ||
312 | drawsetup(); | 316 | setupdraw(&dc, win); |
313 | if(prompt) | 317 | if(prompt) |
314 | promptw = MIN(textw(prompt), mw / 5); | 318 | promptw = MIN(textw(&dc, prompt), mw / 5); |
315 | cursor = strlen(text); | 319 | cursor = strlen(text); |
316 | XMapRaised(dpy, win); | 320 | XMapRaised(dpy, win); |
317 | } | 321 | } |
@@ -55,26 +55,24 @@ static char text[4096]; | |||
55 | static int cmdw = 0; | 55 | static int cmdw = 0; |
56 | static int promptw = 0; | 56 | static int promptw = 0; |
57 | static int ret = 0; | 57 | static int ret = 0; |
58 | static int screen; | ||
58 | static unsigned int lines = 0; | 59 | static unsigned int lines = 0; |
59 | static unsigned int numlockmask = 0; | 60 | static unsigned int numlockmask = 0; |
61 | static unsigned int mw, mh; | ||
60 | static Bool running = True; | 62 | static Bool running = True; |
63 | static DC dc; | ||
64 | static Display *dpy; | ||
61 | static Item *allitems = NULL; /* first of all items */ | 65 | static Item *allitems = NULL; /* first of all items */ |
62 | static Item *item = NULL; /* first of pattern matching items */ | 66 | static Item *item = NULL; /* first of pattern matching items */ |
63 | static Item *sel = NULL; | 67 | static Item *sel = NULL; |
64 | static Item *next = NULL; | 68 | static Item *next = NULL; |
65 | static Item *prev = NULL; | 69 | static Item *prev = NULL; |
66 | static Item *curr = NULL; | 70 | static Item *curr = NULL; |
67 | static Window win; | 71 | static Window win, parent; |
68 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | 72 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; |
69 | static char *(*fstrstr)(const char *, const char *) = strstr; | 73 | static char *(*fstrstr)(const char *, const char *) = strstr; |
70 | static void (*calcoffsets)(void) = calcoffsetsh; | 74 | static void (*calcoffsets)(void) = calcoffsetsh; |
71 | 75 | ||
72 | Display *dpy; | ||
73 | DC dc; | ||
74 | int screen; | ||
75 | unsigned int mw, mh; | ||
76 | Window parent; | ||
77 | |||
78 | void | 76 | void |
79 | appenditem(Item *i, Item **list, Item **last) { | 77 | appenditem(Item *i, Item **list, Item **last) { |
80 | if(!(*last)) | 78 | if(!(*last)) |
@@ -92,11 +90,11 @@ calcoffsetsh(void) { | |||
92 | 90 | ||
93 | w = promptw + cmdw + (2 * spaceitem); | 91 | w = promptw + cmdw + (2 * spaceitem); |
94 | for(next = curr; next; next = next->right) | 92 | for(next = curr; next; next = next->right) |
95 | if((w += MIN(textw(next->text), mw / 3)) > mw) | 93 | if((w += MIN(textw(&dc, next->text), mw / 3)) > mw) |
96 | break; | 94 | break; |
97 | w = promptw + cmdw + (2 * spaceitem); | 95 | w = promptw + cmdw + (2 * spaceitem); |
98 | for(prev = curr; prev && prev->left; prev = prev->left) | 96 | for(prev = curr; prev && prev->left; prev = prev->left) |
99 | if((w += MIN(textw(prev->left->text), mw / 3)) > mw) | 97 | if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) |
100 | break; | 98 | break; |
101 | } | 99 | } |
102 | 100 | ||
@@ -143,7 +141,7 @@ cleanup(void) { | |||
143 | free(allitems); | 141 | free(allitems); |
144 | allitems = itm; | 142 | allitems = itm; |
145 | } | 143 | } |
146 | drawcleanup(); | 144 | cleanupdraw(&dc); |
147 | XDestroyWindow(dpy, win); | 145 | XDestroyWindow(dpy, win); |
148 | XUngrabKeyboard(dpy, CurrentTime); | 146 | XUngrabKeyboard(dpy, CurrentTime); |
149 | } | 147 | } |
@@ -161,18 +159,18 @@ drawmenu(void) { | |||
161 | dc.y = 0; | 159 | dc.y = 0; |
162 | dc.w = mw; | 160 | dc.w = mw; |
163 | dc.h = mh; | 161 | dc.h = mh; |
164 | drawtext(NULL, dc.norm); | 162 | drawtext(&dc, NULL, dc.norm); |
165 | /* print prompt? */ | 163 | /* print prompt? */ |
166 | if(prompt) { | 164 | if(prompt) { |
167 | dc.w = promptw; | 165 | dc.w = promptw; |
168 | drawtext(prompt, dc.sel); | 166 | drawtext(&dc, prompt, dc.sel); |
169 | dc.x += dc.w; | 167 | dc.x += dc.w; |
170 | } | 168 | } |
171 | dc.w = mw - dc.x; | 169 | dc.w = mw - dc.x; |
172 | /* print command */ | 170 | /* print command */ |
173 | if(cmdw && item && lines == 0) | 171 | if(cmdw && item && lines == 0) |
174 | dc.w = cmdw; | 172 | dc.w = cmdw; |
175 | drawtext(*text ? text : NULL, dc.norm); | 173 | drawtext(&dc, *text ? text : NULL, dc.norm); |
176 | if(curr) { | 174 | if(curr) { |
177 | if(lines > 0) | 175 | if(lines > 0) |
178 | drawmenuv(); | 176 | drawmenuv(); |
@@ -189,16 +187,16 @@ drawmenuh(void) { | |||
189 | 187 | ||
190 | dc.x += cmdw; | 188 | dc.x += cmdw; |
191 | dc.w = spaceitem; | 189 | dc.w = spaceitem; |
192 | drawtext(curr->left ? "<" : NULL, dc.norm); | 190 | drawtext(&dc, curr->left ? "<" : NULL, dc.norm); |
193 | dc.x += dc.w; | 191 | dc.x += dc.w; |
194 | for(i = curr; i != next; i=i->right) { | 192 | for(i = curr; i != next; i=i->right) { |
195 | dc.w = MIN(textw(i->text), mw / 3); | 193 | dc.w = MIN(textw(&dc, i->text), mw / 3); |
196 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); | 194 | drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); |
197 | dc.x += dc.w; | 195 | dc.x += dc.w; |
198 | } | 196 | } |
199 | dc.w = spaceitem; | 197 | dc.w = spaceitem; |
200 | dc.x = mw - dc.w; | 198 | dc.x = mw - dc.w; |
201 | drawtext(next ? ">" : NULL, dc.norm); | 199 | drawtext(&dc, next ? ">" : NULL, dc.norm); |
202 | } | 200 | } |
203 | 201 | ||
204 | void | 202 | void |
@@ -209,11 +207,11 @@ drawmenuv(void) { | |||
209 | dc.h = dc.font.height + 2; | 207 | dc.h = dc.font.height + 2; |
210 | dc.y = dc.h; | 208 | dc.y = dc.h; |
211 | for(i = curr; i != next; i=i->right) { | 209 | for(i = curr; i != next; i=i->right) { |
212 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); | 210 | drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); |
213 | dc.y += dc.h; | 211 | dc.y += dc.h; |
214 | } | 212 | } |
215 | dc.h = mh - dc.y; | 213 | dc.h = mh - dc.y; |
216 | drawtext(NULL, dc.norm); | 214 | drawtext(&dc, NULL, dc.norm); |
217 | } | 215 | } |
218 | 216 | ||
219 | Bool | 217 | Bool |
@@ -491,7 +489,12 @@ setup(Bool topbar) { | |||
491 | } | 489 | } |
492 | XFreeModifiermap(modmap); | 490 | XFreeModifiermap(modmap); |
493 | 491 | ||
494 | initfont(font); | 492 | dc.dpy = dpy; |
493 | dc.norm[ColBG] = getcolor(&dc, normbgcolor); | ||
494 | dc.norm[ColFG] = getcolor(&dc, normfgcolor); | ||
495 | dc.sel[ColBG] = getcolor(&dc, selbgcolor); | ||
496 | dc.sel[ColFG] = getcolor(&dc, selfgcolor); | ||
497 | initfont(&dc, font); | ||
495 | 498 | ||
496 | /* menu window */ | 499 | /* menu window */ |
497 | wa.override_redirect = True; | 500 | wa.override_redirect = True; |
@@ -531,11 +534,11 @@ setup(Bool topbar) { | |||
531 | DefaultVisual(dpy, screen), | 534 | DefaultVisual(dpy, screen), |
532 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | 535 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
533 | 536 | ||
534 | drawsetup(); | 537 | setupdraw(&dc, win); |
535 | if(maxname) | 538 | if(maxname) |
536 | cmdw = MIN(textw(maxname), mw / 3); | 539 | cmdw = MIN(textw(&dc, maxname), mw / 3); |
537 | if(prompt) | 540 | if(prompt) |
538 | promptw = MIN(textw(prompt), mw / 5); | 541 | promptw = MIN(textw(&dc, prompt), mw / 5); |
539 | text[0] = '\0'; | 542 | text[0] = '\0'; |
540 | match(text); | 543 | match(text); |
541 | XMapRaised(dpy, win); | 544 | XMapRaised(dpy, win); |
@@ -14,126 +14,123 @@ | |||
14 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 14 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
15 | 15 | ||
16 | /* variables */ | 16 | /* variables */ |
17 | char *progname; | 17 | const char *progname; |
18 | 18 | ||
19 | void | 19 | void |
20 | drawcleanup(void) { | 20 | cleanupdraw(DC *dc) { |
21 | if(dc.font.set) | 21 | if(dc->font.set) |
22 | XFreeFontSet(dpy, dc.font.set); | 22 | XFreeFontSet(dc->dpy, dc->font.set); |
23 | else | 23 | else |
24 | XFreeFont(dpy, dc.font.xfont); | 24 | XFreeFont(dc->dpy, dc->font.xfont); |
25 | XFreePixmap(dpy, dc.drawable); | 25 | XFreePixmap(dc->dpy, dc->drawable); |
26 | XFreeGC(dpy, dc.gc); | 26 | XFreeGC(dc->dpy, dc->gc); |
27 | } | 27 | } |
28 | 28 | ||
29 | void | 29 | void |
30 | drawsetup(void) { | 30 | setupdraw(DC *dc, Window w) { |
31 | /* style */ | 31 | XWindowAttributes wa; |
32 | dc.norm[ColBG] = getcolor(normbgcolor); | 32 | |
33 | dc.norm[ColFG] = getcolor(normfgcolor); | 33 | XGetWindowAttributes(dc->dpy, w, &wa); |
34 | dc.sel[ColBG] = getcolor(selbgcolor); | 34 | dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, |
35 | dc.sel[ColFG] = getcolor(selfgcolor); | 35 | DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); |
36 | 36 | dc->gc = XCreateGC(dc->dpy, w, 0, NULL); | |
37 | /* pixmap */ | 37 | XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); |
38 | dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); | 38 | if(!dc->font.set) |
39 | dc.gc = XCreateGC(dpy, parent, 0, NULL); | 39 | XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); |
40 | XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); | ||
41 | if(!dc.font.set) | ||
42 | XSetFont(dpy, dc.gc, dc.font.xfont->fid); | ||
43 | } | 40 | } |
44 | 41 | ||
45 | void | 42 | void |
46 | drawtext(const char *text, unsigned long col[ColLast]) { | 43 | drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { |
47 | char buf[256]; | 44 | char buf[256]; |
48 | int i, x, y, h, len, olen; | 45 | int i, x, y, h, len, olen; |
49 | XRectangle r = { dc.x, dc.y, dc.w, dc.h }; | 46 | XRectangle r = { dc->x, dc->y, dc->w, dc->h }; |
50 | 47 | ||
51 | XSetForeground(dpy, dc.gc, col[ColBG]); | 48 | XSetForeground(dc->dpy, dc->gc, col[ColBG]); |
52 | XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); | 49 | XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); |
53 | if(!text) | 50 | if(!text) |
54 | return; | 51 | return; |
55 | olen = strlen(text); | 52 | olen = strlen(text); |
56 | h = dc.font.height; | 53 | h = dc->font.height; |
57 | y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; | 54 | y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; |
58 | x = dc.x + (h / 2); | 55 | x = dc->x + (h / 2); |
59 | /* shorten text if necessary */ | 56 | /* shorten text if necessary */ |
60 | for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); | 57 | for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--); |
61 | if(!len) | 58 | if(!len) |
62 | return; | 59 | return; |
63 | memcpy(buf, text, len); | 60 | memcpy(buf, text, len); |
64 | if(len < olen) | 61 | if(len < olen) |
65 | for(i = len; i && i > len - 3; buf[--i] = '.'); | 62 | for(i = len; i && i > len - 3; buf[--i] = '.'); |
66 | XSetForeground(dpy, dc.gc, col[ColFG]); | 63 | XSetForeground(dc->dpy, dc->gc, col[ColFG]); |
67 | if(dc.font.set) | 64 | if(dc->font.set) |
68 | XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); | 65 | XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); |
69 | else | 66 | else |
70 | XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); | 67 | XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len); |
71 | } | 68 | } |
72 | 69 | ||
73 | void | 70 | void |
74 | eprint(const char *errstr, ...) { | 71 | eprint(const char *fmt, ...) { |
75 | va_list ap; | 72 | va_list ap; |
76 | 73 | ||
77 | fprintf(stderr, "%s: ", progname); | 74 | fprintf(stderr, "%s: ", progname); |
78 | va_start(ap, errstr); | 75 | va_start(ap, fmt); |
79 | vfprintf(stderr, errstr, ap); | 76 | vfprintf(stderr, fmt, ap); |
80 | va_end(ap); | 77 | va_end(ap); |
81 | exit(EXIT_FAILURE); | 78 | exit(EXIT_FAILURE); |
82 | } | 79 | } |
83 | 80 | ||
84 | unsigned long | 81 | unsigned long |
85 | getcolor(const char *colstr) { | 82 | getcolor(DC *dc, const char *colstr) { |
86 | Colormap cmap = DefaultColormap(dpy, screen); | 83 | Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); |
87 | XColor color; | 84 | XColor color; |
88 | 85 | ||
89 | if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) | 86 | if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) |
90 | eprint("cannot allocate color '%s'\n", colstr); | 87 | eprint("cannot allocate color '%s'\n", colstr); |
91 | return color.pixel; | 88 | return color.pixel; |
92 | } | 89 | } |
93 | 90 | ||
94 | void | 91 | void |
95 | initfont(const char *fontstr) { | 92 | initfont(DC *dc, const char *fontstr) { |
96 | char *def, **missing = NULL; | 93 | char *def, **missing = NULL; |
97 | int i, n; | 94 | int i, n; |
98 | 95 | ||
99 | if(!fontstr || !*fontstr) | 96 | if(!fontstr || !*fontstr) |
100 | eprint("cannot load null font\n"); | 97 | eprint("cannot load null font\n"); |
101 | dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); | 98 | dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def); |
102 | if(missing) | 99 | if(missing) |
103 | XFreeStringList(missing); | 100 | XFreeStringList(missing); |
104 | if(dc.font.set) { | 101 | if(dc->font.set) { |
105 | XFontStruct **xfonts; | 102 | XFontStruct **xfonts; |
106 | char **font_names; | 103 | char **font_names; |
107 | dc.font.ascent = dc.font.descent = 0; | 104 | dc->font.ascent = dc->font.descent = 0; |
108 | n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); | 105 | n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names); |
109 | for(i = 0; i < n; i++) { | 106 | for(i = 0; i < n; i++) { |
110 | dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); | 107 | dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); |
111 | dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); | 108 | dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent); |
112 | xfonts++; | 109 | xfonts++; |
113 | } | 110 | } |
114 | } | 111 | } |
115 | else { | 112 | else { |
116 | if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) | 113 | if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) |
117 | && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) | 114 | && !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed"))) |
118 | eprint("cannot load font '%s'\n", fontstr); | 115 | eprint("cannot load font '%s'\n", fontstr); |
119 | dc.font.ascent = dc.font.xfont->ascent; | 116 | dc->font.ascent = dc->font.xfont->ascent; |
120 | dc.font.descent = dc.font.xfont->descent; | 117 | dc->font.descent = dc->font.xfont->descent; |
121 | } | 118 | } |
122 | dc.font.height = dc.font.ascent + dc.font.descent; | 119 | dc->font.height = dc->font.ascent + dc->font.descent; |
123 | } | 120 | } |
124 | 121 | ||
125 | int | 122 | int |
126 | textnw(const char *text, unsigned int len) { | 123 | textnw(DC *dc, const char *text, unsigned int len) { |
127 | XRectangle r; | 124 | XRectangle r; |
128 | 125 | ||
129 | if(dc.font.set) { | 126 | if(dc->font.set) { |
130 | XmbTextExtents(dc.font.set, text, len, NULL, &r); | 127 | XmbTextExtents(dc->font.set, text, len, NULL, &r); |
131 | return r.width; | 128 | return r.width; |
132 | } | 129 | } |
133 | return XTextWidth(dc.font.xfont, text, len); | 130 | return XTextWidth(dc->font.xfont, text, len); |
134 | } | 131 | } |
135 | 132 | ||
136 | int | 133 | int |
137 | textw(const char *text) { | 134 | textw(DC *dc, const char *text) { |
138 | return textnw(text, strlen(text)) + dc.font.height; | 135 | return textnw(dc, text, strlen(text)) + dc->font.height; |
139 | } | 136 | } |
@@ -9,6 +9,7 @@ typedef struct { | |||
9 | unsigned long norm[ColLast]; | 9 | unsigned long norm[ColLast]; |
10 | unsigned long sel[ColLast]; | 10 | unsigned long sel[ColLast]; |
11 | Drawable drawable; | 11 | Drawable drawable; |
12 | Display *dpy; | ||
12 | GC gc; | 13 | GC gc; |
13 | struct { | 14 | struct { |
14 | XFontStruct *xfont; | 15 | XFontStruct *xfont; |
@@ -20,25 +21,14 @@ typedef struct { | |||
20 | } DC; /* draw context */ | 21 | } DC; /* draw context */ |
21 | 22 | ||
22 | /* forward declarations */ | 23 | /* forward declarations */ |
23 | void drawcleanup(void); | 24 | void cleanupdraw(DC *dc); |
24 | void drawsetup(void); | 25 | void setupdraw(DC *dc, Window w); |
25 | void drawtext(const char *text, unsigned long col[ColLast]); | 26 | void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); |
26 | void eprint(const char *errstr, ...); | 27 | void eprint(const char *fmt, ...); |
27 | unsigned long getcolor(const char *colstr); | 28 | unsigned long getcolor(DC *dc, const char *colstr); |
28 | void initfont(const char *fontstr); | 29 | void initfont(DC *dc, const char *fontstr); |
29 | int textnw(const char *text, unsigned int len); | 30 | int textnw(DC *dc, const char *text, unsigned int len); |
30 | int textw(const char *text); | 31 | int textw(DC *dc, const char *text); |
31 | 32 | ||
32 | /* variables */ | 33 | /* variables */ |
33 | extern char *progname; | 34 | extern const char *progname; |
34 | extern Display *dpy; | ||
35 | extern DC dc; | ||
36 | extern int screen; | ||
37 | extern unsigned int mw, mh; | ||
38 | extern Window parent; | ||
39 | |||
40 | extern const char *font; | ||
41 | extern const char *normbgcolor; | ||
42 | extern const char *normfgcolor; | ||
43 | extern const char *selbgcolor; | ||
44 | extern const char *selfgcolor; | ||