cosmetic + copyright
[awesome.git] / statusbar.c
blob20cd3bb41020eb7436793596d7738fd4f9dae029
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;
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(globalconf.display, phys_screen,
49 vscreen.statusbar->width,
50 vscreen.statusbar->height);
51 drawrectangle(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));
61 else if (widget->alignment == AlignRight)
62 right += widget->draw(widget, ctx, right, (left + right));
64 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
65 if (widget->alignment == AlignFlex)
66 left += widget->draw(widget, ctx, left, (left + right));
68 if(vscreen.statusbar->position == BarRight ||
69 vscreen.statusbar->position == BarLeft)
71 Drawable d;
72 if(vscreen.statusbar->position == BarRight)
73 d = draw_rotate(ctx,
74 phys_screen,
75 M_PI_2,
76 vscreen.statusbar->height,
77 0);
78 else
79 d = draw_rotate(ctx,
80 phys_screen,
81 - M_PI_2,
83 vscreen.statusbar->width);
84 XCopyArea(globalconf.display, d,
85 vscreen.statusbar->window,
86 DefaultGC(globalconf.display, phys_screen), 0, 0,
87 vscreen.statusbar->height,
88 vscreen.statusbar->width, 0, 0);
89 XFreePixmap(globalconf.display, d);
91 else
92 XCopyArea(globalconf.display, ctx->drawable,
93 vscreen.statusbar->window,
94 DefaultGC(globalconf.display, phys_screen), 0, 0,
95 vscreen.statusbar->width, vscreen.statusbar->height, 0, 0);
97 draw_free_context(ctx);
98 XSync(globalconf.display, False);
101 void
102 statusbar_init(int screen)
104 XSetWindowAttributes wa;
105 int phys_screen = get_phys_screen(screen);
106 ScreenInfo *si = get_screen_info(screen,
107 NULL,
108 &globalconf.screens[screen].padding);
109 Statusbar *statusbar = globalconf.screens[screen].statusbar;
111 statusbar->height = globalconf.screens[screen].font->height * 1.5;
113 if(statusbar->position == BarRight || statusbar->position == BarLeft)
114 statusbar->width = si[screen].height;
115 else
116 statusbar->width = si[screen].width;
118 p_delete(&si);
120 statusbar->screen = screen;
122 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
123 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
124 wa.cursor = globalconf.cursor[CurNormal];
125 wa.override_redirect = 1;
126 wa.background_pixmap = ParentRelative;
127 wa.event_mask = ButtonPressMask | ExposureMask;
128 if(statusbar->dposition == BarRight || statusbar->dposition == BarLeft)
129 statusbar->window = XCreateWindow(globalconf.display,
130 RootWindow(globalconf.display,
131 phys_screen),
132 0, 0,
133 statusbar->height,
134 statusbar->width,
136 DefaultDepth(globalconf.display,
137 phys_screen),
138 CopyFromParent,
139 DefaultVisual(globalconf.display,
140 phys_screen),
141 CWOverrideRedirect |
142 CWBackPixmap |
143 CWEventMask,
144 &wa);
145 else
146 statusbar->window = XCreateWindow(globalconf.display,
147 RootWindow(globalconf.display,
148 phys_screen),
149 0, 0,
150 statusbar->width,
151 statusbar->height,
153 DefaultDepth(globalconf.display,
154 phys_screen),
155 CopyFromParent,
156 DefaultVisual(globalconf.display,
157 phys_screen),
158 CWOverrideRedirect |
159 CWBackPixmap |
160 CWEventMask,
161 &wa);
162 XDefineCursor(globalconf.display,
163 statusbar->window,
164 globalconf.cursor[CurNormal]);
166 calculate_alignments(statusbar->widgets);
168 statusbar_update_position(globalconf.display,
169 statusbar,
170 &globalconf.screens[screen].padding);
171 XMapRaised(globalconf.display, statusbar->window);
174 void
175 statusbar_update_position(Display *disp, Statusbar *statusbar, Padding *padding)
177 XEvent ev;
178 ScreenInfo *si = get_screen_info(statusbar->screen, NULL, padding);
180 XMapRaised(disp, statusbar->window);
181 switch (statusbar->position)
183 default:
184 XMoveWindow(disp, statusbar->window, si[statusbar->screen].x_org, si[statusbar->screen].y_org);
185 break;
186 case BarRight:
187 XMoveWindow(disp, statusbar->window, si[statusbar->screen].x_org + (si[statusbar->screen].width - statusbar->height), si[statusbar->screen].y_org);
188 break;
189 case BarBot:
190 XMoveWindow(disp, statusbar->window, si[statusbar->screen].x_org, si[statusbar->screen].height - statusbar->height);
191 break;
192 case BarOff:
193 XUnmapWindow(disp, statusbar->window);
194 break;
196 p_delete(&si);
197 XSync(disp, False);
198 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
202 statusbar_get_position_from_str(const char * pos)
204 if(!a_strncmp(pos, "off", 3))
205 return BarOff;
206 else if(!a_strncmp(pos, "bottom", 6))
207 return BarBot;
208 else if(!a_strncmp(pos, "right", 5))
209 return BarRight;
210 else if(!a_strncmp(pos, "left", 4))
211 return BarLeft;
212 return BarTop;
215 /** Toggle statusbar
216 * \param screen Screen ID
217 * \param arg Unused
218 * \ingroup ui_callback
220 void
221 uicb_statusbar_toggle(int screen, char *arg __attribute__ ((unused)))
223 if(globalconf.screens[screen].statusbar->position == BarOff)
224 globalconf.screens[screen].statusbar->position = (globalconf.screens[screen].statusbar->dposition == BarOff) ? BarTop : globalconf.screens[screen].statusbar->dposition;
225 else
226 globalconf.screens[screen].statusbar->position = BarOff;
227 statusbar_update_position(globalconf.display, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding);
228 arrange(screen);
231 /** Set statusbar position
232 * \param screen Screen ID
233 * \param arg off | bottom | right | left | top
234 * \ingroup ui_callback
236 void
237 uicb_statusbar_set_position(int screen, char *arg)
239 globalconf.screens[screen].statusbar->dposition =
240 globalconf.screens[screen].statusbar->position =
241 statusbar_get_position_from_str(arg);
242 statusbar_update_position(globalconf.display,
243 globalconf.screens[screen].statusbar,
244 &globalconf.screens[screen].padding);
247 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80