JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
renamed seltag into seltags
[dwm.git] / draw.c
1 /* See LICENSE file for copyright and license details. */
2 #include "dwm.h"
3 #include <string.h>
4
5 /* static */
6
7 static void
8 drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
9         int x;
10         XGCValues gcv;
11         XRectangle r = { dc.x, dc.y, dc.w, dc.h };
12
13         gcv.foreground = col[ColFG];
14         XChangeGC(dpy, dc.gc, GCForeground, &gcv);
15         x = (dc.font.ascent + dc.font.descent + 2) / 4;
16         r.x = dc.x + 1;
17         r.y = dc.y + 1;
18         if(filled) {
19                 r.width = r.height = x + 1;
20                 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
21         }
22         else if(empty) {
23                 r.width = r.height = x;
24                 XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
25         }
26 }
27
28 static Bool
29 isoccupied(unsigned int t) {
30         Client *c;
31
32         for(c = clients; c; c = c->next)
33                 if(c->tags[t])
34                         return True;
35         return False;
36 }
37
38 static unsigned int
39 textnw(const char *text, unsigned int len) {
40         XRectangle r;
41
42         if(dc.font.set) {
43                 XmbTextExtents(dc.font.set, text, len, NULL, &r);
44                 return r.width;
45         }
46         return XTextWidth(dc.font.xfont, text, len);
47 }
48
49 /* extern */
50
51 void
52 drawstatus(void) {
53         int i, x;
54
55         dc.x = dc.y = 0;
56         for(i = 0; i < ntags; i++) {
57                 dc.w = textw(tags[i]);
58                 if(seltags[i]) {
59                         drawtext(tags[i], dc.sel);
60                         drawsquare(sel && sel->tags[i], isoccupied(i), dc.sel);
61                 }
62                 else {
63                         drawtext(tags[i], dc.norm);
64                         drawsquare(sel && sel->tags[i], isoccupied(i), dc.norm);
65                 }
66                 dc.x += dc.w;
67         }
68         dc.w = blw;
69         drawtext(getsymbol(), dc.norm);
70         x = dc.x + dc.w;
71         dc.w = textw(stext);
72         dc.x = sw - dc.w;
73         if(dc.x < x) {
74                 dc.x = x;
75                 dc.w = sw - x;
76         }
77         drawtext(stext, dc.norm);
78         if((dc.w = dc.x - x) > bh) {
79                 dc.x = x;
80                 if(sel) {
81                         drawtext(sel->name, dc.sel);
82                         drawsquare(sel->ismax, sel->isfloating, dc.sel);
83                 }
84                 else
85                         drawtext(NULL, dc.norm);
86         }
87         XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
88         XSync(dpy, False);
89 }
90
91 void
92 drawtext(const char *text, unsigned long col[ColLast]) {
93         int x, y, w, h;
94         static char buf[256];
95         unsigned int len, olen;
96         XRectangle r = { dc.x, dc.y, dc.w, dc.h };
97
98         XSetForeground(dpy, dc.gc, col[ColBG]);
99         XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
100         if(!text)
101                 return;
102         w = 0;
103         olen = len = strlen(text);
104         if(len >= sizeof buf)
105                 len = sizeof buf - 1;
106         memcpy(buf, text, len);
107         buf[len] = 0;
108         h = dc.font.ascent + dc.font.descent;
109         y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
110         x = dc.x + (h / 2);
111         /* shorten text if necessary */
112         while(len && (w = textnw(buf, len)) > dc.w - h)
113                 buf[--len] = 0;
114         if(len < olen) {
115                 if(len > 1)
116                         buf[len - 1] = '.';
117                 if(len > 2)
118                         buf[len - 2] = '.';
119                 if(len > 3)
120                         buf[len - 3] = '.';
121         }
122         if(w > dc.w)
123                 return; /* too long */
124         XSetForeground(dpy, dc.gc, col[ColFG]);
125         if(dc.font.set)
126                 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
127         else
128                 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
129 }
130
131 unsigned int
132 textw(const char *text) {
133         return textnw(text, strlen(text)) + dc.font.height;
134 }