chance license to GPLv2
[awesome.git] / draw.c
blobd3054e3d6b5868182dcf3ddb8aa3997ed497be15
1 /*
2 * draw.c - draw functions
3 *
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "layout.h"
24 extern DC dc; /* global draw context */
25 extern Client *clients, *sel, *stack; /* global client list and stack */
27 /* static */
29 static void
30 drawtext(Display *disp, const char *text, unsigned long col[ColLast])
32 int x, y, w, h;
33 static char buf[256];
34 unsigned int len, olen;
35 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
37 XSetForeground(disp, dc.gc, col[ColBG]);
38 XFillRectangles(disp, dc.drawable, dc.gc, &r, 1);
39 if(!text)
40 return;
41 w = 0;
42 olen = len = a_strlen(text);
43 if(len >= sizeof buf)
44 len = sizeof buf - 1;
45 memcpy(buf, text, len);
46 buf[len] = 0;
47 h = dc.font.ascent + dc.font.descent;
48 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
49 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(w > dc.w)
54 return; /* too long */
55 if(len < olen)
57 if(len > 1)
58 buf[len - 1] = '.';
59 if(len > 2)
60 buf[len - 2] = '.';
61 if(len > 3)
62 buf[len - 3] = '.';
64 XSetForeground(disp, dc.gc, col[ColFG]);
65 if(dc.font.set)
66 XmbDrawString(disp, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
67 else
68 XDrawString(disp, dc.drawable, dc.gc, x, y, buf, len);
71 static void
72 drawsquare(Bool filled, Bool empty, unsigned long col[ColLast], Display *disp)
74 int x;
75 XGCValues gcv;
76 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
78 gcv.foreground = col[ColFG];
79 XChangeGC(disp, dc.gc, GCForeground, &gcv);
80 x = (dc.font.ascent + dc.font.descent + 2) / 4;
81 r.x = dc.x + 1;
82 r.y = dc.y + 1;
83 if(filled)
85 r.width = r.height = x + 1;
86 XFillRectangles(disp, dc.drawable, dc.gc, &r, 1);
88 else if(empty)
90 r.width = r.height = x;
91 XDrawRectangles(disp, dc.drawable, dc.gc, &r, 1);
95 /** Check if at least a client is tagged with tag number t
96 * \param t tag number
97 * \return True or False
99 static Bool
100 isoccupied(unsigned int t)
102 Client *c;
104 for(c = clients; c; c = c->next)
105 if(c->tags[t])
106 return True;
107 return False;
111 /* extern */
113 unsigned int
114 textnw(const char *text, unsigned int len)
116 XRectangle r;
118 if(dc.font.set)
120 XmbTextExtents(dc.font.set, text, len, NULL, &r);
121 return r.width;
123 return XTextWidth(dc.font.xfont, text, len);
126 void
127 drawstatus(Display *disp, awesome_config * awesomeconf)
129 int x, i;
130 dc.x = dc.y = 0;
131 for(i = 0; i < awesomeconf->ntags; i++)
133 dc.w = textw(awesomeconf->tags[i]);
134 if(awesomeconf->selected_tags[i])
136 drawtext(disp, awesomeconf->tags[i], dc.sel);
137 drawsquare(sel && sel->tags[i], isoccupied(i), dc.sel, disp);
139 else
141 drawtext(disp, awesomeconf->tags[i], dc.norm);
142 drawsquare(sel && sel->tags[i], isoccupied(i), dc.norm, disp);
144 dc.x += dc.w;
146 dc.w = awesomeconf->statusbar.width;
147 drawtext(disp, awesomeconf->current_layout->symbol, dc.norm);
148 x = dc.x + dc.w;
149 dc.w = textw(awesomeconf->statustext);
150 dc.x = DisplayWidth(disp, DefaultScreen(disp)) - dc.w;
151 if(dc.x < x)
153 dc.x = x;
154 dc.w = DisplayWidth(disp, DefaultScreen(disp)) - x;
156 drawtext(disp, awesomeconf->statustext, dc.norm);
157 if((dc.w = dc.x - x) > awesomeconf->statusbar.height)
159 dc.x = x;
160 if(sel)
162 drawtext(disp, sel->name, dc.sel);
163 drawsquare(sel->ismax, sel->isfloating, dc.sel, disp);
165 else
166 drawtext(disp, NULL, dc.norm);
168 XCopyArea(disp, dc.drawable, awesomeconf->statusbar.window, dc.gc, 0, 0, DisplayWidth(disp, DefaultScreen(disp)), awesomeconf->statusbar.height, 0, 0);
169 XSync(disp, False);