remove textwidth_primitive
[awesome.git] / statusbar.c
blobaf7d85a9a8c7de7f29429cd98c29e5d110e8206f
1 /*
2 * statusbar.c - statusbar functions
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
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 <stdio.h>
23 #include <math.h>
25 #include "layout.h"
26 #include "statusbar.h"
27 #include "draw.h"
28 #include "screen.h"
29 #include "util.h"
30 #include "tag.h"
31 #include "widget.h"
33 extern AwesomeConf globalconf;
35 void
36 statusbar_draw(int screen)
38 int phys_screen = get_phys_screen(screen);
39 VirtScreen vscreen;
40 Widget *widget, *last_drawn = NULL;
41 int left = 0, right = 0;
43 vscreen = globalconf.screens[screen];
44 /* don't waste our time */
45 if(vscreen.statusbar->position == BarOff)
46 return;
48 DrawCtx *ctx = draw_get_context(phys_screen,
49 vscreen.statusbar->width,
50 vscreen.statusbar->height);
51 draw_rectangle(ctx,
54 vscreen.statusbar->width,
55 vscreen.statusbar->height,
56 True,
57 vscreen.colors_normal[ColBG]);
58 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
59 if (widget->alignment == AlignLeft)
60 left += widget->draw(widget, ctx, left, (left + right));
62 /* renders right widget from last to first */
63 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
64 if (widget->alignment == AlignRight && last_drawn == widget->next)
66 right += widget->draw(widget, ctx, right, (left + right));
67 last_drawn = widget;
68 widget = vscreen.statusbar->widgets;
71 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
72 if (widget->alignment == AlignFlex)
73 left += widget->draw(widget, ctx, left, (left + right));
75 if(vscreen.statusbar->position == BarRight
76 || vscreen.statusbar->position == BarLeft)
78 Drawable d;
79 if(vscreen.statusbar->position == BarRight)
80 d = draw_rotate(ctx,
81 phys_screen,
82 M_PI_2,
83 vscreen.statusbar->height,
84 0);
85 else
86 d = draw_rotate(ctx,
87 phys_screen,
88 - M_PI_2,
90 vscreen.statusbar->width);
92 vscreen.statusbar->drawable = d;
93 draw_free_context(ctx);
95 else
97 vscreen.statusbar->drawable = ctx->drawable;
98 /* just delete the struct, don't delete the drawable */
99 p_delete(&ctx);
103 statusbar_display(screen);
107 void
108 statusbar_display(int screen)
110 VirtScreen vscreen = globalconf.screens[screen];
111 int phys_screen = get_phys_screen(screen);
113 if(vscreen.statusbar->position == BarRight
114 || vscreen.statusbar->position == BarLeft)
115 XCopyArea(globalconf.display, vscreen.statusbar->drawable,
116 vscreen.statusbar->window,
117 DefaultGC(globalconf.display, phys_screen), 0, 0,
118 vscreen.statusbar->height,
119 vscreen.statusbar->width, 0, 0);
120 else
121 XCopyArea(globalconf.display, vscreen.statusbar->drawable,
122 vscreen.statusbar->window,
123 DefaultGC(globalconf.display, phys_screen), 0, 0,
124 vscreen.statusbar->width, vscreen.statusbar->height, 0, 0);
127 void
128 statusbar_init(int screen)
130 Widget *widget;
131 XSetWindowAttributes wa;
132 int phys_screen = get_phys_screen(screen);
133 Area area = get_screen_area(screen,
134 NULL,
135 &globalconf.screens[screen].padding);
136 Statusbar *statusbar = globalconf.screens[screen].statusbar;
138 statusbar->height = globalconf.screens[screen].font->height * 1.5;
140 for(widget = statusbar->widgets; widget; widget = widget->next)
141 if(widget->font)
142 statusbar->height = MAX(statusbar->height, widget->font->height);
144 if(statusbar->position == BarRight || statusbar->position == BarLeft)
145 statusbar->width = area.height;
146 else
147 statusbar->width = area.width;
149 statusbar->screen = screen;
151 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
152 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
153 wa.cursor = globalconf.cursor[CurNormal];
154 wa.override_redirect = 1;
155 wa.background_pixmap = ParentRelative;
156 wa.event_mask = ButtonPressMask | ExposureMask;
157 if(statusbar->dposition == BarRight || statusbar->dposition == BarLeft)
158 statusbar->window = XCreateWindow(globalconf.display,
159 RootWindow(globalconf.display,
160 phys_screen),
161 0, 0,
162 statusbar->height,
163 statusbar->width,
165 DefaultDepth(globalconf.display,
166 phys_screen),
167 CopyFromParent,
168 DefaultVisual(globalconf.display,
169 phys_screen),
170 CWOverrideRedirect |
171 CWBackPixmap |
172 CWEventMask,
173 &wa);
174 else
175 statusbar->window = XCreateWindow(globalconf.display,
176 RootWindow(globalconf.display,
177 phys_screen),
178 0, 0,
179 statusbar->width,
180 statusbar->height,
182 DefaultDepth(globalconf.display,
183 phys_screen),
184 CopyFromParent,
185 DefaultVisual(globalconf.display,
186 phys_screen),
187 CWOverrideRedirect |
188 CWBackPixmap |
189 CWEventMask,
190 &wa);
192 statusbar->drawable = XCreatePixmap(globalconf.display,
193 RootWindow(globalconf.display, phys_screen),
194 statusbar->width, statusbar->height,
195 DefaultDepth(globalconf.display, phys_screen));
198 XDefineCursor(globalconf.display,
199 statusbar->window,
200 globalconf.cursor[CurNormal]);
202 widget_calculate_alignments(statusbar->widgets);
204 statusbar_update_position(screen);
205 XMapRaised(globalconf.display, statusbar->window);
208 void
209 statusbar_update_position(int screen)
211 XEvent ev;
212 Statusbar *statusbar = globalconf.screens[screen].statusbar;
213 Area area = get_screen_area(statusbar->screen,
214 NULL,
215 &globalconf.screens[screen].padding);
217 XMapRaised(globalconf.display, statusbar->window);
218 switch (statusbar->position)
220 default:
221 XMoveWindow(globalconf.display,
222 statusbar->window,
223 area.x,
224 area.y);
225 break;
226 case BarRight:
227 XMoveWindow(globalconf.display,
228 statusbar->window,
229 area.x + (area.width - statusbar->height),
230 area.y);
231 break;
232 case BarBot:
233 XMoveWindow(globalconf.display,
234 statusbar->window,
235 area.x,
236 area.height - statusbar->height);
237 break;
238 case BarOff:
239 XUnmapWindow(globalconf.display, statusbar->window);
240 break;
242 XSync(globalconf.display, False);
243 while(XCheckMaskEvent(globalconf.display, EnterWindowMask, &ev));
247 statusbar_get_position_from_str(const char * pos)
249 if(!a_strncmp(pos, "off", 3))
250 return BarOff;
251 else if(!a_strncmp(pos, "bottom", 6))
252 return BarBot;
253 else if(!a_strncmp(pos, "right", 5))
254 return BarRight;
255 else if(!a_strncmp(pos, "left", 4))
256 return BarLeft;
257 return BarTop;
260 /** Toggle statusbar
261 * \param screen Screen ID
262 * \param arg Unused
263 * \ingroup ui_callback
265 void
266 uicb_statusbar_toggle(int screen, char *arg __attribute__ ((unused)))
268 if(globalconf.screens[screen].statusbar->position == BarOff)
269 globalconf.screens[screen].statusbar->position = (globalconf.screens[screen].statusbar->dposition == BarOff) ? BarTop : globalconf.screens[screen].statusbar->dposition;
270 else
271 globalconf.screens[screen].statusbar->position = BarOff;
272 statusbar_update_position(screen);
273 arrange(screen);
276 /** Set statusbar position
277 * \param screen Screen ID
278 * \param arg off | bottom | right | left | top
279 * \ingroup ui_callback
281 void
282 uicb_statusbar_set_position(int screen, char *arg)
284 globalconf.screens[screen].statusbar->dposition =
285 globalconf.screens[screen].statusbar->position =
286 statusbar_get_position_from_str(arg);
287 statusbar_update_position(screen);
290 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80