Xft support
[awesome.git] / statusbar.c
blob05211f10522cba330a68258ad601cada87f4b1d9
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 <stdio.h>
24 #include "layout.h"
25 #include "statusbar.h"
26 #include "draw.h"
27 #include "screen.h"
28 #include "util.h"
29 #include "layouts/tile.h"
31 extern Client *clients, *sel, *stack; /* global client list and stack */
33 /** Check if at least a client is tagged with tag number t and is on screen
34 * screen
35 * \param t tag number
36 * \param screen screen number
37 * \return True or False
39 static Bool
40 isoccupied(unsigned int t, int screen)
42 Client *c;
44 for(c = clients; c; c = c->next)
45 if(c->tags[t] && c->screen == screen)
46 return True;
47 return False;
50 void
51 drawstatusbar(Display *disp, DC *drawcontext, awesome_config * awesomeconf)
53 int x, i;
54 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, NULL, &i);
56 drawcontext->x = drawcontext->y = 0;
57 for(i = 0; i < awesomeconf->ntags; i++)
59 drawcontext->w = textwidth(disp, drawcontext->font, awesomeconf->tags[i].name, a_strlen(awesomeconf->tags[i].name)) + drawcontext->font->height;
60 if(awesomeconf->tags[i].selected)
62 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, awesomeconf->tags[i].name, drawcontext->sel, drawcontext->text_selected);
63 if(isoccupied(i, awesomeconf->screen))
64 drawsquare(disp, *drawcontext, awesomeconf->statusbar.drawable, sel && sel->tags[i], drawcontext->sel[ColFG]);
66 else
68 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, awesomeconf->tags[i].name, drawcontext->norm, drawcontext->text_normal);
69 if(isoccupied(i, awesomeconf->screen))
70 drawsquare(disp, *drawcontext, awesomeconf->statusbar.drawable, sel && sel->tags[i], drawcontext->norm[ColFG]);
72 drawcontext->x += drawcontext->w;
74 drawcontext->w = awesomeconf->statusbar.width;
75 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, awesomeconf->current_layout->symbol, drawcontext->norm, drawcontext->text_normal);
76 x = drawcontext->x + drawcontext->w;
77 drawcontext->w = textwidth(disp, drawcontext->font, awesomeconf->statustext, a_strlen(awesomeconf->statustext)) + drawcontext->font->height;
78 drawcontext->x = si[awesomeconf->screen].width - drawcontext->w;
79 if(drawcontext->x < x)
81 drawcontext->x = x;
82 drawcontext->w = si[awesomeconf->screen].width - x;
84 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, awesomeconf->statustext, drawcontext->norm, drawcontext->text_normal);
85 if((drawcontext->w = drawcontext->x - x) > awesomeconf->statusbar.height)
87 drawcontext->x = x;
88 if(sel)
90 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, sel->name, drawcontext->sel, drawcontext->text_selected);
91 if(sel->isfloating)
92 drawsquare(disp, *drawcontext, awesomeconf->statusbar.drawable, sel->ismax, drawcontext->sel[ColFG]);
94 else if(IS_ARRANGE(layout_tile) || IS_ARRANGE(layout_tileleft))
96 char buf[256];
97 snprintf(buf, sizeof(buf), "nmaster: %d ncols: %d mwfact: %.2lf", awesomeconf->nmaster, awesomeconf->ncols, awesomeconf->mwfact);
98 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, buf, drawcontext->norm, drawcontext->text_normal);
100 else
101 drawtext(disp, awesomeconf->phys_screen, drawcontext, awesomeconf->statusbar.drawable, NULL, drawcontext->norm, drawcontext->text_normal);
103 XCopyArea(disp, awesomeconf->statusbar.drawable, awesomeconf->statusbar.window, drawcontext->gc, 0, 0, si[awesomeconf->screen].width, awesomeconf->statusbar.height, 0, 0);
104 XSync(disp, False);
107 void
108 initstatusbar(Display *disp, int screen, DC *drawcontext, Statusbar *statusbar)
110 XSetWindowAttributes wa;
111 int screen_number, phys_screen;
112 ScreenInfo *si;
114 phys_screen = get_phys_screen(disp, screen);
116 statusbar->screen = screen;
118 si = get_screen_info(disp, screen, NULL, &screen_number);
120 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
121 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
122 wa.cursor = drawcontext->cursor[CurNormal];
123 wa.override_redirect = 1;
124 wa.background_pixmap = ParentRelative;
125 wa.event_mask = ButtonPressMask | ExposureMask;
126 statusbar->window = XCreateWindow(disp, RootWindow(disp, phys_screen), 0, 0, si[screen].width,
127 statusbar->height, 0, DefaultDepth(disp, phys_screen), CopyFromParent,
128 DefaultVisual(disp, phys_screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
129 XDefineCursor(disp, statusbar->window, drawcontext->cursor[CurNormal]);
130 updatebarpos(disp, *statusbar);
131 XMapRaised(disp, statusbar->window);
132 statusbar->drawable = XCreatePixmap(disp,
133 RootWindow(disp, phys_screen),
134 si[screen].width,
135 statusbar->height,
136 DefaultDepth(disp, phys_screen));
139 void
140 updatebarpos(Display *disp, Statusbar statusbar)
142 XEvent ev;
143 int dummy;
144 ScreenInfo *si = get_screen_info(disp, statusbar.screen, NULL, &dummy);
146 switch (statusbar.position)
148 default:
149 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].y_org);
150 break;
151 case BarBot:
152 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].height - statusbar.height);
153 break;
154 case BarOff:
155 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].y_org - statusbar.height);
156 break;
158 XFree(si);
159 XSync(disp, False);
160 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
163 void
164 uicb_togglebar(Display *disp,
165 DC *drawcontext,
166 awesome_config *awesomeconf,
167 const char *arg __attribute__ ((unused)))
169 if(awesomeconf->statusbar.position == BarOff)
170 awesomeconf->statusbar.position = (awesomeconf->statusbar.position == BarOff) ? BarTop : awesomeconf->statusbar_default_position;
171 else
172 awesomeconf->statusbar.position = BarOff;
173 updatebarpos(disp, awesomeconf->statusbar);
174 arrange(disp, drawcontext, awesomeconf);