all repos — dwm @ e1deda9e040c052af62aecc2fb4ee770fb2496a2

fork of suckless dynamic window manager

draw.c (view raw)

  1/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
  2 * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
  3 * © 2007 Premysl Hruby <dfenze at gmail dot com>
  4 * See LICENSE file for license details. */
  5#include "dwm.h"
  6#include <string.h>
  7
  8/* static */
  9
 10static void
 11drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
 12	int x;
 13	XGCValues gcv;
 14	XRectangle r = { dc.x, dc.y, dc.w, dc.h };
 15
 16	gcv.foreground = col[ColFG];
 17	XChangeGC(dpy, dc.gc, GCForeground, &gcv);
 18	x = (dc.font.ascent + dc.font.descent + 2) / 4;
 19	r.x = dc.x + 1;
 20	r.y = dc.y + 1;
 21	if(filled) {
 22		r.width = r.height = x + 1;
 23		XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
 24	}
 25	else if(empty) {
 26		r.width = r.height = x;
 27		XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
 28	}
 29}
 30
 31static Bool
 32isoccupied(unsigned int t) {
 33	Client *c;
 34
 35	for(c = clients; c; c = c->next)
 36		if(c->tags[t])
 37			return True;
 38	return False;
 39}
 40
 41static unsigned int
 42textnw(const char *text, unsigned int len) {
 43	XRectangle r;
 44
 45	if(dc.font.set) {
 46		XmbTextExtents(dc.font.set, text, len, NULL, &r);
 47		return r.width;
 48	}
 49	return XTextWidth(dc.font.xfont, text, len);
 50}
 51
 52/* extern */
 53
 54void
 55drawstatus(void) {
 56	int i, x;
 57
 58	dc.x = dc.y = 0;
 59	for(i = 0; i < ntags; i++) {
 60		dc.w = textw(tags[i]);
 61		if(seltag[i]) {
 62			drawtext(tags[i], dc.sel);
 63			drawsquare(sel && sel->tags[i], isoccupied(i), dc.sel);
 64		}
 65		else {
 66			drawtext(tags[i], dc.norm);
 67			drawsquare(sel && sel->tags[i], isoccupied(i), dc.norm);
 68		}
 69		dc.x += dc.w;
 70	}
 71	dc.w = blw;
 72	drawtext(lt->symbol, dc.norm);
 73	x = dc.x + dc.w;
 74	dc.w = textw(stext);
 75	dc.x = sw - dc.w;
 76	if(dc.x < x) {
 77		dc.x = x;
 78		dc.w = sw - x;
 79	}
 80	drawtext(stext, dc.norm);
 81	if((dc.w = dc.x - x) > bh) {
 82		dc.x = x;
 83		if(sel) {
 84			drawtext(sel->name, dc.sel);
 85			drawsquare(sel->ismax, sel->isfloating, dc.sel);
 86		}
 87		else
 88			drawtext(NULL, dc.norm);
 89	}
 90	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
 91	XSync(dpy, False);
 92}
 93
 94void
 95drawtext(const char *text, unsigned long col[ColLast]) {
 96	int x, y, w, h;
 97	static char buf[256];
 98	unsigned int len, olen;
 99	XRectangle r = { dc.x, dc.y, dc.w, dc.h };
100
101	XSetForeground(dpy, dc.gc, col[ColBG]);
102	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
103	if(!text)
104		return;
105	w = 0;
106	olen = len = strlen(text);
107	if(len >= sizeof buf)
108		len = sizeof buf - 1;
109	memcpy(buf, text, len);
110	buf[len] = 0;
111	h = dc.font.ascent + dc.font.descent;
112	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
113	x = dc.x + (h / 2);
114	/* shorten text if necessary */
115	while(len && (w = textnw(buf, len)) > dc.w - h)
116		buf[--len] = 0;
117	if(len < olen) {
118		if(len > 1)
119			buf[len - 1] = '.';
120		if(len > 2)
121			buf[len - 2] = '.';
122		if(len > 3)
123			buf[len - 3] = '.';
124	}
125	if(w > dc.w)
126		return; /* too long */
127	XSetForeground(dpy, dc.gc, col[ColFG]);
128	if(dc.font.set)
129		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
130	else
131		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
132}
133
134unsigned int
135textw(const char *text) {
136	return textnw(text, strlen(text)) + dc.font.height;
137}