1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 theme.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
26 #include "parser/parse.h"
29 #include <X11/Xresource.h>
34 static XrmDatabase loaddb(RrTheme *theme, const gchar *name, gchar **path);
35 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value);
36 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value);
37 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
38 const gchar *rname, RrColor **value);
39 static gboolean read_mask(const RrInstance *inst, const gchar *path,
40 const gchar *maskname, RrTheme *theme,
41 RrPixmapMask **value);
42 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
43 const gchar *rname, RrAppearance *value,
44 gboolean allow_trans);
45 static int parse_inline_number(const char *p);
46 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
47 static void set_default_appearance(RrAppearance *a);
49 RrTheme* RrThemeNew(const RrInstance *inst, gchar *name,
50 RrFont *active_window_font, RrFont *inactive_window_font,
51 RrFont *menu_title_font, RrFont *menu_item_font)
53 XrmDatabase db = NULL;
54 RrJustify winjust, mtitlejust;
59 theme = g_new0(RrTheme, 1);
63 theme->a_disabled_focused_max = RrAppearanceNew(inst, 1);
64 theme->a_disabled_unfocused_max = RrAppearanceNew(inst, 1);
65 theme->a_hover_focused_max = RrAppearanceNew(inst, 1);
66 theme->a_hover_unfocused_max = RrAppearanceNew(inst, 1);
67 theme->a_toggled_focused_max = RrAppearanceNew(inst, 1);
68 theme->a_toggled_unfocused_max = RrAppearanceNew(inst, 1);
69 theme->a_focused_unpressed_max = RrAppearanceNew(inst, 1);
70 theme->a_focused_pressed_max = RrAppearanceNew(inst, 1);
71 theme->a_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
72 theme->a_unfocused_pressed_max = RrAppearanceNew(inst, 1);
73 theme->a_focused_grip = RrAppearanceNew(inst, 0);
74 theme->a_unfocused_grip = RrAppearanceNew(inst, 0);
75 theme->a_focused_title = RrAppearanceNew(inst, 0);
76 theme->a_unfocused_title = RrAppearanceNew(inst, 0);
77 theme->a_focused_label = RrAppearanceNew(inst, 1);
78 theme->a_unfocused_label = RrAppearanceNew(inst, 1);
79 theme->a_icon = RrAppearanceNew(inst, 1);
80 theme->a_focused_handle = RrAppearanceNew(inst, 0);
81 theme->a_unfocused_handle = RrAppearanceNew(inst, 0);
82 theme->a_menu = RrAppearanceNew(inst, 0);
83 theme->a_menu_title = RrAppearanceNew(inst, 1);
84 theme->a_menu_normal = RrAppearanceNew(inst, 0);
85 theme->a_menu_disabled = RrAppearanceNew(inst, 0);
86 theme->a_menu_selected = RrAppearanceNew(inst, 0);
87 theme->a_menu_text_normal = RrAppearanceNew(inst, 1);
88 theme->a_menu_text_disabled = RrAppearanceNew(inst, 1);
89 theme->a_menu_text_selected = RrAppearanceNew(inst, 1);
90 theme->a_menu_bullet_normal = RrAppearanceNew(inst, 1);
91 theme->a_menu_bullet_selected = RrAppearanceNew(inst, 1);
92 theme->a_clear = RrAppearanceNew(inst, 0);
93 theme->a_clear_tex = RrAppearanceNew(inst, 1);
96 db = loaddb(theme, name, &path);
98 g_warning("Failed to load the theme '%s'\n"
99 "Falling back to the default: '%s'",
100 name, DEFAULT_THEME);
104 db = loaddb(theme, DEFAULT_THEME, &path);
106 g_warning("Failed to load the theme '%s'.", DEFAULT_THEME);
111 /* load the font stuff */
112 if (active_window_font) {
113 theme->win_font_focused = active_window_font;
114 RrFontRef(active_window_font);
116 theme->win_font_focused = RrFontOpenDefault(inst);
118 if (inactive_window_font) {
119 theme->win_font_unfocused = inactive_window_font;
120 RrFontRef(inactive_window_font);
122 theme->win_font_unfocused = RrFontOpenDefault(inst);
124 winjust = RR_JUSTIFY_LEFT;
125 if (read_string(db, "window.label.text.justify", &str)) {
126 if (!g_ascii_strcasecmp(str, "right"))
127 winjust = RR_JUSTIFY_RIGHT;
128 else if (!g_ascii_strcasecmp(str, "center"))
129 winjust = RR_JUSTIFY_CENTER;
132 if (menu_title_font) {
133 theme->menu_title_font = menu_title_font;
134 RrFontRef(menu_title_font);
136 theme->menu_title_font = RrFontOpenDefault(inst);
138 mtitlejust = RR_JUSTIFY_LEFT;
139 if (read_string(db, "menu.title.text.justify", &str)) {
140 if (!g_ascii_strcasecmp(str, "right"))
141 mtitlejust = RR_JUSTIFY_RIGHT;
142 else if (!g_ascii_strcasecmp(str, "center"))
143 mtitlejust = RR_JUSTIFY_CENTER;
146 if (menu_item_font) {
147 theme->menu_font = menu_item_font;
148 RrFontRef(menu_item_font);
150 theme->menu_font = RrFontOpenDefault(inst);
152 /* load direct dimensions */
153 if (!read_int(db, "menu.overlap", &theme->menu_overlap) ||
154 theme->menu_overlap < 0 || theme->menu_overlap > 20)
155 theme->menu_overlap = 0;
156 if (!read_int(db, "window.handle.width", &theme->handle_height) ||
157 theme->handle_height < 0 || theme->handle_height > 100)
158 theme->handle_height = 6;
159 if (!read_int(db, "padding.width", &theme->paddingx) ||
160 theme->paddingx < 0 || theme->paddingx > 100)
162 theme->paddingy = theme->paddingx;
163 if (!read_int(db, "border.width", &theme->fbwidth) ||
164 theme->fbwidth < 0 || theme->fbwidth > 100)
166 theme->mbwidth = theme->fbwidth;
167 if (!read_int(db, "window.client.padding.width", &theme->cbwidthx) ||
168 theme->cbwidthx < 0 || theme->cbwidthx > 100)
169 theme->cbwidthx = theme->paddingx;
170 theme->cbwidthy = theme->cbwidthx;
173 if (!read_color(db, inst,
174 "border.color", &theme->frame_b_color))
175 theme->frame_b_color = RrColorNew(inst, 0, 0, 0);
176 theme->menu_b_color = RrColorNew(inst,
177 theme->frame_b_color->r,
178 theme->frame_b_color->g,
179 theme->frame_b_color->b);
180 if (!read_color(db, inst,
181 "window.active.client.color",
182 &theme->cb_focused_color))
183 theme->cb_focused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
184 if (!read_color(db, inst,
185 "window.inactive.client.color",
186 &theme->cb_unfocused_color))
187 theme->cb_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
188 if (!read_color(db, inst,
189 "window.active.label.text.color",
190 &theme->title_focused_color))
191 theme->title_focused_color = RrColorNew(inst, 0x0, 0x0, 0x0);
192 theme->osd_color = RrColorNew(inst,
193 theme->title_focused_color->r,
194 theme->title_focused_color->g,
195 theme->title_focused_color->b);
196 if (!read_color(db, inst,
197 "window.inactive.label.text.color",
198 &theme->title_unfocused_color))
199 theme->title_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
200 if (!read_color(db, inst,
201 "window.active.button.unpressed.image.color",
202 &theme->titlebut_focused_unpressed_color))
203 theme->titlebut_focused_unpressed_color = RrColorNew(inst, 0, 0, 0);
204 if (!read_color(db, inst,
205 "window.inactive.button.unpressed.image.color",
206 &theme->titlebut_unfocused_unpressed_color))
207 theme->titlebut_unfocused_unpressed_color =
208 RrColorNew(inst, 0xff, 0xff, 0xff);
209 if (!read_color(db, inst,
210 "window.active.button.pressed.image.color",
211 &theme->titlebut_focused_pressed_color))
212 theme->titlebut_focused_pressed_color =
214 theme->titlebut_focused_unpressed_color->r,
215 theme->titlebut_focused_unpressed_color->g,
216 theme->titlebut_focused_unpressed_color->b);
217 if (!read_color(db, inst,
218 "window.inactive.button.pressed.image.color",
219 &theme->titlebut_unfocused_pressed_color))
220 theme->titlebut_unfocused_pressed_color =
222 theme->titlebut_unfocused_unpressed_color->r,
223 theme->titlebut_unfocused_unpressed_color->g,
224 theme->titlebut_unfocused_unpressed_color->b);
225 if (!read_color(db, inst,
226 "window.active.button.disabled.image.color",
227 &theme->titlebut_disabled_focused_color))
228 theme->titlebut_disabled_focused_color =
229 RrColorNew(inst, 0xff, 0xff, 0xff);
230 if (!read_color(db, inst,
231 "window.inactive.button.disabled.image.color",
232 &theme->titlebut_disabled_unfocused_color))
233 theme->titlebut_disabled_unfocused_color = RrColorNew(inst, 0, 0, 0);
234 if (!read_color(db, inst,
235 "window.active.button.hover.image.color",
236 &theme->titlebut_hover_focused_color))
237 theme->titlebut_hover_focused_color =
239 theme->titlebut_focused_unpressed_color->r,
240 theme->titlebut_focused_unpressed_color->g,
241 theme->titlebut_focused_unpressed_color->b);
242 if (!read_color(db, inst,
243 "window.inactive.button.hover.image.color",
244 &theme->titlebut_hover_unfocused_color))
245 theme->titlebut_hover_unfocused_color =
247 theme->titlebut_unfocused_unpressed_color->r,
248 theme->titlebut_unfocused_unpressed_color->g,
249 theme->titlebut_unfocused_unpressed_color->b);
250 if (!read_color(db, inst,
251 "window.active.button.toggled.image.color",
252 &theme->titlebut_toggled_focused_color))
253 theme->titlebut_toggled_focused_color =
255 theme->titlebut_focused_pressed_color->r,
256 theme->titlebut_focused_pressed_color->g,
257 theme->titlebut_focused_pressed_color->b);
258 if (!read_color(db, inst,
259 "window.inactive.button.toggled.image.color",
260 &theme->titlebut_toggled_unfocused_color))
261 theme->titlebut_toggled_unfocused_color =
263 theme->titlebut_unfocused_pressed_color->r,
264 theme->titlebut_unfocused_pressed_color->g,
265 theme->titlebut_unfocused_pressed_color->b);
266 if (!read_color(db, inst,
267 "menu.title.text.color", &theme->menu_title_color))
268 theme->menu_title_color = RrColorNew(inst, 0, 0, 0);
269 if (!read_color(db, inst,
270 "menu.items.text.color", &theme->menu_color))
271 theme->menu_color = RrColorNew(inst, 0xff, 0xff, 0xff);
272 if (!read_color(db, inst,
273 "menu.items.disabled.text.color",
274 &theme->menu_disabled_color))
275 theme->menu_disabled_color = RrColorNew(inst, 0, 0, 0);
276 if (!read_color(db, inst,
277 "menu.items.active.text.color",
278 &theme->menu_selected_color))
279 theme->menu_selected_color = RrColorNew(inst, 0, 0, 0);
281 if (read_mask(inst, path, "max.xbm", theme, &theme->max_mask)) {
282 if (!read_mask(inst, path, "max_pressed.xbm", theme,
283 &theme->max_pressed_mask)) {
284 theme->max_pressed_mask = RrPixmapMaskCopy(theme->max_mask);
286 if (!read_mask(inst, path, "max_toggled.xbm", theme,
287 &theme->max_toggled_mask)) {
288 theme->max_toggled_mask =
289 RrPixmapMaskCopy(theme->max_pressed_mask);
291 if (!read_mask(inst, path, "max_disabled.xbm", theme,
292 &theme->max_disabled_mask)) {
293 theme->max_disabled_mask = RrPixmapMaskCopy(theme->max_mask);
295 if (!read_mask(inst, path, "max_hover.xbm", theme,
296 &theme->max_hover_mask)) {
297 theme->max_hover_mask = RrPixmapMaskCopy(theme->max_mask);
301 guchar data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
302 theme->max_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
305 guchar data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
306 theme->max_toggled_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
308 theme->max_pressed_mask = RrPixmapMaskCopy(theme->max_mask);
309 theme->max_disabled_mask = RrPixmapMaskCopy(theme->max_mask);
310 theme->max_hover_mask = RrPixmapMaskCopy(theme->max_mask);
313 if (read_mask(inst, path, "iconify.xbm", theme, &theme->iconify_mask)) {
314 if (!read_mask(inst, path, "iconify_pressed.xbm", theme,
315 &theme->iconify_pressed_mask)) {
316 theme->iconify_pressed_mask =
317 RrPixmapMaskCopy(theme->iconify_mask);
319 if (!read_mask(inst, path, "iconify_disabled.xbm", theme,
320 &theme->iconify_disabled_mask)) {
321 theme->iconify_disabled_mask =
322 RrPixmapMaskCopy(theme->iconify_mask);
324 if (!read_mask(inst, path, "iconify_hover.xbm", theme,
325 &theme->iconify_hover_mask)) {
326 theme->iconify_hover_mask = RrPixmapMaskCopy(theme->iconify_mask);
330 guchar data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
331 theme->iconify_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
333 theme->iconify_pressed_mask = RrPixmapMaskCopy(theme->iconify_mask);
334 theme->iconify_disabled_mask = RrPixmapMaskCopy(theme->iconify_mask);
335 theme->iconify_hover_mask = RrPixmapMaskCopy(theme->iconify_mask);
338 theme->def_win_icon = read_c_image(OB_DEFAULT_ICON_WIDTH,
339 OB_DEFAULT_ICON_HEIGHT,
340 OB_DEFAULT_ICON_pixel_data);
342 if (read_mask(inst, path, "desk.xbm", theme, &theme->desk_mask)) {
343 if (!read_mask(inst, path, "desk_pressed.xbm", theme,
344 &theme->desk_pressed_mask)) {
345 theme->desk_pressed_mask = RrPixmapMaskCopy(theme->desk_mask);
347 if (!read_mask(inst, path, "desk_toggled.xbm", theme,
348 &theme->desk_toggled_mask)) {
349 theme->desk_toggled_mask =
350 RrPixmapMaskCopy(theme->desk_pressed_mask);
352 if (!read_mask(inst, path, "desk_disabled.xbm", theme,
353 &theme->desk_disabled_mask)) {
354 theme->desk_disabled_mask = RrPixmapMaskCopy(theme->desk_mask);
356 if (!read_mask(inst, path, "desk_hover.xbm", theme,
357 &theme->desk_hover_mask)) {
358 theme->desk_hover_mask = RrPixmapMaskCopy(theme->desk_mask);
362 guchar data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
363 theme->desk_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
366 guchar data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
367 theme->desk_toggled_mask = RrPixmapMaskNew(inst, 7, 7,
370 theme->desk_pressed_mask = RrPixmapMaskCopy(theme->desk_mask);
371 theme->desk_disabled_mask = RrPixmapMaskCopy(theme->desk_mask);
372 theme->desk_hover_mask = RrPixmapMaskCopy(theme->desk_mask);
375 if (read_mask(inst, path, "shade.xbm", theme, &theme->shade_mask)) {
376 if (!read_mask(inst, path, "shade_pressed.xbm", theme,
377 &theme->shade_pressed_mask)) {
378 theme->shade_pressed_mask = RrPixmapMaskCopy(theme->shade_mask);
380 if (!read_mask(inst, path, "shade_toggled.xbm", theme,
381 &theme->shade_toggled_mask)) {
382 theme->shade_toggled_mask =
383 RrPixmapMaskCopy(theme->shade_pressed_mask);
385 if (!read_mask(inst, path, "shade_disabled.xbm", theme,
386 &theme->shade_disabled_mask)) {
387 theme->shade_disabled_mask = RrPixmapMaskCopy(theme->shade_mask);
389 if (!read_mask(inst, path, "shade_hover.xbm", theme,
390 &theme->shade_hover_mask)) {
391 theme->shade_hover_mask = RrPixmapMaskCopy(theme->shade_mask);
395 guchar data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
396 theme->shade_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
399 guchar data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
400 theme->shade_toggled_mask = RrPixmapMaskNew(inst, 7, 7,
403 theme->shade_pressed_mask = RrPixmapMaskCopy(theme->shade_mask);
404 theme->shade_disabled_mask = RrPixmapMaskCopy(theme->shade_mask);
405 theme->shade_hover_mask = RrPixmapMaskCopy(theme->shade_mask);
408 if (read_mask(inst, path, "close.xbm", theme, &theme->close_mask)) {
409 if (!read_mask(inst, path, "close_pressed.xbm", theme,
410 &theme->close_pressed_mask)) {
411 theme->close_pressed_mask = RrPixmapMaskCopy(theme->close_mask);
413 if (!read_mask(inst, path, "close_disabled.xbm", theme,
414 &theme->close_disabled_mask)) {
415 theme->close_disabled_mask = RrPixmapMaskCopy(theme->close_mask);
417 if (!read_mask(inst, path, "close_hover.xbm", theme,
418 &theme->close_hover_mask)) {
419 theme->close_hover_mask = RrPixmapMaskCopy(theme->close_mask);
423 guchar data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
424 theme->close_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
426 theme->close_pressed_mask = RrPixmapMaskCopy(theme->close_mask);
427 theme->close_disabled_mask = RrPixmapMaskCopy(theme->close_mask);
428 theme->close_hover_mask = RrPixmapMaskCopy(theme->close_mask);
431 if (!read_mask(inst, path, "bullet.xbm", theme,
432 &theme->menu_bullet_mask)) {
433 guchar data[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01 };
434 theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
437 /* read the decoration textures */
438 if (!read_appearance(db, inst,
439 "window.active.title.bg", theme->a_focused_title,
441 set_default_appearance(theme->a_focused_title);
442 if (!read_appearance(db, inst,
443 "window.inactive.title.bg", theme->a_unfocused_title,
445 set_default_appearance(theme->a_unfocused_title);
446 if (!read_appearance(db, inst,
447 "window.active.label.bg", theme->a_focused_label,
449 set_default_appearance(theme->a_focused_label);
450 if (!read_appearance(db, inst,
451 "window.inactive.label.bg", theme->a_unfocused_label,
453 set_default_appearance(theme->a_unfocused_label);
454 if (!read_appearance(db, inst,
455 "window.active.handle.bg", theme->a_focused_handle,
457 set_default_appearance(theme->a_focused_handle);
458 if (!read_appearance(db, inst,
459 "window.inactive.handle.bg",theme->a_unfocused_handle,
461 set_default_appearance(theme->a_unfocused_handle);
462 if (!read_appearance(db, inst,
463 "window.active.grip.bg", theme->a_focused_grip,
465 set_default_appearance(theme->a_focused_grip);
466 if (!read_appearance(db, inst,
467 "window.inactive.grip.bg", theme->a_unfocused_grip,
469 set_default_appearance(theme->a_unfocused_grip);
470 if (!read_appearance(db, inst,
471 "menu.items.bg", theme->a_menu,
473 set_default_appearance(theme->a_menu);
474 if (!read_appearance(db, inst,
475 "menu.title.bg", theme->a_menu_title,
477 set_default_appearance(theme->a_menu_title);
478 if (!read_appearance(db, inst,
479 "menu.items.active.bg", theme->a_menu_selected,
481 set_default_appearance(theme->a_menu_selected);
483 /* read the appearances for rendering non-decorations */
484 theme->osd_hilite_bg = RrAppearanceCopy(theme->a_focused_title);
485 theme->osd_hilite_label = RrAppearanceCopy(theme->a_focused_label);
486 if (theme->a_focused_label->surface.grad != RR_SURFACE_PARENTREL)
487 theme->osd_hilite_fg = RrAppearanceCopy(theme->a_focused_label);
489 theme->osd_hilite_fg = RrAppearanceCopy(theme->a_focused_title);
490 if (theme->a_unfocused_label->surface.grad != RR_SURFACE_PARENTREL)
491 theme->osd_unhilite_fg = RrAppearanceCopy(theme->a_unfocused_label);
493 theme->osd_unhilite_fg = RrAppearanceCopy(theme->a_unfocused_title);
495 /* read buttons textures */
496 if (!read_appearance(db, inst,
497 "window.active.button.disabled.bg",
498 theme->a_disabled_focused_max,
500 set_default_appearance(theme->a_disabled_focused_max);
501 if (!read_appearance(db, inst,
502 "window.inactive.button.disabled.bg",
503 theme->a_disabled_unfocused_max,
505 set_default_appearance(theme->a_disabled_unfocused_max);
506 if (!read_appearance(db, inst,
507 "window.active.button.pressed.bg",
508 theme->a_focused_pressed_max,
510 set_default_appearance(theme->a_focused_pressed_max);
511 if (!read_appearance(db, inst,
512 "window.inactive.button.pressed.bg",
513 theme->a_unfocused_pressed_max,
515 set_default_appearance(theme->a_unfocused_pressed_max);
516 if (!read_appearance(db, inst,
517 "window.active.button.toggled.bg",
518 theme->a_toggled_focused_max,
521 RrAppearanceFree(theme->a_toggled_focused_max);
522 theme->a_toggled_focused_max =
523 RrAppearanceCopy(theme->a_focused_pressed_max);
525 if (!read_appearance(db, inst,
526 "window.inactive.button.toggled.bg",
527 theme->a_toggled_unfocused_max,
530 RrAppearanceFree(theme->a_toggled_unfocused_max);
531 theme->a_toggled_unfocused_max =
532 RrAppearanceCopy(theme->a_unfocused_pressed_max);
534 if (!read_appearance(db, inst,
535 "window.active.button.unpressed.bg",
536 theme->a_focused_unpressed_max,
538 set_default_appearance(theme->a_focused_unpressed_max);
539 if (!read_appearance(db, inst,
540 "window.inactive.button.unpressed.bg",
541 theme->a_unfocused_unpressed_max,
543 set_default_appearance(theme->a_unfocused_unpressed_max);
544 if (!read_appearance(db, inst,
545 "window.active.button.hover.bg",
546 theme->a_hover_focused_max,
549 RrAppearanceFree(theme->a_hover_focused_max);
550 theme->a_hover_focused_max =
551 RrAppearanceCopy(theme->a_focused_unpressed_max);
553 if (!read_appearance(db, inst,
554 "window.inactive.button.hover.bg",
555 theme->a_hover_unfocused_max,
558 RrAppearanceFree(theme->a_hover_unfocused_max);
559 theme->a_hover_unfocused_max =
560 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
563 theme->a_disabled_focused_close =
564 RrAppearanceCopy(theme->a_disabled_focused_max);
565 theme->a_disabled_unfocused_close =
566 RrAppearanceCopy(theme->a_disabled_unfocused_max);
567 theme->a_hover_focused_close =
568 RrAppearanceCopy(theme->a_hover_focused_max);
569 theme->a_hover_unfocused_close =
570 RrAppearanceCopy(theme->a_hover_unfocused_max);
571 theme->a_unfocused_unpressed_close =
572 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
573 theme->a_unfocused_pressed_close =
574 RrAppearanceCopy(theme->a_unfocused_pressed_max);
575 theme->a_focused_unpressed_close =
576 RrAppearanceCopy(theme->a_focused_unpressed_max);
577 theme->a_focused_pressed_close =
578 RrAppearanceCopy(theme->a_focused_pressed_max);
579 theme->a_disabled_focused_desk =
580 RrAppearanceCopy(theme->a_disabled_focused_max);
581 theme->a_disabled_unfocused_desk =
582 RrAppearanceCopy(theme->a_disabled_unfocused_max);
583 theme->a_hover_focused_desk =
584 RrAppearanceCopy(theme->a_hover_focused_max);
585 theme->a_hover_unfocused_desk =
586 RrAppearanceCopy(theme->a_hover_unfocused_max);
587 theme->a_toggled_focused_desk =
588 RrAppearanceCopy(theme->a_toggled_focused_max);
589 theme->a_toggled_unfocused_desk =
590 RrAppearanceCopy(theme->a_toggled_unfocused_max);
591 theme->a_unfocused_unpressed_desk =
592 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
593 theme->a_unfocused_pressed_desk =
594 RrAppearanceCopy(theme->a_unfocused_pressed_max);
595 theme->a_focused_unpressed_desk =
596 RrAppearanceCopy(theme->a_focused_unpressed_max);
597 theme->a_focused_pressed_desk =
598 RrAppearanceCopy(theme->a_focused_pressed_max);
599 theme->a_disabled_focused_shade =
600 RrAppearanceCopy(theme->a_disabled_focused_max);
601 theme->a_disabled_unfocused_shade =
602 RrAppearanceCopy(theme->a_disabled_unfocused_max);
603 theme->a_hover_focused_shade =
604 RrAppearanceCopy(theme->a_hover_focused_max);
605 theme->a_hover_unfocused_shade =
606 RrAppearanceCopy(theme->a_hover_unfocused_max);
607 theme->a_toggled_focused_shade =
608 RrAppearanceCopy(theme->a_toggled_focused_max);
609 theme->a_toggled_unfocused_shade =
610 RrAppearanceCopy(theme->a_toggled_unfocused_max);
611 theme->a_unfocused_unpressed_shade =
612 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
613 theme->a_unfocused_pressed_shade =
614 RrAppearanceCopy(theme->a_unfocused_pressed_max);
615 theme->a_focused_unpressed_shade =
616 RrAppearanceCopy(theme->a_focused_unpressed_max);
617 theme->a_focused_pressed_shade =
618 RrAppearanceCopy(theme->a_focused_pressed_max);
619 theme->a_disabled_focused_iconify =
620 RrAppearanceCopy(theme->a_disabled_focused_max);
621 theme->a_disabled_unfocused_iconify =
622 RrAppearanceCopy(theme->a_disabled_focused_max);
623 theme->a_hover_focused_iconify =
624 RrAppearanceCopy(theme->a_hover_focused_max);
625 theme->a_hover_unfocused_iconify =
626 RrAppearanceCopy(theme->a_hover_unfocused_max);
627 theme->a_unfocused_unpressed_iconify =
628 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
629 theme->a_unfocused_pressed_iconify =
630 RrAppearanceCopy(theme->a_unfocused_pressed_max);
631 theme->a_focused_unpressed_iconify =
632 RrAppearanceCopy(theme->a_focused_unpressed_max);
633 theme->a_focused_pressed_iconify =
634 RrAppearanceCopy(theme->a_focused_pressed_max);
636 theme->a_icon->surface.grad =
637 theme->a_clear->surface.grad =
638 theme->a_clear_tex->surface.grad =
639 theme->a_menu_normal->surface.grad =
640 theme->a_menu_disabled->surface.grad =
641 theme->a_menu_text_normal->surface.grad =
642 theme->a_menu_text_disabled->surface.grad =
643 theme->a_menu_text_selected->surface.grad =
644 theme->a_menu_bullet_normal->surface.grad =
645 theme->a_menu_bullet_selected->surface.grad = RR_SURFACE_PARENTREL;
647 /* set up the textures */
648 theme->a_focused_label->texture[0].type =
649 theme->osd_hilite_label->texture[0].type = RR_TEXTURE_TEXT;
650 theme->a_focused_label->texture[0].data.text.justify = winjust;
651 theme->osd_hilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
652 theme->a_focused_label->texture[0].data.text.font =
653 theme->osd_hilite_label->texture[0].data.text.font =
654 theme->win_font_focused;
655 theme->a_focused_label->texture[0].data.text.color =
656 theme->title_focused_color;
657 theme->osd_hilite_label->texture[0].data.text.color =
660 if (read_string(db, "window.active.label.text.font", &str)) {
664 if (strstr(str, "shadow=y")) {
665 if ((p = strstr(str, "shadowoffset=")))
666 i = parse_inline_number(p + strlen("shadowoffset="));
669 theme->a_focused_label->texture[0].data.text.shadow_offset_x = i;
670 theme->a_focused_label->texture[0].data.text.shadow_offset_y = i;
671 theme->osd_hilite_label->texture[0].data.text.shadow_offset_x = i;
672 theme->osd_hilite_label->texture[0].data.text.shadow_offset_y = i;
674 if (i && (p = strstr(str, "shadowtint=")))
676 i = parse_inline_number(p + strlen("shadowtint="));
677 j = (i > 0 ? 0 : 255);
680 theme->title_focused_shadow_color = RrColorNew(inst, j, j, j);
681 theme->title_focused_shadow_alpha = i;
682 theme->osd_shadow_color = RrColorNew(inst, j, j, j);
683 theme->osd_shadow_alpha = i;
685 theme->title_focused_shadow_color = RrColorNew(inst, 0, 0, 0);
686 theme->title_focused_shadow_alpha = 50;
687 theme->osd_shadow_color = RrColorNew(inst, 0, 0, 0);
688 theme->osd_shadow_alpha = 50;
692 theme->a_unfocused_label->texture[0].type = RR_TEXTURE_TEXT;
693 theme->a_unfocused_label->texture[0].data.text.justify = winjust;
694 theme->a_unfocused_label->texture[0].data.text.font =
695 theme->win_font_unfocused;
696 theme->a_unfocused_label->texture[0].data.text.color =
697 theme->title_unfocused_color;
699 if (read_string(db, "window.inactive.label.text.font", &str)) {
703 if (strstr(str, "shadow=y")) {
704 if ((p = strstr(str, "shadowoffset=")))
705 i = parse_inline_number(p + strlen("shadowoffset="));
708 theme->a_unfocused_label->texture[0].data.text.shadow_offset_x = i;
709 theme->a_unfocused_label->texture[0].data.text.shadow_offset_y = i;
711 if (i && (p = strstr(str, "shadowtint=")))
713 i = parse_inline_number(p + strlen("shadowtint="));
714 j = (i > 0 ? 0 : 255);
717 theme->title_unfocused_shadow_color = RrColorNew(inst, j, j, j);
718 theme->title_unfocused_shadow_alpha = i;
720 theme->title_unfocused_shadow_color = RrColorNew(inst, 0, 0, 0);
721 theme->title_unfocused_shadow_alpha = 50;
726 theme->a_menu_title->texture[0].type = RR_TEXTURE_TEXT;
727 theme->a_menu_title->texture[0].data.text.justify = mtitlejust;
728 theme->a_menu_title->texture[0].data.text.font = theme->menu_title_font;
729 theme->a_menu_title->texture[0].data.text.color = theme->menu_title_color;
731 if (read_string(db, "menu.title.text.font", &str)) {
735 if (strstr(str, "shadow=y")) {
736 if ((p = strstr(str, "shadowoffset=")))
737 i = parse_inline_number(p + strlen("shadowoffset="));
740 theme->a_menu_title->texture[0].data.text.shadow_offset_x = i;
741 theme->a_menu_title->texture[0].data.text.shadow_offset_y = i;
743 if (i && (p = strstr(str, "shadowtint=")))
745 i = parse_inline_number(p + strlen("shadowtint="));
746 j = (i > 0 ? 0 : 255);
749 theme->menu_title_shadow_color = RrColorNew(inst, j, j, j);
750 theme->menu_title_shadow_alpha = i;
752 theme->menu_title_shadow_color = RrColorNew(inst, 0, 0, 0);
753 theme->menu_title_shadow_alpha = 50;
758 theme->a_menu_text_normal->texture[0].type =
759 theme->a_menu_text_disabled->texture[0].type =
760 theme->a_menu_text_selected->texture[0].type = RR_TEXTURE_TEXT;
761 theme->a_menu_text_normal->texture[0].data.text.justify =
762 theme->a_menu_text_disabled->texture[0].data.text.justify =
763 theme->a_menu_text_selected->texture[0].data.text.justify =
765 theme->a_menu_text_normal->texture[0].data.text.font =
766 theme->a_menu_text_disabled->texture[0].data.text.font =
767 theme->a_menu_text_selected->texture[0].data.text.font =
769 theme->a_menu_text_normal->texture[0].data.text.color = theme->menu_color;
770 theme->a_menu_text_disabled->texture[0].data.text.color =
771 theme->menu_disabled_color;
772 theme->a_menu_text_selected->texture[0].data.text.color =
773 theme->menu_selected_color;
775 if (read_string(db, "menu.items.font", &str)) {
779 if (strstr(str, "shadow=y")) {
780 if ((p = strstr(str, "shadowoffset=")))
781 i = parse_inline_number(p + strlen("shadowoffset="));
784 theme->a_menu_text_normal->
785 texture[0].data.text.shadow_offset_x = i;
786 theme->a_menu_text_normal->
787 texture[0].data.text.shadow_offset_y = i;
788 theme->a_menu_text_disabled->
789 texture[0].data.text.shadow_offset_x = i;
790 theme->a_menu_text_disabled->
791 texture[0].data.text.shadow_offset_y = i;
792 theme->a_menu_text_selected->
793 texture[0].data.text.shadow_offset_x = i;
794 theme->a_menu_text_selected->
795 texture[0].data.text.shadow_offset_y = i;
797 if (i && (p = strstr(str, "shadowtint=")))
799 i = parse_inline_number(p + strlen("shadowtint="));
800 j = (i > 0 ? 0 : 255);
803 theme->menu_text_normal_shadow_color = RrColorNew(inst, j, j, j);
804 theme->menu_text_selected_shadow_color = RrColorNew(inst, j, j, j);
805 theme->menu_text_disabled_shadow_color = RrColorNew(inst, j, j, j);
806 theme->menu_text_normal_shadow_alpha = i;
807 theme->menu_text_selected_shadow_alpha = i;
808 theme->menu_text_disabled_shadow_alpha = i;
810 theme->menu_text_normal_shadow_color = RrColorNew(inst, 0, 0, 0);
811 theme->menu_text_selected_shadow_color = RrColorNew(inst, 0, 0, 0);
812 theme->menu_text_disabled_shadow_color = RrColorNew(inst, 0, 0, 0);
813 theme->menu_text_normal_shadow_alpha = 50;
814 theme->menu_text_selected_shadow_alpha = 50;
815 theme->menu_text_disabled_shadow_alpha = 50;
819 theme->a_disabled_focused_max->texture[0].type =
820 theme->a_disabled_unfocused_max->texture[0].type =
821 theme->a_hover_focused_max->texture[0].type =
822 theme->a_hover_unfocused_max->texture[0].type =
823 theme->a_toggled_focused_max->texture[0].type =
824 theme->a_toggled_unfocused_max->texture[0].type =
825 theme->a_focused_unpressed_max->texture[0].type =
826 theme->a_focused_pressed_max->texture[0].type =
827 theme->a_unfocused_unpressed_max->texture[0].type =
828 theme->a_unfocused_pressed_max->texture[0].type =
829 theme->a_disabled_focused_close->texture[0].type =
830 theme->a_disabled_unfocused_close->texture[0].type =
831 theme->a_hover_focused_close->texture[0].type =
832 theme->a_hover_unfocused_close->texture[0].type =
833 theme->a_focused_unpressed_close->texture[0].type =
834 theme->a_focused_pressed_close->texture[0].type =
835 theme->a_unfocused_unpressed_close->texture[0].type =
836 theme->a_unfocused_pressed_close->texture[0].type =
837 theme->a_disabled_focused_desk->texture[0].type =
838 theme->a_disabled_unfocused_desk->texture[0].type =
839 theme->a_hover_focused_desk->texture[0].type =
840 theme->a_hover_unfocused_desk->texture[0].type =
841 theme->a_toggled_focused_desk->texture[0].type =
842 theme->a_toggled_unfocused_desk->texture[0].type =
843 theme->a_focused_unpressed_desk->texture[0].type =
844 theme->a_focused_pressed_desk->texture[0].type =
845 theme->a_unfocused_unpressed_desk->texture[0].type =
846 theme->a_unfocused_pressed_desk->texture[0].type =
847 theme->a_disabled_focused_shade->texture[0].type =
848 theme->a_disabled_unfocused_shade->texture[0].type =
849 theme->a_hover_focused_shade->texture[0].type =
850 theme->a_hover_unfocused_shade->texture[0].type =
851 theme->a_toggled_focused_shade->texture[0].type =
852 theme->a_toggled_unfocused_shade->texture[0].type =
853 theme->a_focused_unpressed_shade->texture[0].type =
854 theme->a_focused_pressed_shade->texture[0].type =
855 theme->a_unfocused_unpressed_shade->texture[0].type =
856 theme->a_unfocused_pressed_shade->texture[0].type =
857 theme->a_disabled_focused_iconify->texture[0].type =
858 theme->a_disabled_unfocused_iconify->texture[0].type =
859 theme->a_hover_focused_iconify->texture[0].type =
860 theme->a_hover_unfocused_iconify->texture[0].type =
861 theme->a_focused_unpressed_iconify->texture[0].type =
862 theme->a_focused_pressed_iconify->texture[0].type =
863 theme->a_unfocused_unpressed_iconify->texture[0].type =
864 theme->a_unfocused_pressed_iconify->texture[0].type =
865 theme->a_menu_bullet_normal->texture[0].type =
866 theme->a_menu_bullet_selected->texture[0].type = RR_TEXTURE_MASK;
868 theme->a_disabled_focused_max->texture[0].data.mask.mask =
869 theme->a_disabled_unfocused_max->texture[0].data.mask.mask =
870 theme->max_disabled_mask;
871 theme->a_hover_focused_max->texture[0].data.mask.mask =
872 theme->a_hover_unfocused_max->texture[0].data.mask.mask =
873 theme->max_hover_mask;
874 theme->a_focused_pressed_max->texture[0].data.mask.mask =
875 theme->a_unfocused_pressed_max->texture[0].data.mask.mask =
876 theme->max_pressed_mask;
877 theme->a_focused_unpressed_max->texture[0].data.mask.mask =
878 theme->a_unfocused_unpressed_max->texture[0].data.mask.mask =
880 theme->a_toggled_focused_max->texture[0].data.mask.mask =
881 theme->a_toggled_unfocused_max->texture[0].data.mask.mask =
882 theme->max_toggled_mask;
883 theme->a_disabled_focused_close->texture[0].data.mask.mask =
884 theme->a_disabled_unfocused_close->texture[0].data.mask.mask =
885 theme->close_disabled_mask;
886 theme->a_hover_focused_close->texture[0].data.mask.mask =
887 theme->a_hover_unfocused_close->texture[0].data.mask.mask =
888 theme->close_hover_mask;
889 theme->a_focused_pressed_close->texture[0].data.mask.mask =
890 theme->a_unfocused_pressed_close->texture[0].data.mask.mask =
891 theme->close_pressed_mask;
892 theme->a_focused_unpressed_close->texture[0].data.mask.mask =
893 theme->a_unfocused_unpressed_close->texture[0].data.mask.mask =
895 theme->a_disabled_focused_desk->texture[0].data.mask.mask =
896 theme->a_disabled_unfocused_desk->texture[0].data.mask.mask =
897 theme->desk_disabled_mask;
898 theme->a_hover_focused_desk->texture[0].data.mask.mask =
899 theme->a_hover_unfocused_desk->texture[0].data.mask.mask =
900 theme->desk_hover_mask;
901 theme->a_focused_pressed_desk->texture[0].data.mask.mask =
902 theme->a_unfocused_pressed_desk->texture[0].data.mask.mask =
903 theme->desk_pressed_mask;
904 theme->a_focused_unpressed_desk->texture[0].data.mask.mask =
905 theme->a_unfocused_unpressed_desk->texture[0].data.mask.mask =
907 theme->a_toggled_focused_desk->texture[0].data.mask.mask =
908 theme->a_toggled_unfocused_desk->texture[0].data.mask.mask =
909 theme->desk_toggled_mask;
910 theme->a_disabled_focused_shade->texture[0].data.mask.mask =
911 theme->a_disabled_unfocused_shade->texture[0].data.mask.mask =
912 theme->shade_disabled_mask;
913 theme->a_hover_focused_shade->texture[0].data.mask.mask =
914 theme->a_hover_unfocused_shade->texture[0].data.mask.mask =
915 theme->shade_hover_mask;
916 theme->a_focused_pressed_shade->texture[0].data.mask.mask =
917 theme->a_unfocused_pressed_shade->texture[0].data.mask.mask =
918 theme->shade_pressed_mask;
919 theme->a_focused_unpressed_shade->texture[0].data.mask.mask =
920 theme->a_unfocused_unpressed_shade->texture[0].data.mask.mask =
922 theme->a_toggled_focused_shade->texture[0].data.mask.mask =
923 theme->a_toggled_unfocused_shade->texture[0].data.mask.mask =
924 theme->shade_toggled_mask;
925 theme->a_disabled_focused_iconify->texture[0].data.mask.mask =
926 theme->a_disabled_unfocused_iconify->texture[0].data.mask.mask =
927 theme->iconify_disabled_mask;
928 theme->a_hover_focused_iconify->texture[0].data.mask.mask =
929 theme->a_hover_unfocused_iconify->texture[0].data.mask.mask =
930 theme->iconify_hover_mask;
931 theme->a_focused_pressed_iconify->texture[0].data.mask.mask =
932 theme->a_unfocused_pressed_iconify->texture[0].data.mask.mask =
933 theme->iconify_pressed_mask;
934 theme->a_focused_unpressed_iconify->texture[0].data.mask.mask =
935 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
937 theme->a_menu_bullet_normal->texture[0].data.mask.mask =
938 theme->a_menu_bullet_selected->texture[0].data.mask.mask =
939 theme->menu_bullet_mask;
940 theme->a_disabled_focused_max->texture[0].data.mask.color =
941 theme->a_disabled_focused_close->texture[0].data.mask.color =
942 theme->a_disabled_focused_desk->texture[0].data.mask.color =
943 theme->a_disabled_focused_shade->texture[0].data.mask.color =
944 theme->a_disabled_focused_iconify->texture[0].data.mask.color =
945 theme->titlebut_disabled_focused_color;
946 theme->a_disabled_unfocused_max->texture[0].data.mask.color =
947 theme->a_disabled_unfocused_close->texture[0].data.mask.color =
948 theme->a_disabled_unfocused_desk->texture[0].data.mask.color =
949 theme->a_disabled_unfocused_shade->texture[0].data.mask.color =
950 theme->a_disabled_unfocused_iconify->texture[0].data.mask.color =
951 theme->titlebut_disabled_unfocused_color;
952 theme->a_hover_focused_max->texture[0].data.mask.color =
953 theme->a_hover_focused_close->texture[0].data.mask.color =
954 theme->a_hover_focused_desk->texture[0].data.mask.color =
955 theme->a_hover_focused_shade->texture[0].data.mask.color =
956 theme->a_hover_focused_iconify->texture[0].data.mask.color =
957 theme->titlebut_hover_focused_color;
958 theme->a_hover_unfocused_max->texture[0].data.mask.color =
959 theme->a_hover_unfocused_close->texture[0].data.mask.color =
960 theme->a_hover_unfocused_desk->texture[0].data.mask.color =
961 theme->a_hover_unfocused_shade->texture[0].data.mask.color =
962 theme->a_hover_unfocused_iconify->texture[0].data.mask.color =
963 theme->titlebut_hover_unfocused_color;
964 theme->a_toggled_focused_max->texture[0].data.mask.color =
965 theme->a_toggled_focused_desk->texture[0].data.mask.color =
966 theme->a_toggled_focused_shade->texture[0].data.mask.color =
967 theme->titlebut_toggled_focused_color;
968 theme->a_toggled_unfocused_max->texture[0].data.mask.color =
969 theme->a_toggled_unfocused_desk->texture[0].data.mask.color =
970 theme->a_toggled_unfocused_shade->texture[0].data.mask.color =
971 theme->titlebut_toggled_unfocused_color;
972 theme->a_focused_unpressed_max->texture[0].data.mask.color =
973 theme->a_focused_unpressed_close->texture[0].data.mask.color =
974 theme->a_focused_unpressed_desk->texture[0].data.mask.color =
975 theme->a_focused_unpressed_shade->texture[0].data.mask.color =
976 theme->a_focused_unpressed_iconify->texture[0].data.mask.color =
977 theme->titlebut_focused_unpressed_color;
978 theme->a_focused_pressed_max->texture[0].data.mask.color =
979 theme->a_focused_pressed_close->texture[0].data.mask.color =
980 theme->a_focused_pressed_desk->texture[0].data.mask.color =
981 theme->a_focused_pressed_shade->texture[0].data.mask.color =
982 theme->a_focused_pressed_iconify->texture[0].data.mask.color =
983 theme->titlebut_focused_pressed_color;
984 theme->a_unfocused_unpressed_max->texture[0].data.mask.color =
985 theme->a_unfocused_unpressed_close->texture[0].data.mask.color =
986 theme->a_unfocused_unpressed_desk->texture[0].data.mask.color =
987 theme->a_unfocused_unpressed_shade->texture[0].data.mask.color =
988 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.color =
989 theme->titlebut_unfocused_unpressed_color;
990 theme->a_unfocused_pressed_max->texture[0].data.mask.color =
991 theme->a_unfocused_pressed_close->texture[0].data.mask.color =
992 theme->a_unfocused_pressed_desk->texture[0].data.mask.color =
993 theme->a_unfocused_pressed_shade->texture[0].data.mask.color =
994 theme->a_unfocused_pressed_iconify->texture[0].data.mask.color =
995 theme->titlebut_unfocused_pressed_color;
996 theme->a_menu_bullet_normal->texture[0].data.mask.color =
998 theme->a_menu_bullet_selected->texture[0].data.mask.color =
999 theme->menu_selected_color;
1002 XrmDestroyDatabase(db);
1004 /* set the font heights */
1005 theme->win_font_height = RrFontHeight
1006 (theme->win_font_focused,
1007 theme->a_focused_label->texture[0].data.text.shadow_offset_y);
1008 theme->win_font_height =
1009 MAX(theme->win_font_height,
1011 (theme->win_font_focused,
1012 theme->a_unfocused_label->texture[0].data.text.shadow_offset_y));
1013 theme->menu_title_font_height = RrFontHeight
1014 (theme->menu_title_font,
1015 theme->a_menu_title->texture[0].data.text.shadow_offset_y);
1016 theme->menu_font_height = RrFontHeight
1018 theme->a_menu_text_normal->texture[0].data.text.shadow_offset_y);
1020 /* calculate some last extents */
1022 gint ft, fb, fl, fr, ut, ub, ul, ur;
1024 RrMargins(theme->a_focused_label, &fl, &ft, &fr, &fb);
1025 RrMargins(theme->a_unfocused_label, &ul, &ut, &ur, &ub);
1026 theme->label_height = theme->win_font_height + MAX(ft + fb, ut + ub);
1028 /* this would be nice I think, since padding.width can now be 0,
1029 but it breaks frame.c horribly and I don't feel like fixing that
1030 right now, so if anyone complains, here is how to keep text from
1031 going over the title's bevel/border with a padding.width of 0 and a
1032 bevelless/borderless label
1033 RrMargins(theme->a_focused_title, &fl, &ft, &fr, &fb);
1034 RrMargins(theme->a_unfocused_title, &ul, &ut, &ur, &ub);
1035 theme->title_height = theme->label_height +
1036 MAX(MAX(theme->padding * 2, ft + fb),
1037 MAX(theme->padding * 2, ut + ub));
1039 theme->title_height = theme->label_height + theme->paddingy * 2;
1040 /* this should match the above title_height given the same font size
1042 theme->menu_title_height = theme->menu_title_font_height +
1043 theme->paddingy * 2;
1045 theme->button_size = theme->label_height - 2;
1046 theme->grip_width = 25;
1051 void RrThemeFree(RrTheme *theme)
1054 RrColorFree(theme->menu_b_color);
1055 RrColorFree(theme->frame_b_color);
1056 RrColorFree(theme->cb_unfocused_color);
1057 RrColorFree(theme->cb_focused_color);
1058 RrColorFree(theme->title_focused_color);
1059 RrColorFree(theme->title_unfocused_color);
1060 RrColorFree(theme->titlebut_disabled_focused_color);
1061 RrColorFree(theme->titlebut_disabled_unfocused_color);
1062 RrColorFree(theme->titlebut_hover_focused_color);
1063 RrColorFree(theme->titlebut_hover_unfocused_color);
1064 RrColorFree(theme->titlebut_toggled_focused_color);
1065 RrColorFree(theme->titlebut_toggled_unfocused_color);
1066 RrColorFree(theme->titlebut_focused_pressed_color);
1067 RrColorFree(theme->titlebut_unfocused_pressed_color);
1068 RrColorFree(theme->titlebut_focused_unpressed_color);
1069 RrColorFree(theme->titlebut_unfocused_unpressed_color);
1070 RrColorFree(theme->menu_title_color);
1071 RrColorFree(theme->menu_color);
1072 RrColorFree(theme->menu_disabled_color);
1073 RrColorFree(theme->menu_selected_color);
1074 RrColorFree(theme->title_focused_shadow_color);
1075 RrColorFree(theme->title_unfocused_shadow_color);
1076 RrColorFree(theme->osd_color);
1077 RrColorFree(theme->osd_shadow_color);
1078 RrColorFree(theme->menu_title_shadow_color);
1079 RrColorFree(theme->menu_text_normal_shadow_color);
1080 RrColorFree(theme->menu_text_selected_shadow_color);
1081 RrColorFree(theme->menu_text_disabled_shadow_color);
1083 g_free(theme->def_win_icon);
1085 RrPixmapMaskFree(theme->max_mask);
1086 RrPixmapMaskFree(theme->max_toggled_mask);
1087 RrPixmapMaskFree(theme->max_disabled_mask);
1088 RrPixmapMaskFree(theme->max_hover_mask);
1089 RrPixmapMaskFree(theme->max_pressed_mask);
1090 RrPixmapMaskFree(theme->desk_mask);
1091 RrPixmapMaskFree(theme->desk_toggled_mask);
1092 RrPixmapMaskFree(theme->desk_disabled_mask);
1093 RrPixmapMaskFree(theme->desk_hover_mask);
1094 RrPixmapMaskFree(theme->desk_pressed_mask);
1095 RrPixmapMaskFree(theme->shade_mask);
1096 RrPixmapMaskFree(theme->shade_toggled_mask);
1097 RrPixmapMaskFree(theme->shade_disabled_mask);
1098 RrPixmapMaskFree(theme->shade_hover_mask);
1099 RrPixmapMaskFree(theme->shade_pressed_mask);
1100 RrPixmapMaskFree(theme->iconify_mask);
1101 RrPixmapMaskFree(theme->iconify_disabled_mask);
1102 RrPixmapMaskFree(theme->iconify_hover_mask);
1103 RrPixmapMaskFree(theme->iconify_pressed_mask);
1104 RrPixmapMaskFree(theme->close_mask);
1105 RrPixmapMaskFree(theme->close_disabled_mask);
1106 RrPixmapMaskFree(theme->close_hover_mask);
1107 RrPixmapMaskFree(theme->close_pressed_mask);
1108 RrPixmapMaskFree(theme->menu_bullet_mask);
1110 RrFontClose(theme->win_font_focused);
1111 RrFontClose(theme->win_font_unfocused);
1112 RrFontClose(theme->menu_title_font);
1113 RrFontClose(theme->menu_font);
1115 RrAppearanceFree(theme->a_disabled_focused_max);
1116 RrAppearanceFree(theme->a_disabled_unfocused_max);
1117 RrAppearanceFree(theme->a_hover_focused_max);
1118 RrAppearanceFree(theme->a_hover_unfocused_max);
1119 RrAppearanceFree(theme->a_toggled_focused_max);
1120 RrAppearanceFree(theme->a_toggled_unfocused_max);
1121 RrAppearanceFree(theme->a_focused_unpressed_max);
1122 RrAppearanceFree(theme->a_focused_pressed_max);
1123 RrAppearanceFree(theme->a_unfocused_unpressed_max);
1124 RrAppearanceFree(theme->a_unfocused_pressed_max);
1125 RrAppearanceFree(theme->a_disabled_focused_close);
1126 RrAppearanceFree(theme->a_disabled_unfocused_close);
1127 RrAppearanceFree(theme->a_hover_focused_close);
1128 RrAppearanceFree(theme->a_hover_unfocused_close);
1129 RrAppearanceFree(theme->a_focused_unpressed_close);
1130 RrAppearanceFree(theme->a_focused_pressed_close);
1131 RrAppearanceFree(theme->a_unfocused_unpressed_close);
1132 RrAppearanceFree(theme->a_unfocused_pressed_close);
1133 RrAppearanceFree(theme->a_disabled_focused_desk);
1134 RrAppearanceFree(theme->a_disabled_unfocused_desk);
1135 RrAppearanceFree(theme->a_hover_focused_desk);
1136 RrAppearanceFree(theme->a_hover_unfocused_desk);
1137 RrAppearanceFree(theme->a_toggled_focused_desk);
1138 RrAppearanceFree(theme->a_toggled_unfocused_desk);
1139 RrAppearanceFree(theme->a_focused_unpressed_desk);
1140 RrAppearanceFree(theme->a_focused_pressed_desk);
1141 RrAppearanceFree(theme->a_unfocused_unpressed_desk);
1142 RrAppearanceFree(theme->a_unfocused_pressed_desk);
1143 RrAppearanceFree(theme->a_disabled_focused_shade);
1144 RrAppearanceFree(theme->a_disabled_unfocused_shade);
1145 RrAppearanceFree(theme->a_hover_focused_shade);
1146 RrAppearanceFree(theme->a_hover_unfocused_shade);
1147 RrAppearanceFree(theme->a_toggled_focused_shade);
1148 RrAppearanceFree(theme->a_toggled_unfocused_shade);
1149 RrAppearanceFree(theme->a_focused_unpressed_shade);
1150 RrAppearanceFree(theme->a_focused_pressed_shade);
1151 RrAppearanceFree(theme->a_unfocused_unpressed_shade);
1152 RrAppearanceFree(theme->a_unfocused_pressed_shade);
1153 RrAppearanceFree(theme->a_disabled_focused_iconify);
1154 RrAppearanceFree(theme->a_disabled_unfocused_iconify);
1155 RrAppearanceFree(theme->a_hover_focused_iconify);
1156 RrAppearanceFree(theme->a_hover_unfocused_iconify);
1157 RrAppearanceFree(theme->a_focused_unpressed_iconify);
1158 RrAppearanceFree(theme->a_focused_pressed_iconify);
1159 RrAppearanceFree(theme->a_unfocused_unpressed_iconify);
1160 RrAppearanceFree(theme->a_unfocused_pressed_iconify);
1161 RrAppearanceFree(theme->a_focused_grip);
1162 RrAppearanceFree(theme->a_unfocused_grip);
1163 RrAppearanceFree(theme->a_focused_title);
1164 RrAppearanceFree(theme->a_unfocused_title);
1165 RrAppearanceFree(theme->a_focused_label);
1166 RrAppearanceFree(theme->a_unfocused_label);
1167 RrAppearanceFree(theme->a_icon);
1168 RrAppearanceFree(theme->a_focused_handle);
1169 RrAppearanceFree(theme->a_unfocused_handle);
1170 RrAppearanceFree(theme->a_menu);
1171 RrAppearanceFree(theme->a_menu_title);
1172 RrAppearanceFree(theme->a_menu_normal);
1173 RrAppearanceFree(theme->a_menu_disabled);
1174 RrAppearanceFree(theme->a_menu_selected);
1175 RrAppearanceFree(theme->a_menu_text_normal);
1176 RrAppearanceFree(theme->a_menu_text_disabled);
1177 RrAppearanceFree(theme->a_menu_text_selected);
1178 RrAppearanceFree(theme->a_menu_bullet_normal);
1179 RrAppearanceFree(theme->a_menu_bullet_selected);
1180 RrAppearanceFree(theme->a_clear);
1181 RrAppearanceFree(theme->a_clear_tex);
1182 RrAppearanceFree(theme->osd_hilite_bg);
1183 RrAppearanceFree(theme->osd_hilite_fg);
1184 RrAppearanceFree(theme->osd_hilite_label);
1185 RrAppearanceFree(theme->osd_unhilite_fg);
1191 static XrmDatabase loaddb(RrTheme *theme, const gchar *name, gchar **path)
1194 XrmDatabase db = NULL;
1197 if (name[0] == '/') {
1198 s = g_build_filename(name, "openbox-3", "themerc", NULL);
1199 if ((db = XrmGetFileDatabase(s)))
1200 *path = g_path_get_dirname(s);
1203 /* XXX backwards compatibility, remove me sometime later */
1204 s = g_build_filename(g_get_home_dir(), ".themes", name,
1205 "openbox-3", "themerc", NULL);
1206 if ((db = XrmGetFileDatabase(s)))
1207 *path = g_path_get_dirname(s);
1210 for (it = parse_xdg_data_dir_paths(); !db && it;
1211 it = g_slist_next(it))
1213 s = g_build_filename(it->data, "themes", name,
1214 "openbox-3", "themerc", NULL);
1215 if ((db = XrmGetFileDatabase(s)))
1216 *path = g_path_get_dirname(s);
1222 s = g_build_filename(name, "themerc", NULL);
1223 if ((db = XrmGetFileDatabase(s)))
1224 *path = g_path_get_dirname(s);
1231 static gchar *create_class_name(const gchar *rname)
1233 gchar *rclass = g_strdup(rname);
1238 p = strchr(p+1, '.');
1239 if (p == NULL) break;
1241 if (*p == '\0') break;
1246 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value)
1248 gboolean ret = FALSE;
1249 gchar *rclass = create_class_name(rname);
1250 gchar *rettype, *end;
1253 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1254 retvalue.addr != NULL) {
1255 *value = (gint)strtol(retvalue.addr, &end, 10);
1256 if (end != retvalue.addr)
1264 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)
1266 gboolean ret = FALSE;
1267 gchar *rclass = create_class_name(rname);
1271 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1272 retvalue.addr != NULL) {
1273 *value = retvalue.addr;
1281 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
1282 const gchar *rname, RrColor **value)
1284 gboolean ret = FALSE;
1285 gchar *rclass = create_class_name(rname);
1289 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1290 retvalue.addr != NULL) {
1291 RrColor *c = RrColorParse(inst, retvalue.addr);
1302 static gboolean read_mask(const RrInstance *inst, const gchar *path,
1303 const gchar *maskname, RrTheme *theme,
1304 RrPixmapMask **value)
1306 gboolean ret = FALSE;
1308 gint hx, hy; /* ignored */
1312 s = g_build_filename(path, maskname, NULL);
1313 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) {
1315 *value = RrPixmapMaskNew(inst, w, h, (gchar*)b);
1323 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
1324 RrReliefType *relief, RrBevelType *bevel,
1325 gboolean *interlaced, gboolean *border,
1326 gboolean allow_trans)
1330 /* convert to all lowercase */
1331 for (t = tex; *t != '\0'; ++t)
1332 *t = g_ascii_tolower(*t);
1334 if (allow_trans && strstr(tex, "parentrelative") != NULL) {
1335 *grad = RR_SURFACE_PARENTREL;
1337 if (strstr(tex, "gradient") != NULL) {
1338 if (strstr(tex, "crossdiagonal") != NULL)
1339 *grad = RR_SURFACE_CROSS_DIAGONAL;
1340 else if (strstr(tex, "pyramid") != NULL)
1341 *grad = RR_SURFACE_PYRAMID;
1342 else if (strstr(tex, "mirrorhorizontal") != NULL)
1343 *grad = RR_SURFACE_MIRROR_HORIZONTAL;
1344 else if (strstr(tex, "horizontal") != NULL)
1345 *grad = RR_SURFACE_HORIZONTAL;
1346 else if (strstr(tex, "splitvertical") != NULL)
1347 *grad = RR_SURFACE_SPLIT_VERTICAL;
1348 else if (strstr(tex, "vertical") != NULL)
1349 *grad = RR_SURFACE_VERTICAL;
1351 *grad = RR_SURFACE_DIAGONAL;
1353 *grad = RR_SURFACE_SOLID;
1356 if (strstr(tex, "sunken") != NULL)
1357 *relief = RR_RELIEF_SUNKEN;
1358 else if (strstr(tex, "flat") != NULL)
1359 *relief = RR_RELIEF_FLAT;
1361 *relief = RR_RELIEF_RAISED;
1364 if (*relief == RR_RELIEF_FLAT) {
1365 if (strstr(tex, "border") != NULL)
1368 if (strstr(tex, "bevel2") != NULL)
1369 *bevel = RR_BEVEL_2;
1371 *bevel = RR_BEVEL_1;
1374 if (strstr(tex, "interlaced") != NULL)
1377 *interlaced = FALSE;
1382 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
1383 const gchar *rname, RrAppearance *value,
1384 gboolean allow_trans)
1386 gboolean ret = FALSE;
1387 gchar *rclass = create_class_name(rname);
1388 gchar *cname, *ctoname, *bcname, *icname;
1392 cname = g_strconcat(rname, ".color", NULL);
1393 ctoname = g_strconcat(rname, ".colorTo", NULL);
1394 bcname = g_strconcat(rname, ".border.color", NULL);
1395 icname = g_strconcat(rname, ".interlace.color", NULL);
1397 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1398 retvalue.addr != NULL) {
1399 parse_appearance(retvalue.addr,
1400 &value->surface.grad,
1401 &value->surface.relief,
1402 &value->surface.bevel,
1403 &value->surface.interlaced,
1404 &value->surface.border,
1406 if (!read_color(db, inst, cname, &value->surface.primary))
1407 value->surface.primary = RrColorNew(inst, 0, 0, 0);
1408 if (!read_color(db, inst, ctoname, &value->surface.secondary))
1409 value->surface.secondary = RrColorNew(inst, 0, 0, 0);
1410 if (value->surface.border)
1411 if (!read_color(db, inst, bcname,
1412 &value->surface.border_color))
1413 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
1414 if (value->surface.interlaced)
1415 if (!read_color(db, inst, icname,
1416 &value->surface.interlace_color))
1417 value->surface.interlace_color = RrColorNew(inst, 0, 0, 0);
1429 static int parse_inline_number(const char *p)
1437 for (; isdigit(*p); ++p)
1438 res = res * 10 + *p - '0';
1443 static void set_default_appearance(RrAppearance *a)
1445 a->surface.grad = RR_SURFACE_SOLID;
1446 a->surface.relief = RR_RELIEF_FLAT;
1447 a->surface.bevel = RR_BEVEL_1;
1448 a->surface.interlaced = FALSE;
1449 a->surface.border = FALSE;
1450 a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
1451 a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
1454 /* Reads the output from gimp's C-Source file format into valid RGBA data for
1455 an RrTextureRGBA. */
1456 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data)
1461 p = im = g_memdup(data, width * height * sizeof(RrPixel32));
1463 for (i = 0; i < width * height; ++i) {
1464 guchar a = ((*p >> 24) & 0xff);
1465 guchar b = ((*p >> 16) & 0xff);
1466 guchar g = ((*p >> 8) & 0xff);
1467 guchar r = ((*p >> 0) & 0xff);
1469 *p = ((r << RrDefaultRedOffset) +
1470 (g << RrDefaultGreenOffset) +
1471 (b << RrDefaultBlueOffset) +
1472 (a << RrDefaultAlphaOffset));