aewl

view draw.c @ 541:08d3d329270a

using MASTER 600 again, it is definately better, and using urxvtc for the moment (it doesn't flickers on refreshes, but this is not because of Marc Lehmann, it is because of the original rxvt code)
author arg@mig29
date Thu, 26 Oct 2006 12:13:41 +0200
parents 451f19d48845
children f05cfa7d5128
line source
1 /* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
2 * See LICENSE file for license details.
3 */
4 #include "dwm.h"
5 #include <stdio.h>
6 #include <string.h>
7 #include <X11/Xlocale.h>
9 /* static */
11 static unsigned int
12 textnw(const char *text, unsigned int len) {
13 XRectangle r;
15 if(dc.font.set) {
16 XmbTextExtents(dc.font.set, text, len, NULL, &r);
17 return r.width;
18 }
19 return XTextWidth(dc.font.xfont, text, len);
20 }
22 static void
23 drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
24 int x, y, w, h;
25 static char buf[256];
26 unsigned int len, olen;
27 XGCValues gcv;
28 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
30 XSetForeground(dpy, dc.gc, col[ColBG]);
31 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
32 if(!text)
33 return;
34 w = 0;
35 olen = len = strlen(text);
36 if(len >= sizeof(buf))
37 len = sizeof(buf) - 1;
38 memcpy(buf, text, len);
39 buf[len] = 0;
40 h = dc.font.ascent + dc.font.descent;
41 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
42 x = dc.x + (h / 2);
43 /* shorten text if necessary */
44 while(len && (w = textnw(buf, len)) > dc.w - h)
45 buf[--len] = 0;
46 if(len < olen) {
47 if(len > 1)
48 buf[len - 1] = '.';
49 if(len > 2)
50 buf[len - 2] = '.';
51 if(len > 3)
52 buf[len - 3] = '.';
53 }
54 if(w > dc.w)
55 return; /* too long */
56 gcv.foreground = col[ColFG];
57 if(dc.font.set) {
58 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
59 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
60 }
61 else {
62 gcv.font = dc.font.xfont->fid;
63 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
64 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
65 }
66 if(highlight) {
67 r.x = dc.x + 2;
68 r.y = dc.y + 2;
69 r.width = r.height = (h + 2) / 4;
70 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
71 }
72 }
74 /* extern */
76 void
77 drawall(void) {
78 Client *c;
80 for(c = clients; c; c = getnext(c->next))
81 drawtitle(c);
82 drawstatus();
83 }
85 void
86 drawstatus(void) {
87 int i, x;
89 dc.x = dc.y = 0;
90 for(i = 0; i < ntags; i++) {
91 dc.w = textw(tags[i]);
92 if(seltag[i])
93 drawtext(tags[i], dc.sel, sel && sel->tags[i]);
94 else
95 drawtext(tags[i], dc.norm, sel && sel->tags[i]);
96 dc.x += dc.w;
97 }
98 dc.w = bmw;
99 drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False);
100 x = dc.x + dc.w;
101 dc.w = textw(stext);
102 dc.x = bx + bw - dc.w;
103 if(dc.x < x) {
104 dc.x = x;
105 dc.w = bw - x;
106 }
107 drawtext(stext, dc.status, False);
108 if((dc.w = dc.x - x) > bh) {
109 dc.x = x;
110 if(sel)
111 drawtext(sel->name, dc.sel, False);
112 else
113 drawtext(NULL, dc.norm, False);
114 }
115 XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
116 XSync(dpy, False);
117 }
119 void
120 drawtitle(Client *c) {
121 if(c == sel && issel) {
122 drawstatus();
123 XUnmapWindow(dpy, c->twin);
124 XSetWindowBorder(dpy, c->win, dc.sel[ColBG]);
125 return;
126 }
127 XSetWindowBorder(dpy, c->win, dc.norm[ColBG]);
128 XMapWindow(dpy, c->twin);
129 dc.x = dc.y = 0;
130 dc.w = c->tw;
131 drawtext(c->name, dc.norm, False);
132 XCopyArea(dpy, dc.drawable, c->twin, dc.gc, 0, 0, c->tw, c->th, 0, 0);
133 XSync(dpy, False);
134 }
136 unsigned long
137 getcolor(const char *colstr) {
138 Colormap cmap = DefaultColormap(dpy, screen);
139 XColor color;
141 if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
142 eprint("error, cannot allocate color '%s'\n", colstr);
143 return color.pixel;
144 }
146 void
147 setfont(const char *fontstr) {
148 char **missing, *def;
149 int i, n;
151 missing = NULL;
152 setlocale(LC_ALL, "");
153 if(dc.font.set)
154 XFreeFontSet(dpy, dc.font.set);
155 dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
156 if(missing) {
157 while(n--)
158 fprintf(stderr, "missing fontset: %s\n", missing[n]);
159 XFreeStringList(missing);
160 if(dc.font.set) {
161 XFreeFontSet(dpy, dc.font.set);
162 dc.font.set = NULL;
163 }
164 }
165 if(dc.font.set) {
166 XFontSetExtents *font_extents;
167 XFontStruct **xfonts;
168 char **font_names;
169 dc.font.ascent = dc.font.descent = 0;
170 font_extents = XExtentsOfFontSet(dc.font.set);
171 n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
172 for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
173 if(dc.font.ascent < (*xfonts)->ascent)
174 dc.font.ascent = (*xfonts)->ascent;
175 if(dc.font.descent < (*xfonts)->descent)
176 dc.font.descent = (*xfonts)->descent;
177 xfonts++;
178 }
179 }
180 else {
181 if(dc.font.xfont)
182 XFreeFont(dpy, dc.font.xfont);
183 dc.font.xfont = NULL;
184 dc.font.xfont = XLoadQueryFont(dpy, fontstr);
185 if (!dc.font.xfont)
186 dc.font.xfont = XLoadQueryFont(dpy, "fixed");
187 if (!dc.font.xfont)
188 eprint("error, cannot init 'fixed' font\n");
189 dc.font.ascent = dc.font.xfont->ascent;
190 dc.font.descent = dc.font.xfont->descent;
191 }
192 dc.font.height = dc.font.ascent + dc.font.descent;
193 }
195 unsigned int
196 textw(const char *text) {
197 return textnw(text, strlen(text)) + dc.font.height;
198 }