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; | ||
