dwm-meillo

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