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