aewl

view draw.c @ 384:126e78129f1d

configurenotify remembers max geom now, and restores this if necessary, however it accepts to touch the max size on configurerequest, this shouldn't break fillscreen apps (tested with mplayer)
author Anselm R. Garbe <arg@10kloc.org>
date Tue, 29 Aug 2006 17:31:55 +0200
parents fc9d35252ab4
children 9d23330a5268
line source
1 /*
2 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 * See LICENSE file for license details.
4 */
5 #include "dwm.h"
6 #include <stdio.h>
7 #include <string.h>
8 #include <X11/Xlocale.h>
10 /* static */
12 static unsigned int
13 textnw(const char *text, unsigned int len)
14 {
15 XRectangle r;
17 if(dc.font.set) {
18 XmbTextExtents(dc.font.set, text, len, NULL, &r);
19 return r.width;
20 }
21 return XTextWidth(dc.font.xfont, text, len);
22 }
24 static void
25 drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
26 {
27 int x, y, w, h;
28 static char buf[256];
29 unsigned int len, olen;
30 XGCValues gcv;
31 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
33 XSetForeground(dpy, dc.gc, col[ColBG]);
34 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
36 if(!text)
37 return;
39 w = 0;
40 olen = len = strlen(text);
41 if(len >= sizeof(buf))
42 len = sizeof(buf) - 1;
43 memcpy(buf, text, len);
44 buf[len] = 0;
46 h = dc.font.ascent + dc.font.descent;
47 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
48 x = dc.x + (h / 2);
50 /* shorten text if necessary */
51 while(len && (w = textnw(buf, len)) > dc.w - h)
52 buf[--len] = 0;
53 if(len < olen) {
54 if(len > 1)
55 buf[len - 1] = '.';
56 if(len > 2)
57 buf[len - 2] = '.';
58 if(len > 3)
59 buf[len - 3] = '.';
60 }
62 if(w > dc.w)
63 return; /* too long */
64 gcv.foreground = col[ColFG];
65 if(dc.font.set) {
66 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
67 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
68 }
69 else {
70 gcv.font = dc.font.xfont->fid;
71 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
72 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
73 }
74 if(highlight) {
75 r.x = dc.x + 2;
76 r.y = dc.y + 2;
77 r.width = r.height = 3;
78 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
79 }
80 }
82 /* extern */
84 void
85 drawall()
86 {
87 Client *c;
89 for(c = clients; c; c = getnext(c->next))
90 drawtitle(c);
91 drawstatus();
92 }
94 void
95 drawstatus()
96 {
97 int i, x;
99 dc.x = dc.y = 0;
101 for(i = 0; i < ntags; i++) {
102 dc.w = textw(tags[i]);
103 if(seltag[i])
104 drawtext(tags[i], dc.sel, sel && sel->tags[i]);
105 else
106 drawtext(tags[i], dc.norm, sel && sel->tags[i]);
107 dc.x += dc.w;
108 }
110 dc.w = bmw;
111 drawtext(arrange == dotile ? TILESYMBOL : FLOATSYMBOL, dc.status, False);
113 x = dc.x + dc.w;
114 dc.w = textw(stext);
115 dc.x = bx + bw - dc.w;
116 if(dc.x < x) {
117 dc.x = x;
118 dc.w = bw - x;
119 }
120 drawtext(stext, dc.status, False);
122 if((dc.w = dc.x - x) > bh) {
123 dc.x = x;
124 if(sel)
125 drawtext(sel->name, dc.sel, False);
126 else
127 drawtext(NULL, dc.norm, False);
128 }
129 XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
130 XSync(dpy, False);
131 }
133 void
134 drawtitle(Client *c)
135 {
136 if(c == sel && issel) {
137 drawstatus();
138 XUnmapWindow(dpy, c->twin);
139 XSetWindowBorder(dpy, c->win, dc.sel[ColBG]);
140 return;
141 }
143 XSetWindowBorder(dpy, c->win, dc.norm[ColBG]);
144 XMapWindow(dpy, c->twin);
145 dc.x = dc.y = 0;
146 dc.w = c->tw;
147 drawtext(c->name, dc.norm, False);
148 XCopyArea(dpy, dc.drawable, c->twin, dc.gc, 0, 0, c->tw, c->th, 0, 0);
149 XSync(dpy, False);
150 }
152 unsigned long
153 getcolor(const char *colstr)
154 {
155 Colormap cmap = DefaultColormap(dpy, screen);
156 XColor color;
158 XAllocNamedColor(dpy, cmap, colstr, &color, &color);
159 return color.pixel;
160 }
162 void
163 setfont(const char *fontstr)
164 {
165 char **missing, *def;
166 int i, n;
168 missing = NULL;
169 setlocale(LC_ALL, "");
170 if(dc.font.set)
171 XFreeFontSet(dpy, dc.font.set);
172 dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
173 if(missing) {
174 while(n--)
175 fprintf(stderr, "missing fontset: %s\n", missing[n]);
176 XFreeStringList(missing);
177 if(dc.font.set) {
178 XFreeFontSet(dpy, dc.font.set);
179 dc.font.set = NULL;
180 }
181 }
182 if(dc.font.set) {
183 XFontSetExtents *font_extents;
184 XFontStruct **xfonts;
185 char **font_names;
187 dc.font.ascent = dc.font.descent = 0;
188 font_extents = XExtentsOfFontSet(dc.font.set);
189 n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
190 for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
191 if(dc.font.ascent < (*xfonts)->ascent)
192 dc.font.ascent = (*xfonts)->ascent;
193 if(dc.font.descent < (*xfonts)->descent)
194 dc.font.descent = (*xfonts)->descent;
195 xfonts++;
196 }
197 }
198 else {
199 if(dc.font.xfont)
200 XFreeFont(dpy, dc.font.xfont);
201 dc.font.xfont = NULL;
202 dc.font.xfont = XLoadQueryFont(dpy, fontstr);
203 if (!dc.font.xfont)
204 dc.font.xfont = XLoadQueryFont(dpy, "fixed");
205 if (!dc.font.xfont)
206 eprint("error, cannot init 'fixed' font\n");
207 dc.font.ascent = dc.font.xfont->ascent;
208 dc.font.descent = dc.font.xfont->descent;
209 }
210 dc.font.height = dc.font.ascent + dc.font.descent;
211 }
213 unsigned int
214 textw(const char *text)
215 {
216 return textnw(text, strlen(text)) + dc.font.height;
217 }