diff options
Diffstat (limited to 'draw.c')
| -rw-r--r-- | draw.c | 109 |
1 files changed, 53 insertions, 56 deletions
| @@ -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 | } |
