draw.c
changeset 777 469dc170f833
parent 776 be103ae46dbc
child 778 2ec66bdbb8ad
equal deleted inserted replaced
776:be103ae46dbc 777:469dc170f833
     1 /* (C)opyright MMIV-MMVII 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 
       
     8 /* static */
       
     9 
       
    10 static Bool
       
    11 isoccupied(unsigned int t)
       
    12 {
       
    13 	Client *c;
       
    14 	for(c = clients; c; c = c->next)
       
    15 		if(c->tags[t])
       
    16 			return True;
       
    17 	return False;
       
    18 }
       
    19 
       
    20 static unsigned int
       
    21 textnw(const char *text, unsigned int len) {
       
    22 	XRectangle r;
       
    23 
       
    24 	if(dc.font.set) {
       
    25 		XmbTextExtents(dc.font.set, text, len, NULL, &r);
       
    26 		return r.width;
       
    27 	}
       
    28 	return XTextWidth(dc.font.xfont, text, len);
       
    29 }
       
    30 
       
    31 static void
       
    32 drawtext(const char *text, unsigned long col[ColLast], Bool filledsquare, Bool emptysquare) {
       
    33 	int x, y, w, h;
       
    34 	static char buf[256];
       
    35 	unsigned int len, olen;
       
    36 	XGCValues gcv;
       
    37 	XRectangle r = { dc.x, dc.y, dc.w, dc.h };
       
    38 
       
    39 	XSetForeground(dpy, dc.gc, col[ColBG]);
       
    40 	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
       
    41 	if(!text)
       
    42 		return;
       
    43 	w = 0;
       
    44 	olen = len = strlen(text);
       
    45 	if(len >= sizeof buf)
       
    46 		len = sizeof buf - 1;
       
    47 	memcpy(buf, text, len);
       
    48 	buf[len] = 0;
       
    49 	h = dc.font.ascent + dc.font.descent;
       
    50 	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
       
    51 	x = dc.x + (h / 2);
       
    52 	/* shorten text if necessary */
       
    53 	while(len && (w = textnw(buf, len)) > dc.w - h)
       
    54 		buf[--len] = 0;
       
    55 	if(len < olen) {
       
    56 		if(len > 1)
       
    57 			buf[len - 1] = '.';
       
    58 		if(len > 2)
       
    59 			buf[len - 2] = '.';
       
    60 		if(len > 3)
       
    61 			buf[len - 3] = '.';
       
    62 	}
       
    63 	if(w > dc.w)
       
    64 		return; /* too long */
       
    65 	gcv.foreground = col[ColFG];
       
    66 	if(dc.font.set) {
       
    67 		XChangeGC(dpy, dc.gc, GCForeground, &gcv);
       
    68 		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
       
    69 	}
       
    70 	else {
       
    71 		gcv.font = dc.font.xfont->fid;
       
    72 		XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
       
    73 		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
       
    74 	}
       
    75 	x = (h + 2) / 4;
       
    76 	r.x = dc.x + 1;
       
    77 	r.y = dc.y + 1;
       
    78 	if(filledsquare) {
       
    79 		r.width = r.height = x + 1;
       
    80 		XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
       
    81 	}
       
    82 	else if(emptysquare) {
       
    83 		r.width = r.height = x;
       
    84 		XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
       
    85 	}
       
    86 }
       
    87 
       
    88 /* extern */
       
    89 
       
    90 void
       
    91 drawstatus(void) {
       
    92 	int i, x;
       
    93 
       
    94 	dc.x = dc.y = 0;
       
    95 	for(i = 0; i < ntags; i++) {
       
    96 		dc.w = textw(tags[i]);
       
    97 		if(seltag[i])
       
    98 			drawtext(tags[i], dc.sel, sel && sel->tags[i], isoccupied(i));
       
    99 		else
       
   100 			drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i));
       
   101 		dc.x += dc.w;
       
   102 	}
       
   103 	dc.w = bmw;
       
   104 	drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.norm, False, False);
       
   105 	x = dc.x + dc.w;
       
   106 	dc.w = textw(stext);
       
   107 	dc.x = sw - dc.w;
       
   108 	if(dc.x < x) {
       
   109 		dc.x = x;
       
   110 		dc.w = sw - x;
       
   111 	}
       
   112 	drawtext(stext, dc.norm, False, False);
       
   113 	if((dc.w = dc.x - x) > bh) {
       
   114 		dc.x = x;
       
   115 		drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm, False, False);
       
   116 	}
       
   117 	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
       
   118 	XSync(dpy, False);
       
   119 }
       
   120 
       
   121 unsigned long
       
   122 getcolor(const char *colstr) {
       
   123 	Colormap cmap = DefaultColormap(dpy, screen);
       
   124 	XColor color;
       
   125 
       
   126 	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
       
   127 		eprint("error, cannot allocate color '%s'\n", colstr);
       
   128 	return color.pixel;
       
   129 }
       
   130 
       
   131 void
       
   132 setfont(const char *fontstr) {
       
   133 	char *def, **missing;
       
   134 	int i, n;
       
   135 
       
   136 	missing = NULL;
       
   137 	if(dc.font.set)
       
   138 		XFreeFontSet(dpy, dc.font.set);
       
   139 	dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
       
   140 	if(missing) {
       
   141 		while(n--)
       
   142 			fprintf(stderr, "missing fontset: %s\n", missing[n]);
       
   143 		XFreeStringList(missing);
       
   144 	}
       
   145 	if(dc.font.set) {
       
   146 		XFontSetExtents *font_extents;
       
   147 		XFontStruct **xfonts;
       
   148 		char **font_names;
       
   149 		dc.font.ascent = dc.font.descent = 0;
       
   150 		font_extents = XExtentsOfFontSet(dc.font.set);
       
   151 		n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
       
   152 		for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
       
   153 			if(dc.font.ascent < (*xfonts)->ascent)
       
   154 				dc.font.ascent = (*xfonts)->ascent;
       
   155 			if(dc.font.descent < (*xfonts)->descent)
       
   156 				dc.font.descent = (*xfonts)->descent;
       
   157 			xfonts++;
       
   158 		}
       
   159 	}
       
   160 	else {
       
   161 		if(dc.font.xfont)
       
   162 			XFreeFont(dpy, dc.font.xfont);
       
   163 		dc.font.xfont = NULL;
       
   164 		if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
       
   165 			eprint("error, cannot load font: '%s'\n", fontstr);
       
   166 		dc.font.ascent = dc.font.xfont->ascent;
       
   167 		dc.font.descent = dc.font.xfont->descent;
       
   168 	}
       
   169 	dc.font.height = dc.font.ascent + dc.font.descent;
       
   170 }
       
   171 
       
   172 unsigned int
       
   173 textw(const char *text) {
       
   174 	return textnw(text, strlen(text)) + dc.font.height;
       
   175 }