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