draw the handle without borders
[mikachu/openbox.git] / openbox / framerender.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    framerender.c for the Openbox window manager
4    Copyright (c) 2006        Mikael Magnusson
5    Copyright (c) 2003-2007   Dana Jansens
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "frame.h"
21 #include "openbox.h"
22 #include "screen.h"
23 #include "client.h"
24 #include "framerender.h"
25 #include "render/theme.h"
26
27 static void framerender_label(ObFrame *self, RrAppearance *a);
28 static void framerender_icon(ObFrame *self, RrAppearance *a);
29 static void framerender_max(ObFrame *self, RrAppearance *a);
30 static void framerender_iconify(ObFrame *self, RrAppearance *a);
31 static void framerender_desk(ObFrame *self, RrAppearance *a);
32 static void framerender_shade(ObFrame *self, RrAppearance *a);
33 static void framerender_close(ObFrame *self, RrAppearance *a);
34
35 void framerender_frame(ObFrame *self)
36 {
37     {
38         gulong px;
39
40         px = (self->focused ?
41               RrColorPixel(ob_rr_theme->cb_focused_color) :
42               RrColorPixel(ob_rr_theme->cb_unfocused_color));
43         XSetWindowBackground(ob_display, self->inner, px);
44         XClearWindow(ob_display, self->inner);
45
46         px = (self->focused ?
47               RrColorPixel(ob_rr_theme->frame_focused_border_color) :
48               RrColorPixel(ob_rr_theme->frame_unfocused_border_color));
49
50         XSetWindowBackground(ob_display, self->left, px);
51         XClearWindow(ob_display, self->left);
52         XSetWindowBackground(ob_display, self->right, px);
53         XClearWindow(ob_display, self->right);
54
55         XSetWindowBackground(ob_display, self->titleleft, px);
56         XClearWindow(ob_display, self->titleleft);
57         XSetWindowBackground(ob_display, self->titletop, px);
58         XClearWindow(ob_display, self->titletop);
59         XSetWindowBackground(ob_display, self->titletopleft, px);
60         XClearWindow(ob_display, self->titletopleft);
61         XSetWindowBackground(ob_display, self->titletopright, px);
62         XClearWindow(ob_display, self->titletopright);
63         XSetWindowBackground(ob_display, self->titleright, px);
64         XClearWindow(ob_display, self->titleright);
65         XSetWindowBackground(ob_display, self->titlebottom, px);
66         XClearWindow(ob_display, self->titlebottom);
67
68         XSetWindowBackground(ob_display, self->handleleft, px);
69         XClearWindow(ob_display, self->handleleft);
70         XSetWindowBackground(ob_display, self->handletop, px);
71         XClearWindow(ob_display, self->handletop);
72         XSetWindowBackground(ob_display, self->handleright, px);
73         XClearWindow(ob_display, self->handleright);
74         XSetWindowBackground(ob_display, self->handlebottom, px);
75         XClearWindow(ob_display, self->handlebottom);
76
77         XSetWindowBackground(ob_display, self->lgripleft, px);
78         XClearWindow(ob_display, self->lgripleft);
79         XSetWindowBackground(ob_display, self->lgriptop, px);
80         XClearWindow(ob_display, self->lgriptop);
81         XSetWindowBackground(ob_display, self->lgripbottom, px);
82         XClearWindow(ob_display, self->lgripbottom);
83
84         XSetWindowBackground(ob_display, self->rgripright, px);
85         XClearWindow(ob_display, self->rgripright);
86         XSetWindowBackground(ob_display, self->rgriptop, px);
87         XClearWindow(ob_display, self->rgriptop);
88         XSetWindowBackground(ob_display, self->rgripbottom, px);
89         XClearWindow(ob_display, self->rgripbottom);
90     }
91
92     if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
93         RrAppearance *t, *l, *m, *n, *i, *d, *s, *c;
94         if (self->focused) {
95
96             t = self->a_focused_title;
97             l = self->a_focused_label;
98
99             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
100                  ob_rr_theme->a_disabled_focused_max :
101                  (self->client->max_vert || self->client->max_horz ?
102                   (self->max_press ?
103                    ob_rr_theme->a_toggled_focused_pressed_max :
104                    (self->max_hover ?
105                     ob_rr_theme->a_toggled_hover_focused_max : 
106                     ob_rr_theme->a_toggled_focused_unpressed_max)) :
107                   (self->max_press ?
108                    ob_rr_theme->a_focused_pressed_max :
109                    (self->max_hover ?
110                     ob_rr_theme->a_hover_focused_max : 
111                     ob_rr_theme->a_focused_unpressed_max))));
112             n = self->a_icon;
113             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
114                  ob_rr_theme->a_disabled_focused_iconify :
115                  (self->iconify_press ?
116                   ob_rr_theme->a_focused_pressed_iconify :
117                   (self->iconify_hover ?
118                    ob_rr_theme->a_hover_focused_iconify : 
119                    ob_rr_theme->a_focused_unpressed_iconify)));
120             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
121                  ob_rr_theme->a_disabled_focused_desk :
122                  (self->client->desktop == DESKTOP_ALL ?
123                   (self->desk_press ?
124                    ob_rr_theme->a_toggled_focused_pressed_desk :
125                    (self->desk_hover ?
126                     ob_rr_theme->a_toggled_hover_focused_desk : 
127                     ob_rr_theme->a_toggled_focused_unpressed_desk)) :
128                   (self->desk_press ?
129                    ob_rr_theme->a_focused_pressed_desk :
130                    (self->desk_hover ?
131                     ob_rr_theme->a_hover_focused_desk : 
132                     ob_rr_theme->a_focused_unpressed_desk))));
133             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
134                  ob_rr_theme->a_disabled_focused_shade :
135                  (self->client->shaded ?
136                   (self->shade_press ?
137                    ob_rr_theme->a_toggled_focused_pressed_shade :
138                    (self->shade_hover ?
139                     ob_rr_theme->a_toggled_hover_focused_shade : 
140                     ob_rr_theme->a_toggled_focused_unpressed_shade)) :
141                   (self->shade_press ?
142                    ob_rr_theme->a_focused_pressed_shade :
143                    (self->shade_hover ?
144                     ob_rr_theme->a_hover_focused_shade : 
145                     ob_rr_theme->a_focused_unpressed_shade))));
146             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
147                  ob_rr_theme->a_disabled_focused_close :
148                  (self->close_press ?
149                   ob_rr_theme->a_focused_pressed_close :
150                   (self->close_hover ?
151                    ob_rr_theme->a_hover_focused_close : 
152                    ob_rr_theme->a_focused_unpressed_close)));
153         } else {
154             t = self->a_unfocused_title;
155             l = self->a_unfocused_label;
156             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
157                  ob_rr_theme->a_disabled_unfocused_max :
158                  (self->client->max_vert || self->client->max_horz ?
159                   (self->max_press ?
160                    ob_rr_theme->a_toggled_unfocused_pressed_max :
161                    (self->max_hover ?
162                     ob_rr_theme->a_toggled_hover_unfocused_max : 
163                     ob_rr_theme->a_toggled_unfocused_unpressed_max)) :
164                   (self->max_press ?
165                    ob_rr_theme->a_unfocused_pressed_max :
166                    (self->max_hover ?
167                     ob_rr_theme->a_hover_unfocused_max : 
168                     ob_rr_theme->a_unfocused_unpressed_max))));
169             n = self->a_icon;
170             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
171                  ob_rr_theme->a_disabled_unfocused_iconify :
172                  (self->iconify_press ?
173                   ob_rr_theme->a_unfocused_pressed_iconify :
174                   (self->iconify_hover ?
175                    ob_rr_theme->a_hover_unfocused_iconify : 
176                    ob_rr_theme->a_unfocused_unpressed_iconify)));
177             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
178                  ob_rr_theme->a_disabled_unfocused_desk :
179                  (self->client->desktop == DESKTOP_ALL ?
180                   (self->desk_press ?
181                    ob_rr_theme->a_toggled_unfocused_pressed_desk :
182                    (self->desk_hover ?
183                     ob_rr_theme->a_toggled_hover_unfocused_desk : 
184                     ob_rr_theme->a_toggled_unfocused_unpressed_desk)) :
185                   (self->desk_press ?
186                    ob_rr_theme->a_unfocused_pressed_desk :
187                    (self->desk_hover ?
188                     ob_rr_theme->a_hover_unfocused_desk : 
189                     ob_rr_theme->a_unfocused_unpressed_desk))));
190             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
191                  ob_rr_theme->a_disabled_unfocused_shade :
192                  (self->client->shaded ?
193                   (self->shade_press ?
194                    ob_rr_theme->a_toggled_unfocused_pressed_shade :
195                    (self->shade_hover ?
196                     ob_rr_theme->a_toggled_hover_unfocused_shade : 
197                     ob_rr_theme->a_toggled_unfocused_unpressed_shade)) :
198                   (self->shade_press ?
199                    ob_rr_theme->a_unfocused_pressed_shade :
200                    (self->shade_hover ?
201                     ob_rr_theme->a_hover_unfocused_shade : 
202                     ob_rr_theme->a_unfocused_unpressed_shade))));
203             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
204                  ob_rr_theme->a_disabled_unfocused_close :
205                  (self->close_press ?
206                   ob_rr_theme->a_unfocused_pressed_close :
207                   (self->close_hover ?
208                    ob_rr_theme->a_hover_unfocused_close : 
209                    ob_rr_theme->a_unfocused_unpressed_close)));
210         }
211
212         RrPaint(t, self->title, self->width, ob_rr_theme->title_height);
213
214         ob_rr_theme->a_clear->surface.parent = t;
215         ob_rr_theme->a_clear->surface.parenty = 0;
216
217         ob_rr_theme->a_clear->surface.parentx = ob_rr_theme->grip_width +
218             self->bwidth;
219         RrPaint(ob_rr_theme->a_clear, self->topresize,
220                 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
221                 ob_rr_theme->paddingy + 1);
222
223         ob_rr_theme->a_clear->surface.parentx = 0;
224
225         if (ob_rr_theme->grip_width > 0)
226             RrPaint(ob_rr_theme->a_clear, self->tltresize,
227                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
228         if (ob_rr_theme->title_height > 0)
229             RrPaint(ob_rr_theme->a_clear, self->tllresize,
230                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
231
232         ob_rr_theme->a_clear->surface.parentx =
233             self->width - ob_rr_theme->grip_width;
234
235         if (ob_rr_theme->grip_width > 0)
236             RrPaint(ob_rr_theme->a_clear, self->trtresize,
237                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
238
239         ob_rr_theme->a_clear->surface.parentx =
240             self->width - (ob_rr_theme->paddingx + 1);
241
242         if (ob_rr_theme->title_height > 0)
243             RrPaint(ob_rr_theme->a_clear, self->trrresize,
244                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
245
246         /* set parents for any parent relative guys */
247         l->surface.parent = t;
248         l->surface.parentx = self->label_x;
249         l->surface.parenty = ob_rr_theme->paddingy;
250
251         m->surface.parent = t;
252         m->surface.parentx = self->max_x;
253         m->surface.parenty = ob_rr_theme->paddingy + 1;
254
255         n->surface.parent = t;
256         n->surface.parentx = self->icon_x;
257         n->surface.parenty = ob_rr_theme->paddingy;
258
259         i->surface.parent = t;
260         i->surface.parentx = self->iconify_x;
261         i->surface.parenty = ob_rr_theme->paddingy + 1;
262
263         d->surface.parent = t;
264         d->surface.parentx = self->desk_x;
265         d->surface.parenty = ob_rr_theme->paddingy + 1;
266
267         s->surface.parent = t;
268         s->surface.parentx = self->shade_x;
269         s->surface.parenty = ob_rr_theme->paddingy + 1;
270
271         c->surface.parent = t;
272         c->surface.parentx = self->close_x;
273         c->surface.parenty = ob_rr_theme->paddingy + 1;
274
275         framerender_label(self, l);
276         framerender_max(self, m);
277         framerender_icon(self, n);
278         framerender_iconify(self, i);
279         framerender_desk(self, d);
280         framerender_shade(self, s);
281         framerender_close(self, c);
282     }
283
284     if (self->decorations & OB_FRAME_DECOR_HANDLE &&
285         ob_rr_theme->handle_height > 0)
286     {
287         RrAppearance *h, *g;
288
289         h = (self->focused ?
290              self->a_focused_handle : self->a_unfocused_handle);
291
292         RrPaint(h, self->handle, self->width, ob_rr_theme->handle_height);
293
294         if (self->decorations & OB_FRAME_DECOR_GRIPS) {
295             g = (self->focused ?
296                  ob_rr_theme->a_focused_grip : ob_rr_theme->a_unfocused_grip);
297
298             if (g->surface.grad == RR_SURFACE_PARENTREL)
299                 g->surface.parent = h;
300
301             g->surface.parentx = 0;
302             g->surface.parenty = 0;
303
304             RrPaint(g, self->lgrip,
305                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
306
307             g->surface.parentx = self->width - ob_rr_theme->grip_width;
308             g->surface.parenty = 0;
309
310             RrPaint(g, self->rgrip,
311                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
312         }
313     }
314
315     XFlush(ob_display);
316 }
317
318 static void framerender_label(ObFrame *self, RrAppearance *a)
319 {
320     if (!self->label_on) return;
321     /* set the texture's text! */
322     a->texture[0].data.text.string = self->client->title;
323     RrPaint(a, self->label, self->label_width, ob_rr_theme->label_height);
324 }
325
326 static void framerender_icon(ObFrame *self, RrAppearance *a)
327 {
328     const ObClientIcon *icon;
329
330     if (!self->icon_on) return;
331
332     icon = client_icon(self->client,
333                        ob_rr_theme->button_size + 2,
334                        ob_rr_theme->button_size + 2);
335     if (icon) {
336         a->texture[0].type = RR_TEXTURE_RGBA;
337         a->texture[0].data.rgba.width = icon->width;
338         a->texture[0].data.rgba.height = icon->height;
339         a->texture[0].data.rgba.data = icon->data;
340     } else
341         a->texture[0].type = RR_TEXTURE_NONE;
342
343     RrPaint(a, self->icon,
344             ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
345 }
346
347 static void framerender_max(ObFrame *self, RrAppearance *a)
348 {
349     if (!self->max_on) return;
350     RrPaint(a, self->max, ob_rr_theme->button_size, ob_rr_theme->button_size);
351 }
352
353 static void framerender_iconify(ObFrame *self, RrAppearance *a)
354 {
355     if (!self->iconify_on) return;
356     RrPaint(a, self->iconify,
357             ob_rr_theme->button_size, ob_rr_theme->button_size);
358 }
359
360 static void framerender_desk(ObFrame *self, RrAppearance *a)
361 {
362     if (!self->desk_on) return;
363     RrPaint(a, self->desk, ob_rr_theme->button_size, ob_rr_theme->button_size);
364 }
365
366 static void framerender_shade(ObFrame *self, RrAppearance *a)
367 {
368     if (!self->shade_on) return;
369     RrPaint(a, self->shade,
370             ob_rr_theme->button_size, ob_rr_theme->button_size);
371 }
372
373 static void framerender_close(ObFrame *self, RrAppearance *a)
374 {
375     if (!self->close_on) return;
376     RrPaint(a, self->close,
377             ob_rr_theme->button_size, ob_rr_theme->button_size);
378 }