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