rev |
line source |
paulo@0
|
1 /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
|
paulo@0
|
2 * See LICENSE file for license details.
|
paulo@0
|
3 */
|
paulo@0
|
4 #include "dwm.h"
|
paulo@0
|
5 #include <string.h>
|
paulo@0
|
6
|
paulo@0
|
7 /* static */
|
paulo@0
|
8
|
paulo@0
|
9 static void
|
paulo@0
|
10 drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
|
paulo@0
|
11 int x;
|
paulo@0
|
12 XGCValues gcv;
|
paulo@0
|
13 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
|
paulo@0
|
14
|
paulo@0
|
15 gcv.foreground = col[ColFG];
|
paulo@0
|
16 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
|
paulo@0
|
17 x = (dc.font.ascent + dc.font.descent + 2) / 4;
|
paulo@0
|
18 r.x = dc.x + 1;
|
paulo@0
|
19 r.y = dc.y + 1;
|
paulo@0
|
20 if(filled) {
|
paulo@0
|
21 r.width = r.height = x + 1;
|
paulo@0
|
22 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
paulo@0
|
23 }
|
paulo@0
|
24 else if(empty) {
|
paulo@0
|
25 r.width = r.height = x;
|
paulo@0
|
26 XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
paulo@0
|
27 }
|
paulo@0
|
28 }
|
paulo@0
|
29
|
paulo@0
|
30 static Bool
|
paulo@0
|
31 isoccupied(unsigned int t) {
|
paulo@0
|
32 Client *c;
|
paulo@0
|
33
|
paulo@0
|
34 for(c = clients; c; c = c->next)
|
paulo@0
|
35 if(c->tags[t])
|
paulo@0
|
36 return True;
|
paulo@0
|
37 return False;
|
paulo@0
|
38 }
|
paulo@0
|
39
|
paulo@0
|
40 static unsigned int
|
paulo@0
|
41 textnw(const char *text, unsigned int len) {
|
paulo@0
|
42 XRectangle r;
|
paulo@0
|
43
|
paulo@0
|
44 if(dc.font.set) {
|
paulo@0
|
45 XmbTextExtents(dc.font.set, text, len, NULL, &r);
|
paulo@0
|
46 return r.width;
|
paulo@0
|
47 }
|
paulo@0
|
48 return XTextWidth(dc.font.xfont, text, len);
|
paulo@0
|
49 }
|
paulo@0
|
50
|
paulo@0
|
51 /* extern */
|
paulo@0
|
52
|
paulo@0
|
53 void
|
paulo@0
|
54 drawstatus(void) {
|
paulo@0
|
55 Client *c;
|
paulo@0
|
56 int i, j, x;
|
paulo@0
|
57
|
paulo@0
|
58 dc.x = dc.y = 0;
|
paulo@0
|
59 for(i = 0; i < ntags; i++) {
|
paulo@0
|
60 dc.w = textw(tags[i]);
|
paulo@0
|
61 if(seltag[i]) {
|
paulo@0
|
62 drawtext(tags[i], dc.sel);
|
paulo@0
|
63 drawsquare(sel && sel->tags[i], isoccupied(i), dc.sel);
|
paulo@0
|
64 }
|
paulo@0
|
65 else {
|
paulo@0
|
66 drawtext(tags[i], dc.norm);
|
paulo@0
|
67 drawsquare(sel && sel->tags[i], isoccupied(i), dc.norm);
|
paulo@0
|
68 }
|
paulo@0
|
69 dc.x += dc.w;
|
paulo@0
|
70 }
|
paulo@0
|
71 dc.w = blw;
|
paulo@0
|
72 drawtext(lt->symbol, dc.norm);
|
paulo@0
|
73 x = dc.x + dc.w;
|
paulo@0
|
74 dc.w = textw(stext);
|
paulo@0
|
75 dc.x = sw - dc.w;
|
paulo@0
|
76 if(dc.x < x) {
|
paulo@0
|
77 dc.x = x;
|
paulo@0
|
78 dc.w = sw - x;
|
paulo@0
|
79 }
|
paulo@0
|
80 drawtext(stext, dc.norm);
|
paulo@0
|
81 if((dc.w = dc.x - x) > bh) {
|
paulo@0
|
82 dc.x = x;
|
paulo@0
|
83 for(j=0, c = clients; c; c = c->next) {
|
paulo@0
|
84 if(isvisible(c))
|
paulo@0
|
85 j++;
|
paulo@0
|
86 }
|
paulo@0
|
87 if(j && j < MAX_TASKS)
|
paulo@0
|
88 dc.w /= j;
|
paulo@0
|
89 else {
|
paulo@0
|
90 drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm);
|
paulo@0
|
91 j = 0;
|
paulo@0
|
92 }
|
paulo@0
|
93 for(c = clients; j && c; c = c->next) {
|
paulo@0
|
94 if(isvisible(c)) {
|
paulo@0
|
95 drawtext(c->name, (c == sel) ? dc.sel : dc.norm);
|
paulo@0
|
96 dc.x += dc.w;
|
paulo@0
|
97 j--;
|
paulo@0
|
98 }
|
paulo@0
|
99 }
|
paulo@0
|
100 }
|
paulo@0
|
101 XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
|
paulo@0
|
102 XSync(dpy, False);
|
paulo@0
|
103 }
|
paulo@0
|
104
|
paulo@0
|
105 void
|
paulo@0
|
106 drawtext(const char *text, unsigned long col[ColLast]) {
|
paulo@0
|
107 int x, y, w, h;
|
paulo@0
|
108 static char buf[256];
|
paulo@0
|
109 unsigned int len, olen;
|
paulo@0
|
110 XGCValues gcv;
|
paulo@0
|
111 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
|
paulo@0
|
112
|
paulo@0
|
113 XSetForeground(dpy, dc.gc, col[ColBG]);
|
paulo@0
|
114 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
paulo@0
|
115 if(!text)
|
paulo@0
|
116 return;
|
paulo@0
|
117 w = 0;
|
paulo@0
|
118 olen = len = strlen(text);
|
paulo@0
|
119 if(len >= sizeof buf)
|
paulo@0
|
120 len = sizeof buf - 1;
|
paulo@0
|
121 memcpy(buf, text, len);
|
paulo@0
|
122 buf[len] = 0;
|
paulo@0
|
123 h = dc.font.ascent + dc.font.descent;
|
paulo@0
|
124 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
|
paulo@0
|
125 x = dc.x + (h / 2);
|
paulo@0
|
126 /* shorten text if necessary */
|
paulo@0
|
127 while(len && (w = textnw(buf, len)) > dc.w - h)
|
paulo@0
|
128 buf[--len] = 0;
|
paulo@0
|
129 if(len < olen) {
|
paulo@0
|
130 if(len > 1)
|
paulo@0
|
131 buf[len - 1] = '.';
|
paulo@0
|
132 if(len > 2)
|
paulo@0
|
133 buf[len - 2] = '.';
|
paulo@0
|
134 if(len > 3)
|
paulo@0
|
135 buf[len - 3] = '.';
|
paulo@0
|
136 }
|
paulo@0
|
137 if(w > dc.w)
|
paulo@0
|
138 return; /* too long */
|
paulo@0
|
139 gcv.foreground = col[ColFG];
|
paulo@0
|
140 if(dc.font.set) {
|
paulo@0
|
141 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
|
paulo@0
|
142 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
|
paulo@0
|
143 }
|
paulo@0
|
144 else {
|
paulo@0
|
145 gcv.font = dc.font.xfont->fid;
|
paulo@0
|
146 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
|
paulo@0
|
147 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
|
paulo@0
|
148 }
|
paulo@0
|
149 }
|
paulo@0
|
150
|
paulo@0
|
151 unsigned int
|
paulo@0
|
152 textw(const char *text) {
|
paulo@0
|
153 return textnw(text, strlen(text)) + dc.font.height;
|
paulo@0
|
154 }
|