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