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@6
|
74
|
paulo@6
|
75 char *_stext = stext;
|
paulo@6
|
76 if (getkeymode() == COMMANDMODE) {
|
paulo@6
|
77 strcpy(cmtext, "-- CMD -- ");
|
paulo@6
|
78 strncat(cmtext, stext, sizeof cmtext - 1 - strlen(cmtext));
|
paulo@6
|
79 _stext = cmtext;
|
paulo@6
|
80 }
|
paulo@6
|
81 dc.w = textw(_stext);
|
paulo@0
|
82 dc.x = sw - dc.w;
|
paulo@0
|
83 if(dc.x < x) {
|
paulo@0
|
84 dc.x = x;
|
paulo@0
|
85 dc.w = sw - x;
|
paulo@0
|
86 }
|
paulo@6
|
87 drawtext(_stext, dc.norm);
|
paulo@6
|
88
|
paulo@0
|
89 if((dc.w = dc.x - x) > bh) {
|
paulo@0
|
90 dc.x = x;
|
paulo@3
|
91 drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm);
|
paulo@3
|
92 }
|
paulo@3
|
93 XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
|
paulo@3
|
94
|
paulo@3
|
95 if (TASKBAR) {
|
paulo@3
|
96 dc.x = dc.y = 0;
|
paulo@3
|
97 dc.w = sw;
|
paulo@0
|
98 for(j=0, c = clients; c; c = c->next) {
|
paulo@0
|
99 if(isvisible(c))
|
paulo@0
|
100 j++;
|
paulo@0
|
101 }
|
paulo@0
|
102 if(j && j < MAX_TASKS)
|
paulo@0
|
103 dc.w /= j;
|
paulo@3
|
104 else
|
paulo@3
|
105 drawtext("", dc.norm);
|
paulo@3
|
106 for(c = clients; j && c && dc.x < sw; c = c->next) {
|
paulo@0
|
107 if(isvisible(c)) {
|
paulo@0
|
108 drawtext(c->name, (c == sel) ? dc.sel : dc.norm);
|
paulo@0
|
109 dc.x += dc.w;
|
paulo@0
|
110 j--;
|
paulo@0
|
111 }
|
paulo@0
|
112 }
|
paulo@3
|
113 XCopyArea(dpy, dc.drawable, tbarwin, dc.gc, 0, 0, sw, bh, 0, 0);
|
paulo@0
|
114 }
|
paulo@3
|
115
|
paulo@0
|
116 XSync(dpy, False);
|
paulo@0
|
117 }
|
paulo@0
|
118
|
paulo@0
|
119 void
|
paulo@0
|
120 drawtext(const char *text, unsigned long col[ColLast]) {
|
paulo@0
|
121 int x, y, w, h;
|
paulo@0
|
122 static char buf[256];
|
paulo@0
|
123 unsigned int len, olen;
|
paulo@0
|
124 XGCValues gcv;
|
paulo@0
|
125 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
|
paulo@0
|
126
|
paulo@0
|
127 XSetForeground(dpy, dc.gc, col[ColBG]);
|
paulo@0
|
128 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
paulo@0
|
129 if(!text)
|
paulo@0
|
130 return;
|
paulo@0
|
131 w = 0;
|
paulo@0
|
132 olen = len = strlen(text);
|
paulo@0
|
133 if(len >= sizeof buf)
|
paulo@0
|
134 len = sizeof buf - 1;
|
paulo@0
|
135 memcpy(buf, text, len);
|
paulo@0
|
136 buf[len] = 0;
|
paulo@0
|
137 h = dc.font.ascent + dc.font.descent;
|
paulo@0
|
138 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
|
paulo@0
|
139 x = dc.x + (h / 2);
|
paulo@0
|
140 /* shorten text if necessary */
|
paulo@0
|
141 while(len && (w = textnw(buf, len)) > dc.w - h)
|
paulo@0
|
142 buf[--len] = 0;
|
paulo@0
|
143 if(len < olen) {
|
paulo@0
|
144 if(len > 1)
|
paulo@0
|
145 buf[len - 1] = '.';
|
paulo@0
|
146 if(len > 2)
|
paulo@0
|
147 buf[len - 2] = '.';
|
paulo@0
|
148 if(len > 3)
|
paulo@0
|
149 buf[len - 3] = '.';
|
paulo@0
|
150 }
|
paulo@0
|
151 if(w > dc.w)
|
paulo@0
|
152 return; /* too long */
|
paulo@0
|
153 gcv.foreground = col[ColFG];
|
paulo@0
|
154 if(dc.font.set) {
|
paulo@0
|
155 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
|
paulo@0
|
156 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
|
paulo@0
|
157 }
|
paulo@0
|
158 else {
|
paulo@0
|
159 gcv.font = dc.font.xfont->fid;
|
paulo@0
|
160 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
|
paulo@0
|
161 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
|
paulo@0
|
162 }
|
paulo@0
|
163 }
|
paulo@0
|
164
|
paulo@0
|
165 unsigned int
|
paulo@0
|
166 textw(const char *text) {
|
paulo@0
|
167 return textnw(text, strlen(text)) + dc.font.height;
|
paulo@0
|
168 }
|