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 "obt/paths.h"
29 #include <X11/Xresource.h>
35 RrAppearance *focused_disabled;
36 RrAppearance *unfocused_disabled;
37 RrAppearance *focused_hover;
38 RrAppearance *unfocused_hover;
39 RrAppearance *focused_unpressed;
40 RrAppearance *focused_pressed;
41 RrAppearance *unfocused_unpressed;
42 RrAppearance *unfocused_pressed;
43 RrAppearance *focused_hover_toggled;
44 RrAppearance *unfocused_hover_toggled;
45 RrAppearance *focused_unpressed_toggled;
46 RrAppearance *focused_pressed_toggled;
47 RrAppearance *unfocused_unpressed_toggled;
48 RrAppearance *unfocused_pressed_toggled;
51 static XrmDatabase loaddb(const gchar *name, gchar **path);
52 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value);
53 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value);
54 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
55 const gchar *rname, RrColor **value);
56 static gboolean read_mask(const RrInstance *inst, const gchar *path,
57 const gchar *maskname, RrPixmapMask **value);
58 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
59 const gchar *rname, RrAppearance *value,
60 gboolean allow_trans);
61 static int parse_inline_number(const char *p);
62 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
63 static void set_default_appearance(RrAppearance *a);
64 static void read_button_styles(XrmDatabase db, const RrInstance *inst,
66 const RrTheme *theme, RrButton *btn,
68 struct fallbacks *fbs,
70 guchar *toggled_mask);
72 static RrFont *get_font(RrFont *target, RrFont **default_font,
73 const RrInstance *inst)
79 /* Only load the default font once */
81 RrFontRef(*default_font);
83 *default_font = RrFontOpenDefault(inst);
89 #define READ_INT(x_resstr, x_var, x_min, x_max, x_def) \
90 if (!read_int(db, x_resstr, & x_var) || \
91 x_var < x_min || x_var > x_max) \
94 #define READ_COLOR(x_resstr, x_var, x_def) \
95 if (!read_color(db, inst, x_resstr, & x_var)) \
98 #define READ_COLOR_(x_res1, x_res2, x_var, x_def) \
99 if (!read_color(db, inst, x_res1, & x_var) && \
100 !read_color(db, inst, x_res2, & x_var)) \
103 #define READ_MASK_COPY(x_file, x_var, x_copysrc) \
104 if (!read_mask(inst, path, x_file, & x_var)) \
105 x_var = RrPixmapMaskCopy(x_copysrc);
107 #define READ_APPEARANCE(x_resstr, x_var, x_parrel) \
108 if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) \
109 set_default_appearance(x_var);
111 #define READ_APPEARANCE_COPY(x_resstr, x_var, x_parrel, x_defval) \
112 if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) {\
113 RrAppearanceFree(x_var); \
114 x_var = RrAppearanceCopy(x_defval); }
116 #define READ_APPEARANCE_COPY_TEXTURES(x_resstr, x_var, x_parrel, x_defval, n_tex) \
117 if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) {\
118 RrAppearanceFree(x_var); \
119 x_var = RrAppearanceCopy(x_defval); \
120 RrAppearanceRemoveTextures(x_var); \
121 RrAppearanceAddTextures(x_var, 5); }
123 #define READ_APPEARANCE_(x_res1, x_res2, x_var, x_parrel, x_defval) \
124 if (!read_appearance(db, inst, x_res1, x_var, x_parrel) && \
125 !read_appearance(db, inst, x_res2, x_var, x_parrel)) {\
126 RrAppearanceFree(x_var); \
127 x_var = RrAppearanceCopy(x_defval); }
129 RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
130 gboolean allow_fallback,
131 RrFont *active_window_font, RrFont *inactive_window_font,
132 RrFont *menu_title_font, RrFont *menu_item_font,
133 RrFont *active_osd_font, RrFont *inactive_osd_font)
135 XrmDatabase db = NULL;
136 RrJustify winjust, mtitlejust;
139 RrFont *default_font = NULL;
141 gint menu_overlap = 0;
142 struct fallbacks fbs;
145 db = loaddb(name, &path);
147 g_message("Unable to load the theme '%s'", name);
149 g_message("Falling back to the default theme '%s'",
151 /* fallback to the default theme */
156 if (allow_fallback) {
157 db = loaddb(DEFAULT_THEME, &path);
159 g_message("Unable to load the theme '%s'", DEFAULT_THEME);
166 /* initialize temp reading textures */
167 fbs.focused_disabled = RrAppearanceNew(inst, 1);
168 fbs.unfocused_disabled = RrAppearanceNew(inst, 1);
169 fbs.focused_hover = RrAppearanceNew(inst, 1);
170 fbs.unfocused_hover = RrAppearanceNew(inst, 1);
171 fbs.focused_unpressed_toggled = RrAppearanceNew(inst, 1);
172 fbs.unfocused_unpressed_toggled = RrAppearanceNew(inst, 1);
173 fbs.focused_hover_toggled = RrAppearanceNew(inst, 1);
174 fbs.unfocused_hover_toggled = RrAppearanceNew(inst, 1);
175 fbs.focused_pressed_toggled = RrAppearanceNew(inst, 1);
176 fbs.unfocused_pressed_toggled = RrAppearanceNew(inst, 1);
177 fbs.focused_unpressed = RrAppearanceNew(inst, 1);
178 fbs.focused_pressed = RrAppearanceNew(inst, 1);
179 fbs.unfocused_unpressed = RrAppearanceNew(inst, 1);
180 fbs.unfocused_pressed = RrAppearanceNew(inst, 1);
182 /* initialize theme */
183 theme = g_slice_new0(RrTheme);
186 theme->name = g_strdup(name ? name : DEFAULT_THEME);
189 theme->btn_max = RrButtonNew(inst);
190 theme->btn_close = RrButtonNew(inst);
191 theme->btn_desk = RrButtonNew(inst);
192 theme->btn_shade = RrButtonNew(inst);
193 theme->btn_iconify = RrButtonNew(inst);
195 /* init appearances */
196 theme->a_focused_grip = RrAppearanceNew(inst, 0);
197 theme->a_unfocused_grip = RrAppearanceNew(inst, 0);
198 theme->a_focused_title = RrAppearanceNew(inst, 0);
199 theme->a_unfocused_title = RrAppearanceNew(inst, 0);
200 theme->a_focused_label = RrAppearanceNew(inst, 1);
201 theme->a_unfocused_label = RrAppearanceNew(inst, 1);
202 theme->a_icon = RrAppearanceNew(inst, 1);
203 theme->a_focused_handle = RrAppearanceNew(inst, 0);
204 theme->a_unfocused_handle = RrAppearanceNew(inst, 0);
205 theme->a_menu = RrAppearanceNew(inst, 0);
206 theme->a_menu_title = RrAppearanceNew(inst, 0);
207 theme->a_menu_text_title = RrAppearanceNew(inst, 1);
208 theme->a_menu_normal = RrAppearanceNew(inst, 0);
209 theme->a_menu_selected = RrAppearanceNew(inst, 0);
210 theme->a_menu_disabled = RrAppearanceNew(inst, 0);
211 /* a_menu_disabled_selected is copied from a_menu_selected */
212 theme->a_menu_text_normal = RrAppearanceNew(inst, 1);
213 theme->a_menu_text_selected = RrAppearanceNew(inst, 1);
214 theme->a_menu_text_disabled = RrAppearanceNew(inst, 1);
215 theme->a_menu_text_disabled_selected = RrAppearanceNew(inst, 1);
216 theme->a_menu_bullet_normal = RrAppearanceNew(inst, 1);
217 theme->a_menu_bullet_selected = RrAppearanceNew(inst, 1);
218 theme->a_clear = RrAppearanceNew(inst, 0);
219 theme->a_clear_tex = RrAppearanceNew(inst, 1);
220 theme->osd_bg = RrAppearanceNew(inst, 0);
221 theme->osd_hilite_label = RrAppearanceNew(inst, 1);
222 theme->osd_hilite_bg = RrAppearanceNew(inst, 0);
223 theme->osd_unhilite_label = RrAppearanceNew(inst, 1);
224 theme->osd_unhilite_bg = RrAppearanceNew(inst, 0);
225 theme->osd_unpressed_button = RrAppearanceNew(inst, 1);
226 theme->osd_pressed_button = RrAppearanceNew(inst, 5);
227 theme->osd_focused_button = RrAppearanceNew(inst, 5);
229 /* load the font stuff */
230 theme->win_font_focused = get_font(active_window_font,
231 &default_font, inst);
232 theme->win_font_unfocused = get_font(inactive_window_font,
233 &default_font, inst);
235 winjust = RR_JUSTIFY_LEFT;
236 if (read_string(db, "window.label.text.justify", &str)) {
237 if (!g_ascii_strcasecmp(str, "right"))
238 winjust = RR_JUSTIFY_RIGHT;
239 else if (!g_ascii_strcasecmp(str, "center"))
240 winjust = RR_JUSTIFY_CENTER;
243 theme->menu_title_font = get_font(menu_title_font, &default_font, inst);
245 mtitlejust = RR_JUSTIFY_LEFT;
246 if (read_string(db, "menu.title.text.justify", &str)) {
247 if (!g_ascii_strcasecmp(str, "right"))
248 mtitlejust = RR_JUSTIFY_RIGHT;
249 else if (!g_ascii_strcasecmp(str, "center"))
250 mtitlejust = RR_JUSTIFY_CENTER;
253 theme->menu_font = get_font(menu_item_font, &default_font, inst);
255 theme->osd_font_hilite = get_font(active_osd_font, &default_font, inst);
256 theme->osd_font_unhilite = get_font(inactive_osd_font, &default_font,inst);
258 /* load direct dimensions */
259 READ_INT("menu.overlap", menu_overlap, -100, 100, 0);
260 READ_INT("menu.overlap.x", theme->menu_overlap_x, -100, 100, menu_overlap);
261 READ_INT("menu.overlap.y", theme->menu_overlap_y, -100, 100, menu_overlap);
262 READ_INT("window.handle.width", theme->handle_height, 0, 100, 6);
263 READ_INT("padding.width", theme->paddingx, 0, 100, 3);
264 READ_INT("padding.height", theme->paddingy, 0, 100, theme->paddingx);
265 READ_INT("border.width", theme->fbwidth, 0, 100, 1);
266 READ_INT("menu.border.width", theme->mbwidth, 0, 100, theme->fbwidth);
267 READ_INT("osd.border.width", theme->obwidth, 0, 100, theme->fbwidth);
268 READ_INT("undecorated.border.width", theme->ubwidth, 0, 100, theme->fbwidth);
269 READ_INT("menu.separator.width", theme->menu_sep_width, 1, 100, 1);
270 READ_INT("menu.separator.padding.width", theme->menu_sep_paddingx, 0, 100, 6);
271 READ_INT("menu.separator.padding.height", theme->menu_sep_paddingy, 0, 100, 3);
272 READ_INT("window.client.padding.width", theme->cbwidthx, 0, 100, theme->paddingx);
273 READ_INT("window.client.padding.height", theme->cbwidthy, 0, 100, theme->cbwidthx);
276 READ_COLOR_("window.active.border.color",
278 theme->frame_focused_border_color,
279 RrColorNew(inst, 0, 0, 0));
280 READ_COLOR("window.undecorated.active.border.color",
281 theme->frame_undecorated_focused_border_color,
282 RrColorCopy(theme->frame_focused_border_color));
283 READ_COLOR("window.active.title.separator.color",
284 theme->title_separator_focused_color,
285 RrColorCopy(theme->frame_focused_border_color));
287 READ_COLOR("window.inactive.border.color",
288 theme->frame_unfocused_border_color,
289 RrColorCopy(theme->frame_focused_border_color));
291 READ_COLOR("window.undecorated.inactive.border.color",
292 theme->frame_undecorated_unfocused_border_color,
293 RrColorCopy(theme->frame_unfocused_border_color));
295 READ_COLOR("window.inactive.title.separator.color",
296 theme->title_separator_unfocused_color,
297 RrColorCopy(theme->frame_unfocused_border_color));
299 READ_COLOR("menu.border.color",
300 theme->menu_border_color,
301 RrColorCopy(theme->frame_focused_border_color));
303 READ_COLOR("osd.border.color",
304 theme->osd_border_color,
305 RrColorCopy(theme->frame_focused_border_color));
307 READ_COLOR("window.active.client.color",
308 theme->cb_focused_color,
309 RrColorNew(inst, 0xff, 0xff, 0xff));
311 READ_COLOR("window.inactive.client.color",
312 theme->cb_unfocused_color,
313 RrColorNew(inst, 0xff, 0xff, 0xff));
315 READ_COLOR("window.active.label.text.color",
316 theme->title_focused_color,
317 RrColorNew(inst, 0x0, 0x0, 0x0));
319 READ_COLOR("window.inactive.label.text.color",
320 theme->title_unfocused_color,
321 RrColorNew(inst, 0xff, 0xff, 0xff));
323 READ_COLOR_("osd.active.label.text.color",
324 "osd.label.text.color",
325 theme->osd_text_active_color,
326 RrColorCopy(theme->title_focused_color));
328 READ_COLOR_("osd.inactive.label.text.color",
329 "osd.label.text.color",
330 theme->osd_text_inactive_color,
331 RrColorCopy(theme->title_unfocused_color));
333 READ_COLOR("window.active.button.unpressed.image.color",
334 theme->titlebut_focused_unpressed_color,
335 RrColorNew(inst, 0, 0, 0));
337 READ_COLOR("window.inactive.button.unpressed.image.color",
338 theme->titlebut_unfocused_unpressed_color,
339 RrColorNew(inst, 0xff, 0xff, 0xff));
341 READ_COLOR("window.active.button.pressed.image.color",
342 theme->titlebut_focused_pressed_color,
343 RrColorCopy(theme->titlebut_focused_unpressed_color));
345 READ_COLOR("window.inactive.button.pressed.image.color",
346 theme->titlebut_unfocused_pressed_color,
347 RrColorCopy(theme->titlebut_unfocused_unpressed_color));
349 READ_COLOR("window.active.button.disabled.image.color",
350 theme->titlebut_focused_disabled_color,
351 RrColorNew(inst, 0xff, 0xff, 0xff));
353 READ_COLOR("window.inactive.button.disabled.image.color",
354 theme->titlebut_unfocused_disabled_color,
355 RrColorNew(inst, 0, 0, 0));
357 READ_COLOR("window.active.button.hover.image.color",
358 theme->titlebut_focused_hover_color,
359 RrColorCopy(theme->titlebut_focused_unpressed_color));
361 READ_COLOR("window.inactive.button.hover.image.color",
362 theme->titlebut_unfocused_hover_color,
363 RrColorCopy(theme->titlebut_unfocused_unpressed_color));
365 READ_COLOR_("window.active.button.toggled.unpressed.image.color",
366 "window.active.button.toggled.image.color",
367 theme->titlebut_focused_unpressed_toggled_color,
368 RrColorCopy(theme->titlebut_focused_pressed_color));
370 READ_COLOR_("window.inactive.button.toggled.unpressed.image.color",
371 "window.inactive.button.toggled.image.color",
372 theme->titlebut_unfocused_unpressed_toggled_color,
373 RrColorCopy(theme->titlebut_unfocused_pressed_color));
375 READ_COLOR("window.active.button.toggled.hover.image.color",
376 theme->titlebut_focused_hover_toggled_color,
377 RrColorCopy(theme->titlebut_focused_unpressed_toggled_color));
379 READ_COLOR("window.inactive.button.toggled.hover.image.color",
380 theme->titlebut_unfocused_hover_toggled_color,
381 RrColorCopy(theme->titlebut_unfocused_unpressed_toggled_color));
383 READ_COLOR("window.active.button.toggled.pressed.image.color",
384 theme->titlebut_focused_pressed_toggled_color,
385 RrColorCopy(theme->titlebut_focused_pressed_color));
387 READ_COLOR("window.inactive.button.toggled.pressed.image.color",
388 theme->titlebut_unfocused_pressed_toggled_color,
389 RrColorCopy(theme->titlebut_unfocused_pressed_color));
391 READ_COLOR("menu.title.text.color",
392 theme->menu_title_color,
393 RrColorNew(inst, 0, 0, 0));
395 READ_COLOR("menu.items.text.color",
397 RrColorNew(inst, 0xff, 0xff, 0xff));
399 READ_COLOR("menu.bullet.image.color",
400 theme->menu_bullet_color,
401 RrColorCopy(theme->menu_color));
403 READ_COLOR("menu.items.disabled.text.color",
404 theme->menu_disabled_color,
405 RrColorNew(inst, 0, 0, 0));
407 READ_COLOR("menu.items.active.disabled.text.color",
408 theme->menu_disabled_selected_color,
409 RrColorCopy(theme->menu_disabled_color));
411 READ_COLOR("menu.items.active.text.color",
412 theme->menu_selected_color,
413 RrColorNew(inst, 0, 0, 0));
415 READ_COLOR("menu.separator.color",
416 theme->menu_sep_color,
417 RrColorCopy(theme->menu_color));
419 READ_COLOR("menu.bullet.selected.image.color",
420 theme->menu_bullet_selected_color,
421 RrColorCopy(theme->menu_selected_color));
423 READ_COLOR("osd.button.unpressed.text.color",
424 theme->osd_unpressed_color,
425 RrColorCopy(theme->osd_text_active_color));
426 READ_COLOR("osd.button.pressed.text.color",
427 theme->osd_pressed_color,
428 RrColorCopy(theme->osd_text_active_color));
429 READ_COLOR("osd.button.focused.text.color",
430 theme->osd_focused_color,
431 RrColorCopy(theme->osd_text_active_color));
432 READ_COLOR("osd.button.pressed.box.color",
433 theme->osd_pressed_lineart,
434 RrColorCopy(theme->titlebut_focused_pressed_color));
435 READ_COLOR("osd.button.focused.box.color",
436 theme->osd_focused_lineart,
437 RrColorCopy(theme->titlebut_focused_hover_color));
439 /* load window buttons */
441 /* bases: unpressed, pressed, disabled */
442 READ_APPEARANCE("window.active.button.unpressed.bg", fbs.focused_unpressed, TRUE);
443 READ_APPEARANCE("window.inactive.button.unpressed.bg", fbs.unfocused_unpressed, TRUE);
444 READ_APPEARANCE("window.active.button.pressed.bg", fbs.focused_pressed, TRUE);
445 READ_APPEARANCE("window.inactive.button.pressed.bg", fbs.unfocused_pressed, TRUE);
446 READ_APPEARANCE("window.active.button.disabled.bg", fbs.focused_disabled, TRUE);
447 READ_APPEARANCE("window.inactive.button.disabled.bg", fbs.unfocused_disabled, TRUE);
450 READ_APPEARANCE_COPY("window.active.button.hover.bg",
451 fbs.focused_hover, TRUE,
452 fbs.focused_unpressed);
453 READ_APPEARANCE_COPY("window.inactive.button.hover.bg",
454 fbs.unfocused_hover, TRUE,
455 fbs.unfocused_unpressed);
457 /* toggled unpressed */
458 READ_APPEARANCE_("window.active.button.toggled.unpressed.bg",
459 "window.active.button.toggled.bg",
460 fbs.focused_unpressed_toggled, TRUE,
461 fbs.focused_pressed);
462 READ_APPEARANCE_("window.inactive.button.toggled.unpressed.bg",
463 "window.inactive.button.toggled.bg",
464 fbs.unfocused_unpressed_toggled, TRUE,
465 fbs.unfocused_pressed);
467 /* toggled pressed */
468 READ_APPEARANCE_COPY("window.active.button.toggled.pressed.bg",
469 fbs.focused_pressed_toggled, TRUE,
470 fbs.focused_pressed);
471 READ_APPEARANCE_COPY("window.inactive.button.toggled.pressed.bg",
472 fbs.unfocused_pressed_toggled, TRUE,
473 fbs.unfocused_pressed);
476 READ_APPEARANCE_COPY("window.active.button.toggled.hover.bg",
477 fbs.focused_hover_toggled, TRUE,
478 fbs.focused_unpressed_toggled);
479 READ_APPEARANCE_COPY("window.inactive.button.toggled.hover.bg",
480 fbs.unfocused_hover_toggled, TRUE,
481 fbs.unfocused_unpressed_toggled);
484 /* now do individual buttons, if specified */
488 guchar normal_mask[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f };
489 guchar toggled_mask[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f };
490 read_button_styles(db, inst, path, theme, theme->btn_max, "max",
491 &fbs, normal_mask, toggled_mask);
496 guchar normal_mask[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
497 read_button_styles(db, inst, path, theme, theme->btn_close, "close",
498 &fbs, normal_mask, NULL);
501 /* all desktops button */
503 guchar normal_mask[] = { 0x33, 0x33, 0x00, 0x00, 0x33, 0x33 };
504 guchar toggled_mask[] = { 0x00, 0x1e, 0x1a, 0x16, 0x1e, 0x00 };
505 read_button_styles(db, inst, path, theme, theme->btn_desk, "desk",
506 &fbs, normal_mask, toggled_mask);
511 guchar normal_mask[] = { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 };
512 read_button_styles(db, inst, path, theme, theme->btn_shade, "shade",
513 &fbs, normal_mask, normal_mask);
518 guchar normal_mask[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f };
519 read_button_styles(db, inst, path, theme, theme->btn_iconify, "iconify",
520 &fbs, normal_mask, NULL);
523 /* submenu bullet mask */
524 if (!read_mask(inst, path, "bullet.xbm", &theme->menu_bullet_mask))
526 guchar data[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01 };
527 theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
530 /* up and down arrows */
532 guchar data[] = { 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00 };
533 theme->down_arrow_mask = RrPixmapMaskNew(inst, 9, 4, (gchar*)data);
536 guchar data[] = { 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00 };
537 theme->up_arrow_mask = RrPixmapMaskNew(inst, 9, 4, (gchar*)data);
540 /* setup the default window icon */
541 theme->def_win_icon = read_c_image(OB_DEFAULT_ICON_WIDTH,
542 OB_DEFAULT_ICON_HEIGHT,
543 OB_DEFAULT_ICON_pixel_data);
544 theme->def_win_icon_w = OB_DEFAULT_ICON_WIDTH;
545 theme->def_win_icon_h = OB_DEFAULT_ICON_HEIGHT;
547 /* read the decoration textures */
548 READ_APPEARANCE("window.active.title.bg", theme->a_focused_title, FALSE);
549 READ_APPEARANCE("window.inactive.title.bg", theme->a_unfocused_title, FALSE);
550 READ_APPEARANCE("window.active.label.bg", theme->a_focused_label, TRUE);
551 READ_APPEARANCE("window.inactive.label.bg", theme->a_unfocused_label, TRUE);
552 READ_APPEARANCE("window.active.handle.bg", theme->a_focused_handle, FALSE);
553 READ_APPEARANCE("window.inactive.handle.bg",theme->a_unfocused_handle, FALSE);
554 READ_APPEARANCE("window.active.grip.bg", theme->a_focused_grip, TRUE);
555 READ_APPEARANCE("window.inactive.grip.bg", theme->a_unfocused_grip, TRUE);
556 READ_APPEARANCE("menu.items.bg", theme->a_menu, FALSE);
557 READ_APPEARANCE("menu.title.bg", theme->a_menu_title, TRUE);
558 READ_APPEARANCE("menu.items.active.bg", theme->a_menu_selected, TRUE);
560 theme->a_menu_disabled_selected =
561 RrAppearanceCopy(theme->a_menu_selected);
563 /* read appearances for non-decorations (on-screen-display) */
564 if (!read_appearance(db, inst, "osd.bg", theme->osd_bg, FALSE))
566 RrAppearanceFree(theme->osd_bg);
567 theme->osd_bg = RrAppearanceCopy(theme->a_focused_title);
569 if (!read_appearance(db, inst, "osd.active.label.bg",
570 theme->osd_hilite_label, TRUE) &&
571 !read_appearance(db, inst, "osd.label.bg",
572 theme->osd_hilite_label, TRUE))
574 RrAppearanceFree(theme->osd_hilite_label);
575 theme->osd_hilite_label = RrAppearanceCopy(theme->a_focused_label);
577 if (!read_appearance(db, inst, "osd.inactive.label.bg",
578 theme->osd_unhilite_label, TRUE))
580 RrAppearanceFree(theme->osd_unhilite_label);
581 theme->osd_unhilite_label = RrAppearanceCopy(theme->a_unfocused_label);
583 /* osd_hilite_fg can't be parentrel */
584 if (!read_appearance(db, inst, "osd.hilight.bg",
585 theme->osd_hilite_bg, FALSE))
587 RrAppearanceFree(theme->osd_hilite_bg);
588 if (theme->a_focused_label->surface.grad != RR_SURFACE_PARENTREL)
589 theme->osd_hilite_bg = RrAppearanceCopy(theme->a_focused_label);
591 theme->osd_hilite_bg = RrAppearanceCopy(theme->a_focused_title);
593 /* osd_unhilite_fg can't be parentrel either */
594 if (!read_appearance(db, inst, "osd.unhilight.bg",
595 theme->osd_unhilite_bg, FALSE))
597 RrAppearanceFree(theme->osd_unhilite_bg);
598 if (theme->a_unfocused_label->surface.grad != RR_SURFACE_PARENTREL)
599 theme->osd_unhilite_bg=RrAppearanceCopy(theme->a_unfocused_label);
601 theme->osd_unhilite_bg=RrAppearanceCopy(theme->a_unfocused_title);
605 READ_APPEARANCE_COPY("osd.button.unpressed.bg", theme->osd_unpressed_button, TRUE, fbs.focused_unpressed);
606 READ_APPEARANCE_COPY_TEXTURES("osd.button.pressed.bg", theme->osd_pressed_button, TRUE, fbs.focused_pressed, 5);
607 READ_APPEARANCE_COPY_TEXTURES("osd.button.focused.bg", theme->osd_focused_button, TRUE, fbs.focused_unpressed, 5);
609 theme->a_icon->surface.grad =
610 theme->a_clear->surface.grad =
611 theme->a_clear_tex->surface.grad =
612 theme->a_menu_text_title->surface.grad =
613 theme->a_menu_normal->surface.grad =
614 theme->a_menu_disabled->surface.grad =
615 theme->a_menu_text_normal->surface.grad =
616 theme->a_menu_text_selected->surface.grad =
617 theme->a_menu_text_disabled->surface.grad =
618 theme->a_menu_text_disabled_selected->surface.grad =
619 theme->a_menu_bullet_normal->surface.grad =
620 theme->a_menu_bullet_selected->surface.grad = RR_SURFACE_PARENTREL;
622 /* set up the textures */
623 theme->a_focused_label->texture[0].type = RR_TEXTURE_TEXT;
624 theme->a_focused_label->texture[0].data.text.justify = winjust;
625 theme->a_focused_label->texture[0].data.text.font=theme->win_font_focused;
626 theme->a_focused_label->texture[0].data.text.color =
627 theme->title_focused_color;
629 if (read_string(db, "window.active.label.text.font", &str)) {
633 if (strstr(str, "shadow=y")) {
634 if ((p = strstr(str, "shadowoffset=")))
635 i = parse_inline_number(p + strlen("shadowoffset="));
638 theme->a_focused_label->texture[0].data.text.shadow_offset_x = i;
639 theme->a_focused_label->texture[0].data.text.shadow_offset_y = i;
641 if ((p = strstr(str, "shadowtint="))) {
642 i = parse_inline_number(p + strlen("shadowtint="));
643 j = (i > 0 ? 0 : 255);
646 theme->title_focused_shadow_color = RrColorNew(inst, j, j, j);
647 theme->title_focused_shadow_alpha = i;
649 theme->title_focused_shadow_color = RrColorNew(inst, 0, 0, 0);
650 theme->title_focused_shadow_alpha = 50;
654 theme->a_focused_label->texture[0].data.text.shadow_color = theme->title_focused_shadow_color;
655 theme->a_focused_label->texture[0].data.text.shadow_alpha = theme->title_focused_shadow_alpha;
657 theme->osd_hilite_label->texture[0].type = RR_TEXTURE_TEXT;
658 theme->osd_hilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
659 theme->osd_hilite_label->texture[0].data.text.font = theme->osd_font_hilite;
660 theme->osd_hilite_label->texture[0].data.text.color = theme->osd_text_active_color;
662 if (read_string(db, "osd.active.label.text.font", &str) ||
663 read_string(db, "osd.label.text.font", &str))
668 if (strstr(str, "shadow=y")) {
669 if ((p = strstr(str, "shadowoffset=")))
670 i = parse_inline_number(p + strlen("shadowoffset="));
673 theme->osd_hilite_label->texture[0].data.text.shadow_offset_x = i;
674 theme->osd_hilite_label->texture[0].data.text.shadow_offset_y = i;
676 if ((p = strstr(str, "shadowtint="))) {
677 i = parse_inline_number(p + strlen("shadowtint="));
678 j = (i > 0 ? 0 : 255);
681 theme->osd_text_active_shadow_color = RrColorNew(inst, j, j, j);
682 theme->osd_text_active_shadow_alpha = i;
684 theme->osd_text_active_shadow_color = RrColorNew(inst, 0, 0, 0);
685 theme->osd_text_active_shadow_alpha = 50;
688 /* inherit the font settings from the focused label */
689 theme->osd_hilite_label->texture[0].data.text.shadow_offset_x =
690 theme->a_focused_label->texture[0].data.text.shadow_offset_x;
691 theme->osd_hilite_label->texture[0].data.text.shadow_offset_y =
692 theme->a_focused_label->texture[0].data.text.shadow_offset_y;
693 if (theme->title_focused_shadow_color)
694 theme->osd_text_active_shadow_color =
695 RrColorCopy(theme->title_focused_shadow_color);
697 theme->osd_text_active_shadow_color = RrColorNew(inst, 0, 0, 0);
698 theme->osd_text_active_shadow_alpha =
699 theme->title_focused_shadow_alpha;
702 theme->osd_hilite_label->texture[0].data.text.shadow_color =
703 theme->osd_text_active_shadow_color;
704 theme->osd_hilite_label->texture[0].data.text.shadow_alpha =
705 theme->osd_text_active_shadow_alpha;
707 theme->osd_unpressed_button->texture[0].type =
708 theme->osd_pressed_button->texture[0].type =
709 theme->osd_focused_button->texture[0].type =
712 theme->osd_unpressed_button->texture[0].data.text.justify =
713 theme->osd_pressed_button->texture[0].data.text.justify =
714 theme->osd_focused_button->texture[0].data.text.justify =
717 theme->osd_unpressed_button->texture[0].data.text.font =
718 theme->osd_pressed_button->texture[0].data.text.font =
719 theme->osd_focused_button->texture[0].data.text.font =
720 theme->osd_font_hilite;
722 theme->osd_unpressed_button->texture[0].data.text.color =
723 theme->osd_unpressed_color;
724 theme->osd_pressed_button->texture[0].data.text.color =
725 theme->osd_pressed_color;
726 theme->osd_focused_button->texture[0].data.text.color =
727 theme->osd_focused_color;
729 theme->osd_pressed_button->texture[1].data.lineart.color =
730 theme->osd_pressed_button->texture[2].data.lineart.color =
731 theme->osd_pressed_button->texture[3].data.lineart.color =
732 theme->osd_pressed_button->texture[4].data.lineart.color =
733 theme->osd_pressed_lineart;
735 theme->osd_focused_button->texture[1].data.lineart.color =
736 theme->osd_focused_button->texture[2].data.lineart.color =
737 theme->osd_focused_button->texture[3].data.lineart.color =
738 theme->osd_focused_button->texture[4].data.lineart.color =
739 theme->osd_focused_lineart;
741 theme->a_unfocused_label->texture[0].type = RR_TEXTURE_TEXT;
742 theme->a_unfocused_label->texture[0].data.text.justify = winjust;
743 theme->a_unfocused_label->texture[0].data.text.font = theme->win_font_unfocused;
744 theme->a_unfocused_label->texture[0].data.text.color = theme->title_unfocused_color;
746 if (read_string(db, "window.inactive.label.text.font", &str)) {
750 if (strstr(str, "shadow=y")) {
751 if ((p = strstr(str, "shadowoffset=")))
752 i = parse_inline_number(p + strlen("shadowoffset="));
755 theme->a_unfocused_label->texture[0].data.text.shadow_offset_x = i;
756 theme->a_unfocused_label->texture[0].data.text.shadow_offset_y = i;
758 if ((p = strstr(str, "shadowtint="))) {
759 i = parse_inline_number(p + strlen("shadowtint="));
760 j = (i > 0 ? 0 : 255);
763 theme->title_unfocused_shadow_color = RrColorNew(inst, j, j, j);
764 theme->title_unfocused_shadow_alpha = i;
766 theme->title_unfocused_shadow_color = RrColorNew(inst, 0, 0, 0);
767 theme->title_unfocused_shadow_alpha = 50;
771 theme->a_unfocused_label->texture[0].data.text.shadow_color =
772 theme->title_unfocused_shadow_color;
773 theme->a_unfocused_label->texture[0].data.text.shadow_alpha =
774 theme->title_unfocused_shadow_alpha;
776 theme->osd_unhilite_label->texture[0].type = RR_TEXTURE_TEXT;
777 theme->osd_unhilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
778 theme->osd_unhilite_label->texture[0].data.text.font =
779 theme->osd_font_unhilite;
780 theme->osd_unhilite_label->texture[0].data.text.color =
781 theme->osd_text_inactive_color;
783 if (read_string(db, "osd.inactive.label.text.font", &str)) {
787 if (strstr(str, "shadow=y")) {
788 if ((p = strstr(str, "shadowoffset=")))
789 i = parse_inline_number(p + strlen("shadowoffset="));
792 theme->osd_unhilite_label->texture[0].data.text.shadow_offset_x=i;
793 theme->osd_unhilite_label->texture[0].data.text.shadow_offset_y=i;
795 if ((p = strstr(str, "shadowtint="))) {
796 i = parse_inline_number(p + strlen("shadowtint="));
797 j = (i > 0 ? 0 : 255);
800 theme->osd_text_inactive_shadow_color = RrColorNew(inst, j, j, j);
801 theme->osd_text_inactive_shadow_alpha = i;
803 theme->osd_text_inactive_shadow_color = RrColorNew(inst, 0, 0, 0);
804 theme->osd_text_inactive_shadow_alpha = 50;
807 /* inherit the font settings from the unfocused label */
808 theme->osd_unhilite_label->texture[0].data.text.shadow_offset_x =
809 theme->a_unfocused_label->texture[0].data.text.shadow_offset_x;
810 theme->osd_unhilite_label->texture[0].data.text.shadow_offset_y =
811 theme->a_unfocused_label->texture[0].data.text.shadow_offset_y;
812 if (theme->title_unfocused_shadow_color)
813 theme->osd_text_inactive_shadow_color =
814 RrColorCopy(theme->title_unfocused_shadow_color);
816 theme->osd_text_inactive_shadow_color = RrColorNew(inst, 0, 0, 0);
817 theme->osd_text_inactive_shadow_alpha =
818 theme->title_unfocused_shadow_alpha;
821 theme->osd_unhilite_label->texture[0].data.text.shadow_color =
822 theme->osd_text_inactive_shadow_color;
823 theme->osd_unhilite_label->texture[0].data.text.shadow_alpha =
824 theme->osd_text_inactive_shadow_alpha;
826 theme->a_menu_text_title->texture[0].type = RR_TEXTURE_TEXT;
827 theme->a_menu_text_title->texture[0].data.text.justify = mtitlejust;
828 theme->a_menu_text_title->texture[0].data.text.font = theme->menu_title_font;
829 theme->a_menu_text_title->texture[0].data.text.color = theme->menu_title_color;
831 if (read_string(db, "menu.title.text.font", &str)) {
835 if (strstr(str, "shadow=y")) {
836 if ((p = strstr(str, "shadowoffset=")))
837 i = parse_inline_number(p + strlen("shadowoffset="));
840 theme->a_menu_text_title->texture[0].data.text.shadow_offset_x = i;
841 theme->a_menu_text_title->texture[0].data.text.shadow_offset_y = i;
843 if ((p = strstr(str, "shadowtint="))) {
844 i = parse_inline_number(p + strlen("shadowtint="));
845 j = (i > 0 ? 0 : 255);
848 theme->menu_title_shadow_color = RrColorNew(inst, j, j, j);
849 theme->menu_title_shadow_alpha = i;
851 theme->menu_title_shadow_color = RrColorNew(inst, 0, 0, 0);
852 theme->menu_title_shadow_alpha = 50;
856 theme->a_menu_text_title->texture[0].data.text.shadow_color =
857 theme->menu_title_shadow_color;
858 theme->a_menu_text_title->texture[0].data.text.shadow_alpha =
859 theme->menu_title_shadow_alpha;
861 theme->a_menu_text_normal->texture[0].type =
862 theme->a_menu_text_selected->texture[0].type =
863 theme->a_menu_text_disabled->texture[0].type =
864 theme->a_menu_text_disabled_selected->texture[0].type =
866 theme->a_menu_text_normal->texture[0].data.text.justify =
867 theme->a_menu_text_selected->texture[0].data.text.justify =
868 theme->a_menu_text_disabled->texture[0].data.text.justify =
869 theme->a_menu_text_disabled_selected->texture[0].data.text.justify =
871 theme->a_menu_text_normal->texture[0].data.text.font =
872 theme->a_menu_text_selected->texture[0].data.text.font =
873 theme->a_menu_text_disabled->texture[0].data.text.font =
874 theme->a_menu_text_disabled_selected->texture[0].data.text.font =
876 theme->a_menu_text_normal->texture[0].data.text.color = theme->menu_color;
877 theme->a_menu_text_selected->texture[0].data.text.color =
878 theme->menu_selected_color;
879 theme->a_menu_text_disabled->texture[0].data.text.color =
880 theme->menu_disabled_color;
881 theme->a_menu_text_disabled_selected->texture[0].data.text.color =
882 theme->menu_disabled_selected_color;
884 if (read_string(db, "menu.items.font", &str)) {
888 if (strstr(str, "shadow=y")) {
889 if ((p = strstr(str, "shadowoffset=")))
890 i = parse_inline_number(p + strlen("shadowoffset="));
893 theme->a_menu_text_normal->
894 texture[0].data.text.shadow_offset_x = i;
895 theme->a_menu_text_normal->
896 texture[0].data.text.shadow_offset_y = i;
897 theme->a_menu_text_selected->
898 texture[0].data.text.shadow_offset_x = i;
899 theme->a_menu_text_selected->
900 texture[0].data.text.shadow_offset_y = i;
901 theme->a_menu_text_disabled->
902 texture[0].data.text.shadow_offset_x = i;
903 theme->a_menu_text_disabled->
904 texture[0].data.text.shadow_offset_y = i;
905 theme->a_menu_text_disabled_selected->
906 texture[0].data.text.shadow_offset_x = i;
907 theme->a_menu_text_disabled_selected->
908 texture[0].data.text.shadow_offset_y = i;
910 if ((p = strstr(str, "shadowtint="))) {
911 i = parse_inline_number(p + strlen("shadowtint="));
912 j = (i > 0 ? 0 : 255);
915 theme->menu_text_normal_shadow_color = RrColorNew(inst, j, j, j);
916 theme->menu_text_selected_shadow_color = RrColorNew(inst, j, j, j);
917 theme->menu_text_disabled_shadow_color = RrColorNew(inst, j, j, j);
918 theme->menu_text_normal_shadow_alpha = i;
919 theme->menu_text_selected_shadow_alpha = i;
920 theme->menu_text_disabled_shadow_alpha = i;
921 theme->menu_text_disabled_selected_shadow_alpha = i;
923 theme->menu_text_normal_shadow_color = RrColorNew(inst, 0, 0, 0);
924 theme->menu_text_selected_shadow_color = RrColorNew(inst, 0, 0, 0);
925 theme->menu_text_disabled_shadow_color = RrColorNew(inst, 0, 0, 0);
926 theme->menu_text_normal_shadow_alpha = 50;
927 theme->menu_text_selected_shadow_alpha = 50;
928 theme->menu_text_disabled_selected_shadow_alpha = 50;
932 theme->a_menu_text_normal->texture[0].data.text.shadow_color =
933 theme->menu_text_normal_shadow_color;
934 theme->a_menu_text_normal->texture[0].data.text.shadow_alpha =
935 theme->menu_text_normal_shadow_alpha;
936 theme->a_menu_text_selected->texture[0].data.text.shadow_color =
937 theme->menu_text_selected_shadow_color;
938 theme->a_menu_text_selected->texture[0].data.text.shadow_alpha =
939 theme->menu_text_selected_shadow_alpha;
940 theme->a_menu_text_disabled->texture[0].data.text.shadow_color =
941 theme->menu_text_disabled_shadow_color;
942 theme->a_menu_text_disabled->texture[0].data.text.shadow_alpha =
943 theme->menu_text_disabled_shadow_alpha;
944 theme->a_menu_text_disabled_selected->texture[0].data.text.shadow_color =
945 theme->menu_text_disabled_shadow_color;
946 theme->a_menu_text_disabled_selected->texture[0].data.text.shadow_alpha =
947 theme->menu_text_disabled_shadow_alpha;
949 theme->btn_max->a_focused_disabled->texture[0].type =
950 theme->btn_max->a_unfocused_disabled->texture[0].type =
951 theme->btn_max->a_focused_hover->texture[0].type =
952 theme->btn_max->a_unfocused_hover->texture[0].type =
953 theme->btn_max->a_focused_hover_toggled->texture[0].type =
954 theme->btn_max->a_unfocused_hover_toggled->texture[0].type =
955 theme->btn_max->a_focused_unpressed_toggled->texture[0].type =
956 theme->btn_max->a_unfocused_unpressed_toggled->texture[0].type =
957 theme->btn_max->a_focused_pressed_toggled->texture[0].type =
958 theme->btn_max->a_unfocused_pressed_toggled->texture[0].type =
959 theme->btn_max->a_focused_unpressed->texture[0].type =
960 theme->btn_max->a_focused_pressed->texture[0].type =
961 theme->btn_max->a_unfocused_unpressed->texture[0].type =
962 theme->btn_max->a_unfocused_pressed->texture[0].type =
963 theme->btn_close->a_focused_disabled->texture[0].type =
964 theme->btn_close->a_unfocused_disabled->texture[0].type =
965 theme->btn_close->a_focused_hover->texture[0].type =
966 theme->btn_close->a_unfocused_hover->texture[0].type =
967 theme->btn_close->a_focused_unpressed->texture[0].type =
968 theme->btn_close->a_focused_pressed->texture[0].type =
969 theme->btn_close->a_unfocused_unpressed->texture[0].type =
970 theme->btn_close->a_unfocused_pressed->texture[0].type =
971 theme->btn_desk->a_focused_disabled->texture[0].type =
972 theme->btn_desk->a_unfocused_disabled->texture[0].type =
973 theme->btn_desk->a_focused_hover->texture[0].type =
974 theme->btn_desk->a_unfocused_hover->texture[0].type =
975 theme->btn_desk->a_focused_hover_toggled->texture[0].type =
976 theme->btn_desk->a_unfocused_hover_toggled->texture[0].type =
977 theme->btn_desk->a_focused_unpressed_toggled->texture[0].type =
978 theme->btn_desk->a_unfocused_unpressed_toggled->texture[0].type =
979 theme->btn_desk->a_focused_pressed_toggled->texture[0].type =
980 theme->btn_desk->a_unfocused_pressed_toggled->texture[0].type =
981 theme->btn_desk->a_focused_unpressed->texture[0].type =
982 theme->btn_desk->a_focused_pressed->texture[0].type =
983 theme->btn_desk->a_unfocused_unpressed->texture[0].type =
984 theme->btn_desk->a_unfocused_pressed->texture[0].type =
985 theme->btn_shade->a_focused_disabled->texture[0].type =
986 theme->btn_shade->a_unfocused_disabled->texture[0].type =
987 theme->btn_shade->a_focused_hover->texture[0].type =
988 theme->btn_shade->a_unfocused_hover->texture[0].type =
989 theme->btn_shade->a_focused_hover_toggled->texture[0].type =
990 theme->btn_shade->a_unfocused_hover_toggled->texture[0].type =
991 theme->btn_shade->a_focused_unpressed_toggled->texture[0].type =
992 theme->btn_shade->a_unfocused_unpressed_toggled->texture[0].type =
993 theme->btn_shade->a_focused_pressed_toggled->texture[0].type =
994 theme->btn_shade->a_unfocused_pressed_toggled->texture[0].type =
995 theme->btn_shade->a_focused_unpressed->texture[0].type =
996 theme->btn_shade->a_focused_pressed->texture[0].type =
997 theme->btn_shade->a_unfocused_unpressed->texture[0].type =
998 theme->btn_shade->a_unfocused_pressed->texture[0].type =
999 theme->btn_iconify->a_focused_disabled->texture[0].type =
1000 theme->btn_iconify->a_unfocused_disabled->texture[0].type =
1001 theme->btn_iconify->a_focused_hover->texture[0].type =
1002 theme->btn_iconify->a_unfocused_hover->texture[0].type =
1003 theme->btn_iconify->a_focused_unpressed->texture[0].type =
1004 theme->btn_iconify->a_focused_pressed->texture[0].type =
1005 theme->btn_iconify->a_unfocused_unpressed->texture[0].type =
1006 theme->btn_iconify->a_unfocused_pressed->texture[0].type =
1007 theme->a_menu_bullet_normal->texture[0].type =
1008 theme->a_menu_bullet_selected->texture[0].type = RR_TEXTURE_MASK;
1010 theme->btn_max->a_focused_disabled->texture[0].data.mask.mask =
1011 theme->btn_max->a_unfocused_disabled->texture[0].data.mask.mask =
1012 theme->btn_max->disabled_mask;
1013 theme->btn_max->a_focused_hover->texture[0].data.mask.mask =
1014 theme->btn_max->a_unfocused_hover->texture[0].data.mask.mask =
1015 theme->btn_max->hover_mask;
1016 theme->btn_max->a_focused_pressed->texture[0].data.mask.mask =
1017 theme->btn_max->a_unfocused_pressed->texture[0].data.mask.mask =
1018 theme->btn_max->pressed_mask;
1019 theme->btn_max->a_focused_unpressed->texture[0].data.mask.mask =
1020 theme->btn_max->a_unfocused_unpressed->texture[0].data.mask.mask =
1021 theme->btn_max->mask;
1022 theme->btn_max->a_focused_hover_toggled->texture[0].data.mask.mask =
1023 theme->btn_max->a_unfocused_hover_toggled->texture[0].data.mask.mask =
1024 theme->btn_max->hover_toggled_mask;
1025 theme->btn_max->a_focused_unpressed_toggled->texture[0].data.mask.mask =
1026 theme->btn_max->a_unfocused_unpressed_toggled->
1027 texture[0].data.mask.mask = theme->btn_max->toggled_mask;
1028 theme->btn_max->a_focused_pressed_toggled->texture[0].data.mask.mask =
1029 theme->btn_max->a_unfocused_pressed_toggled->texture[0].data.mask.mask
1030 = theme->btn_max->pressed_toggled_mask;
1031 theme->btn_close->a_focused_disabled->texture[0].data.mask.mask =
1032 theme->btn_close->a_unfocused_disabled->texture[0].data.mask.mask =
1033 theme->btn_close->disabled_mask;
1034 theme->btn_close->a_focused_hover->texture[0].data.mask.mask =
1035 theme->btn_close->a_unfocused_hover->texture[0].data.mask.mask =
1036 theme->btn_close->hover_mask;
1037 theme->btn_close->a_focused_pressed->texture[0].data.mask.mask =
1038 theme->btn_close->a_unfocused_pressed->texture[0].data.mask.mask =
1039 theme->btn_close->pressed_mask;
1040 theme->btn_close->a_focused_unpressed->texture[0].data.mask.mask =
1041 theme->btn_close->a_unfocused_unpressed->texture[0].data.mask.mask =
1042 theme->btn_close->mask;
1043 theme->btn_desk->a_focused_disabled->texture[0].data.mask.mask =
1044 theme->btn_desk->a_unfocused_disabled->texture[0].data.mask.mask =
1045 theme->btn_desk->disabled_mask;
1046 theme->btn_desk->a_focused_hover->texture[0].data.mask.mask =
1047 theme->btn_desk->a_unfocused_hover->texture[0].data.mask.mask =
1048 theme->btn_desk->hover_mask;
1049 theme->btn_desk->a_focused_pressed->texture[0].data.mask.mask =
1050 theme->btn_desk->a_unfocused_pressed->texture[0].data.mask.mask =
1051 theme->btn_desk->pressed_mask;
1052 theme->btn_desk->a_focused_unpressed->texture[0].data.mask.mask =
1053 theme->btn_desk->a_unfocused_unpressed->texture[0].data.mask.mask =
1054 theme->btn_desk->mask;
1055 theme->btn_desk->a_focused_hover_toggled->texture[0].data.mask.mask =
1056 theme->btn_desk->a_unfocused_hover_toggled->texture[0].data.mask.mask =
1057 theme->btn_desk->hover_toggled_mask;
1058 theme->btn_desk->a_focused_unpressed_toggled->texture[0].data.mask.mask =
1059 theme->btn_desk->a_unfocused_unpressed_toggled->
1060 texture[0].data.mask.mask = theme->btn_desk->toggled_mask;
1061 theme->btn_desk->a_focused_pressed_toggled->texture[0].data.mask.mask =
1062 theme->btn_desk->a_unfocused_pressed_toggled->texture[0].data.mask.mask
1063 = theme->btn_desk->pressed_toggled_mask;
1064 theme->btn_shade->a_focused_disabled->texture[0].data.mask.mask =
1065 theme->btn_shade->a_unfocused_disabled->texture[0].data.mask.mask =
1066 theme->btn_shade->disabled_mask;
1067 theme->btn_shade->a_focused_hover->texture[0].data.mask.mask =
1068 theme->btn_shade->a_unfocused_hover->texture[0].data.mask.mask =
1069 theme->btn_shade->hover_mask;
1070 theme->btn_shade->a_focused_pressed->texture[0].data.mask.mask =
1071 theme->btn_shade->a_unfocused_pressed->texture[0].data.mask.mask =
1072 theme->btn_shade->pressed_mask;
1073 theme->btn_shade->a_focused_unpressed->texture[0].data.mask.mask =
1074 theme->btn_shade->a_unfocused_unpressed->texture[0].data.mask.mask =
1075 theme->btn_shade->mask;
1076 theme->btn_shade->a_focused_hover_toggled->texture[0].data.mask.mask =
1077 theme->btn_shade->a_unfocused_hover_toggled->texture[0].data.mask.mask
1078 = theme->btn_shade->hover_toggled_mask;
1079 theme->btn_shade->a_focused_unpressed_toggled->texture[0].data.mask.mask =
1080 theme->btn_shade->a_unfocused_unpressed_toggled->
1081 texture[0].data.mask.mask = theme->btn_shade->toggled_mask;
1082 theme->btn_shade->a_focused_pressed_toggled->texture[0].data.mask.mask =
1083 theme->btn_shade->a_unfocused_pressed_toggled->
1084 texture[0].data.mask.mask = theme->btn_shade->pressed_toggled_mask;
1085 theme->btn_iconify->a_focused_disabled->texture[0].data.mask.mask =
1086 theme->btn_iconify->a_unfocused_disabled->texture[0].data.mask.mask =
1087 theme->btn_iconify->disabled_mask;
1088 theme->btn_iconify->a_focused_hover->texture[0].data.mask.mask =
1089 theme->btn_iconify->a_unfocused_hover->texture[0].data.mask.mask =
1090 theme->btn_iconify->hover_mask;
1091 theme->btn_iconify->a_focused_pressed->texture[0].data.mask.mask =
1092 theme->btn_iconify->a_unfocused_pressed->texture[0].data.mask.mask =
1093 theme->btn_iconify->pressed_mask;
1094 theme->btn_iconify->a_focused_unpressed->texture[0].data.mask.mask =
1095 theme->btn_iconify->a_unfocused_unpressed->texture[0].data.mask.mask =
1096 theme->btn_iconify->mask;
1097 theme->a_menu_bullet_normal->texture[0].data.mask.mask =
1098 theme->a_menu_bullet_selected->texture[0].data.mask.mask =
1099 theme->menu_bullet_mask;
1100 theme->btn_max->a_focused_disabled->texture[0].data.mask.color =
1101 theme->btn_max->focused_disabled_color;
1102 theme->btn_close->a_focused_disabled->texture[0].data.mask.color =
1103 theme->btn_close->focused_disabled_color;
1104 theme->btn_desk->a_focused_disabled->texture[0].data.mask.color =
1105 theme->btn_desk->focused_disabled_color;
1106 theme->btn_shade->a_focused_disabled->texture[0].data.mask.color =
1107 theme->btn_shade->focused_disabled_color;
1108 theme->btn_iconify->a_focused_disabled->texture[0].data.mask.color =
1109 theme->btn_iconify->focused_disabled_color;
1110 theme->btn_max->a_unfocused_disabled->texture[0].data.mask.color =
1111 theme->btn_max->unfocused_disabled_color;
1112 theme->btn_close->a_unfocused_disabled->texture[0].data.mask.color =
1113 theme->btn_close->unfocused_disabled_color;
1114 theme->btn_desk->a_unfocused_disabled->texture[0].data.mask.color =
1115 theme->btn_desk->unfocused_disabled_color;
1116 theme->btn_shade->a_unfocused_disabled->texture[0].data.mask.color =
1117 theme->btn_shade->unfocused_disabled_color;
1118 theme->btn_iconify->a_unfocused_disabled->texture[0].data.mask.color =
1119 theme->btn_iconify->unfocused_disabled_color;
1120 theme->btn_max->a_focused_hover->texture[0].data.mask.color =
1121 theme->btn_max->focused_hover_color;
1122 theme->btn_close->a_focused_hover->texture[0].data.mask.color =
1123 theme->btn_close->focused_hover_color;
1124 theme->btn_desk->a_focused_hover->texture[0].data.mask.color =
1125 theme->btn_desk->focused_hover_color;
1126 theme->btn_shade->a_focused_hover->texture[0].data.mask.color =
1127 theme->btn_shade->focused_hover_color;
1128 theme->btn_iconify->a_focused_hover->texture[0].data.mask.color =
1129 theme->btn_iconify->focused_hover_color;
1130 theme->btn_max->a_unfocused_hover->texture[0].data.mask.color =
1131 theme->btn_max->unfocused_hover_color;
1132 theme->btn_close->a_unfocused_hover->texture[0].data.mask.color =
1133 theme->btn_close->unfocused_hover_color;
1134 theme->btn_desk->a_unfocused_hover->texture[0].data.mask.color =
1135 theme->btn_desk->unfocused_hover_color;
1136 theme->btn_shade->a_unfocused_hover->texture[0].data.mask.color =
1137 theme->btn_shade->unfocused_hover_color;
1138 theme->btn_iconify->a_unfocused_hover->texture[0].data.mask.color =
1139 theme->btn_iconify->unfocused_hover_color;
1140 theme->btn_max->a_focused_hover_toggled->texture[0].data.mask.color =
1141 theme->btn_max->focused_hover_toggled_color;
1142 theme->btn_desk->a_focused_hover_toggled->texture[0].data.mask.color =
1143 theme->btn_desk->focused_hover_toggled_color;
1144 theme->btn_shade->a_focused_hover_toggled->texture[0].data.mask.color =
1145 theme->btn_shade->focused_hover_toggled_color;
1146 theme->btn_max->a_unfocused_hover_toggled->texture[0].data.mask.color =
1147 theme->btn_max->unfocused_hover_toggled_color;
1148 theme->btn_desk->a_unfocused_hover_toggled->texture[0].data.mask.color =
1149 theme->btn_desk->unfocused_hover_toggled_color;
1150 theme->btn_shade->a_unfocused_hover_toggled->texture[0].data.mask.color =
1151 theme->btn_shade->unfocused_hover_toggled_color;
1152 theme->btn_max->a_focused_unpressed_toggled->texture[0].data.mask.color =
1153 theme->btn_max->focused_unpressed_toggled_color;
1154 theme->btn_desk->a_focused_unpressed_toggled->texture[0].data.mask.color =
1155 theme->btn_desk->focused_unpressed_toggled_color;
1156 theme->btn_shade->a_focused_unpressed_toggled->texture[0].data.mask.color =
1157 theme->btn_shade->focused_unpressed_toggled_color;
1158 theme->btn_max->a_unfocused_unpressed_toggled->texture[0].data.mask.color =
1159 theme->btn_max->unfocused_unpressed_toggled_color;
1160 theme->btn_desk->a_unfocused_unpressed_toggled->texture[0].data.mask.color
1161 = theme->btn_desk->unfocused_unpressed_toggled_color;
1162 theme->btn_shade->a_unfocused_unpressed_toggled->texture[0].data.mask.color
1163 = theme->btn_shade->unfocused_unpressed_toggled_color;
1164 theme->btn_max->a_focused_pressed_toggled->texture[0].data.mask.color =
1165 theme->btn_max->focused_pressed_toggled_color;
1166 theme->btn_desk->a_focused_pressed_toggled->texture[0].data.mask.color =
1167 theme->btn_desk->focused_pressed_toggled_color;
1168 theme->btn_shade->a_focused_pressed_toggled->texture[0].data.mask.color =
1169 theme->btn_shade->focused_pressed_toggled_color;
1170 theme->btn_max->a_unfocused_pressed_toggled->texture[0].data.mask.color =
1171 theme->btn_max->unfocused_pressed_toggled_color;
1172 theme->btn_desk->a_unfocused_pressed_toggled->texture[0].data.mask.color =
1173 theme->btn_desk->unfocused_pressed_toggled_color;
1174 theme->btn_shade->a_unfocused_pressed_toggled->texture[0].data.mask.color =
1175 theme->btn_shade->unfocused_pressed_toggled_color;
1176 theme->btn_max->a_focused_unpressed->texture[0].data.mask.color =
1177 theme->btn_max->focused_unpressed_color;
1178 theme->btn_close->a_focused_unpressed->texture[0].data.mask.color =
1179 theme->btn_close->focused_unpressed_color;
1180 theme->btn_desk->a_focused_unpressed->texture[0].data.mask.color =
1181 theme->btn_desk->focused_unpressed_color;
1182 theme->btn_shade->a_focused_unpressed->texture[0].data.mask.color =
1183 theme->btn_shade->focused_unpressed_color;
1184 theme->btn_iconify->a_focused_unpressed->texture[0].data.mask.color =
1185 theme->btn_iconify->focused_unpressed_color;
1186 theme->btn_max->a_focused_pressed->texture[0].data.mask.color =
1187 theme->btn_max->focused_pressed_color;
1188 theme->btn_close->a_focused_pressed->texture[0].data.mask.color =
1189 theme->btn_close->focused_pressed_color;
1190 theme->btn_desk->a_focused_pressed->texture[0].data.mask.color =
1191 theme->btn_desk->focused_pressed_color;
1192 theme->btn_shade->a_focused_pressed->texture[0].data.mask.color =
1193 theme->btn_shade->focused_pressed_color;
1194 theme->btn_iconify->a_focused_pressed->texture[0].data.mask.color =
1195 theme->btn_iconify->focused_pressed_color;
1196 theme->btn_max->a_unfocused_unpressed->texture[0].data.mask.color =
1197 theme->btn_max->unfocused_unpressed_color;
1198 theme->btn_close->a_unfocused_unpressed->texture[0].data.mask.color =
1199 theme->btn_close->unfocused_unpressed_color;
1200 theme->btn_desk->a_unfocused_unpressed->texture[0].data.mask.color =
1201 theme->btn_desk->unfocused_unpressed_color;
1202 theme->btn_shade->a_unfocused_unpressed->texture[0].data.mask.color =
1203 theme->btn_shade->unfocused_unpressed_color;
1204 theme->btn_iconify->a_unfocused_unpressed->texture[0].data.mask.color =
1205 theme->btn_iconify->unfocused_unpressed_color;
1206 theme->btn_max->a_unfocused_pressed->texture[0].data.mask.color =
1207 theme->btn_max->unfocused_pressed_color;
1208 theme->btn_close->a_unfocused_pressed->texture[0].data.mask.color =
1209 theme->btn_close->unfocused_pressed_color;
1210 theme->btn_desk->a_unfocused_pressed->texture[0].data.mask.color =
1211 theme->btn_desk->unfocused_pressed_color;
1212 theme->btn_shade->a_unfocused_pressed->texture[0].data.mask.color =
1213 theme->btn_shade->unfocused_pressed_color;
1214 theme->btn_iconify->a_unfocused_pressed->texture[0].data.mask.color =
1215 theme->btn_iconify->unfocused_pressed_color;
1216 theme->a_menu_bullet_normal->texture[0].data.mask.color =
1217 theme->menu_bullet_color;
1218 theme->a_menu_bullet_selected->texture[0].data.mask.color =
1219 theme->menu_bullet_selected_color;
1222 XrmDestroyDatabase(db);
1224 /* set the font heights */
1225 theme->win_font_height = RrFontHeight(theme->win_font_focused,
1226 theme->a_focused_label->texture[0].data.text.shadow_offset_y);
1227 theme->win_font_height =
1228 MAX(theme->win_font_height,
1229 RrFontHeight(theme->win_font_focused,
1230 theme->a_unfocused_label->texture[0].data.text.shadow_offset_y));
1231 theme->menu_title_font_height = RrFontHeight(theme->menu_title_font,
1232 theme->a_menu_text_title->texture[0].data.text.shadow_offset_y);
1233 theme->menu_font_height = RrFontHeight(theme->menu_font,
1234 theme->a_menu_text_normal->texture[0].data.text.shadow_offset_y);
1236 /* calculate some last extents */
1238 gint ft, fb, fl, fr, ut, ub, ul, ur;
1240 RrMargins(theme->a_focused_label, &fl, &ft, &fr, &fb);
1241 RrMargins(theme->a_unfocused_label, &ul, &ut, &ur, &ub);
1242 theme->label_height = theme->win_font_height + MAX(ft + fb, ut + ub);
1243 theme->label_height += theme->label_height % 2;
1245 /* this would be nice I think, since padding.width can now be 0,
1246 but it breaks frame.c horribly and I don't feel like fixing that
1247 right now, so if anyone complains, here is how to keep text from
1248 going over the title's bevel/border with a padding.width of 0 and a
1249 bevelless/borderless label
1250 RrMargins(theme->a_focused_title, &fl, &ft, &fr, &fb);
1251 RrMargins(theme->a_unfocused_title, &ul, &ut, &ur, &ub);
1252 theme->title_height = theme->label_height +
1253 MAX(MAX(theme->padding * 2, ft + fb),
1254 MAX(theme->padding * 2, ut + ub));
1256 theme->title_height = theme->label_height + theme->paddingy * 2;
1258 RrMargins(theme->a_menu_title, &ul, &ut, &ur, &ub);
1259 theme->menu_title_label_height = theme->menu_title_font_height+ut+ub;
1260 theme->menu_title_height = theme->menu_title_label_height +
1261 theme->paddingy * 2;
1263 theme->button_size = theme->label_height - 2;
1264 theme->grip_width = 25;
1266 RrAppearanceFree(fbs.focused_disabled);
1267 RrAppearanceFree(fbs.unfocused_disabled);
1268 RrAppearanceFree(fbs.focused_hover);
1269 RrAppearanceFree(fbs.unfocused_hover);
1270 RrAppearanceFree(fbs.focused_unpressed);
1271 RrAppearanceFree(fbs.focused_pressed);
1272 RrAppearanceFree(fbs.unfocused_unpressed);
1273 RrAppearanceFree(fbs.unfocused_pressed);
1274 RrAppearanceFree(fbs.focused_hover_toggled);
1275 RrAppearanceFree(fbs.unfocused_hover_toggled);
1276 RrAppearanceFree(fbs.focused_unpressed_toggled);
1277 RrAppearanceFree(fbs.focused_pressed_toggled);
1278 RrAppearanceFree(fbs.unfocused_unpressed_toggled);
1279 RrAppearanceFree(fbs.unfocused_pressed_toggled);
1284 void RrThemeFree(RrTheme *theme)
1287 g_free(theme->name);
1289 RrButtonFree(theme->btn_max);
1290 RrButtonFree(theme->btn_close);
1291 RrButtonFree(theme->btn_desk);
1292 RrButtonFree(theme->btn_shade);
1293 RrButtonFree(theme->btn_iconify);
1295 RrColorFree(theme->menu_border_color);
1296 RrColorFree(theme->osd_border_color);
1297 RrColorFree(theme->frame_focused_border_color);
1298 RrColorFree(theme->frame_undecorated_focused_border_color);
1299 RrColorFree(theme->frame_unfocused_border_color);
1300 RrColorFree(theme->frame_undecorated_unfocused_border_color);
1301 RrColorFree(theme->title_separator_focused_color);
1302 RrColorFree(theme->title_separator_unfocused_color);
1303 RrColorFree(theme->cb_unfocused_color);
1304 RrColorFree(theme->cb_focused_color);
1305 RrColorFree(theme->title_focused_color);
1306 RrColorFree(theme->title_unfocused_color);
1307 RrColorFree(theme->titlebut_focused_disabled_color);
1308 RrColorFree(theme->titlebut_unfocused_disabled_color);
1309 RrColorFree(theme->titlebut_focused_hover_color);
1310 RrColorFree(theme->titlebut_unfocused_hover_color);
1311 RrColorFree(theme->titlebut_focused_hover_toggled_color);
1312 RrColorFree(theme->titlebut_unfocused_hover_toggled_color);
1313 RrColorFree(theme->titlebut_focused_pressed_toggled_color);
1314 RrColorFree(theme->titlebut_unfocused_pressed_toggled_color);
1315 RrColorFree(theme->titlebut_focused_unpressed_toggled_color);
1316 RrColorFree(theme->titlebut_unfocused_unpressed_toggled_color);
1317 RrColorFree(theme->titlebut_focused_pressed_color);
1318 RrColorFree(theme->titlebut_unfocused_pressed_color);
1319 RrColorFree(theme->titlebut_focused_unpressed_color);
1320 RrColorFree(theme->titlebut_unfocused_unpressed_color);
1321 RrColorFree(theme->menu_title_color);
1322 RrColorFree(theme->menu_sep_color);
1323 RrColorFree(theme->menu_color);
1324 RrColorFree(theme->menu_bullet_color);
1325 RrColorFree(theme->menu_bullet_selected_color);
1326 RrColorFree(theme->menu_selected_color);
1327 RrColorFree(theme->menu_disabled_color);
1328 RrColorFree(theme->menu_disabled_selected_color);
1329 RrColorFree(theme->title_focused_shadow_color);
1330 RrColorFree(theme->title_unfocused_shadow_color);
1331 RrColorFree(theme->osd_text_active_color);
1332 RrColorFree(theme->osd_text_inactive_color);
1333 RrColorFree(theme->osd_text_active_shadow_color);
1334 RrColorFree(theme->osd_text_inactive_shadow_color);
1335 RrColorFree(theme->osd_pressed_color);
1336 RrColorFree(theme->osd_unpressed_color);
1337 RrColorFree(theme->osd_focused_color);
1338 RrColorFree(theme->osd_pressed_lineart);
1339 RrColorFree(theme->osd_focused_lineart);
1340 RrColorFree(theme->menu_title_shadow_color);
1341 RrColorFree(theme->menu_text_normal_shadow_color);
1342 RrColorFree(theme->menu_text_selected_shadow_color);
1343 RrColorFree(theme->menu_text_disabled_shadow_color);
1344 RrColorFree(theme->menu_text_disabled_selected_shadow_color);
1346 g_free(theme->def_win_icon);
1348 RrPixmapMaskFree(theme->menu_bullet_mask);
1349 RrPixmapMaskFree(theme->down_arrow_mask);
1350 RrPixmapMaskFree(theme->up_arrow_mask);
1352 RrFontClose(theme->win_font_focused);
1353 RrFontClose(theme->win_font_unfocused);
1354 RrFontClose(theme->menu_title_font);
1355 RrFontClose(theme->menu_font);
1356 RrFontClose(theme->osd_font_hilite);
1357 RrFontClose(theme->osd_font_unhilite);
1359 RrAppearanceFree(theme->a_focused_grip);
1360 RrAppearanceFree(theme->a_unfocused_grip);
1361 RrAppearanceFree(theme->a_focused_title);
1362 RrAppearanceFree(theme->a_unfocused_title);
1363 RrAppearanceFree(theme->a_focused_label);
1364 RrAppearanceFree(theme->a_unfocused_label);
1365 RrAppearanceFree(theme->a_icon);
1366 RrAppearanceFree(theme->a_focused_handle);
1367 RrAppearanceFree(theme->a_unfocused_handle);
1368 RrAppearanceFree(theme->a_menu);
1369 RrAppearanceFree(theme->a_menu_title);
1370 RrAppearanceFree(theme->a_menu_text_title);
1371 RrAppearanceFree(theme->a_menu_normal);
1372 RrAppearanceFree(theme->a_menu_selected);
1373 RrAppearanceFree(theme->a_menu_disabled);
1374 RrAppearanceFree(theme->a_menu_disabled_selected);
1375 RrAppearanceFree(theme->a_menu_text_normal);
1376 RrAppearanceFree(theme->a_menu_text_selected);
1377 RrAppearanceFree(theme->a_menu_text_disabled);
1378 RrAppearanceFree(theme->a_menu_text_disabled_selected);
1379 RrAppearanceFree(theme->a_menu_bullet_normal);
1380 RrAppearanceFree(theme->a_menu_bullet_selected);
1381 RrAppearanceFree(theme->a_clear);
1382 RrAppearanceFree(theme->a_clear_tex);
1383 RrAppearanceFree(theme->osd_bg);
1384 RrAppearanceFree(theme->osd_hilite_bg);
1385 RrAppearanceFree(theme->osd_hilite_label);
1386 RrAppearanceFree(theme->osd_unhilite_bg);
1387 RrAppearanceFree(theme->osd_unhilite_label);
1388 RrAppearanceFree(theme->osd_pressed_button);
1389 RrAppearanceFree(theme->osd_unpressed_button);
1390 RrAppearanceFree(theme->osd_focused_button);
1392 g_slice_free(RrTheme, theme);
1396 static XrmDatabase loaddb(const gchar *name, gchar **path)
1399 XrmDatabase db = NULL;
1402 if (name[0] == '/') {
1403 s = g_build_filename(name, "openbox-3", "themerc", NULL);
1404 if ((db = XrmGetFileDatabase(s)))
1405 *path = g_path_get_dirname(s);
1410 p = obt_paths_new();
1412 /* XXX backwards compatibility, remove me sometime later */
1413 s = g_build_filename(g_get_home_dir(), ".themes", name,
1414 "openbox-3", "themerc", NULL);
1415 if ((db = XrmGetFileDatabase(s)))
1416 *path = g_path_get_dirname(s);
1419 for (it = obt_paths_data_dirs(p); !db && it; it = g_slist_next(it))
1421 s = g_build_filename(it->data, "themes", name,
1422 "openbox-3", "themerc", NULL);
1423 if ((db = XrmGetFileDatabase(s)))
1424 *path = g_path_get_dirname(s);
1432 s = g_build_filename(name, "themerc", NULL);
1433 if ((db = XrmGetFileDatabase(s)))
1434 *path = g_path_get_dirname(s);
1441 static gchar *create_class_name(const gchar *rname)
1443 gchar *rclass = g_strdup(rname);
1448 p = strchr(p+1, '.');
1449 if (p == NULL) break;
1451 if (*p == '\0') break;
1456 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value)
1458 gboolean ret = FALSE;
1459 gchar *rclass = create_class_name(rname);
1460 gchar *rettype, *end;
1463 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1464 retvalue.addr != NULL) {
1465 *value = (gint)strtol(retvalue.addr, &end, 10);
1466 if (end != retvalue.addr)
1474 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)
1476 gboolean ret = FALSE;
1477 gchar *rclass = create_class_name(rname);
1481 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1482 retvalue.addr != NULL) {
1483 g_strstrip(retvalue.addr);
1484 *value = retvalue.addr;
1492 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
1493 const gchar *rname, RrColor **value)
1495 gboolean ret = FALSE;
1496 gchar *rclass = create_class_name(rname);
1500 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1501 retvalue.addr != NULL) {
1504 /* retvalue.addr is inside the xrdb database so we can't destroy it
1505 but we can edit it in place, as g_strstrip does. */
1506 g_strstrip(retvalue.addr);
1507 c = RrColorParse(inst, retvalue.addr);
1518 static gboolean read_mask(const RrInstance *inst, const gchar *path,
1519 const gchar *maskname, RrPixmapMask **value)
1521 gboolean ret = FALSE;
1523 gint hx, hy; /* ignored */
1527 s = g_build_filename(path, maskname, NULL);
1528 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) {
1530 *value = RrPixmapMaskNew(inst, w, h, (gchar*)b);
1538 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
1539 RrReliefType *relief, RrBevelType *bevel,
1540 gboolean *interlaced, gboolean *border,
1541 gboolean allow_trans)
1545 /* convert to all lowercase */
1546 for (t = tex; *t != '\0'; ++t)
1547 *t = g_ascii_tolower(*t);
1549 if (allow_trans && strstr(tex, "parentrelative") != NULL) {
1550 *grad = RR_SURFACE_PARENTREL;
1552 if (strstr(tex, "gradient") != NULL) {
1553 if (strstr(tex, "crossdiagonal") != NULL)
1554 *grad = RR_SURFACE_CROSS_DIAGONAL;
1555 else if (strstr(tex, "pyramid") != NULL)
1556 *grad = RR_SURFACE_PYRAMID;
1557 else if (strstr(tex, "mirrorhorizontal") != NULL)
1558 *grad = RR_SURFACE_MIRROR_HORIZONTAL;
1559 else if (strstr(tex, "horizontal") != NULL)
1560 *grad = RR_SURFACE_HORIZONTAL;
1561 else if (strstr(tex, "splitvertical") != NULL)
1562 *grad = RR_SURFACE_SPLIT_VERTICAL;
1563 else if (strstr(tex, "vertical") != NULL)
1564 *grad = RR_SURFACE_VERTICAL;
1566 *grad = RR_SURFACE_DIAGONAL;
1568 *grad = RR_SURFACE_SOLID;
1572 if (strstr(tex, "sunken") != NULL)
1573 *relief = RR_RELIEF_SUNKEN;
1574 else if (strstr(tex, "flat") != NULL)
1575 *relief = RR_RELIEF_FLAT;
1576 else if (strstr(tex, "raised") != NULL)
1577 *relief = RR_RELIEF_RAISED;
1579 *relief = (*grad == RR_SURFACE_PARENTREL) ?
1580 RR_RELIEF_FLAT : RR_RELIEF_RAISED;
1583 if (*relief == RR_RELIEF_FLAT) {
1584 if (strstr(tex, "border") != NULL)
1587 if (strstr(tex, "bevel2") != NULL)
1588 *bevel = RR_BEVEL_2;
1590 *bevel = RR_BEVEL_1;
1593 if (strstr(tex, "interlaced") != NULL)
1596 *interlaced = FALSE;
1599 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
1600 const gchar *rname, RrAppearance *value,
1601 gboolean allow_trans)
1603 gboolean ret = FALSE;
1604 gchar *rclass = create_class_name(rname);
1605 gchar *cname, *ctoname, *bcname, *icname, *hname, *sname;
1606 gchar *csplitname, *ctosplitname;
1611 cname = g_strconcat(rname, ".color", NULL);
1612 ctoname = g_strconcat(rname, ".colorTo", NULL);
1613 bcname = g_strconcat(rname, ".border.color", NULL);
1614 icname = g_strconcat(rname, ".interlace.color", NULL);
1615 hname = g_strconcat(rname, ".highlight", NULL);
1616 sname = g_strconcat(rname, ".shadow", NULL);
1617 csplitname = g_strconcat(rname, ".color.splitTo", NULL);
1618 ctosplitname = g_strconcat(rname, ".colorTo.splitTo", NULL);
1620 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1621 retvalue.addr != NULL) {
1622 parse_appearance(retvalue.addr,
1623 &value->surface.grad,
1624 &value->surface.relief,
1625 &value->surface.bevel,
1626 &value->surface.interlaced,
1627 &value->surface.border,
1629 if (!read_color(db, inst, cname, &value->surface.primary))
1630 value->surface.primary = RrColorNew(inst, 0, 0, 0);
1631 if (!read_color(db, inst, ctoname, &value->surface.secondary))
1632 value->surface.secondary = RrColorNew(inst, 0, 0, 0);
1633 if (value->surface.border)
1634 if (!read_color(db, inst, bcname,
1635 &value->surface.border_color))
1636 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
1637 if (value->surface.interlaced)
1638 if (!read_color(db, inst, icname,
1639 &value->surface.interlace_color))
1640 value->surface.interlace_color = RrColorNew(inst, 0, 0, 0);
1641 if (read_int(db, hname, &i) && i >= 0)
1642 value->surface.bevel_light_adjust = i;
1643 if (read_int(db, sname, &i) && i >= 0 && i <= 256)
1644 value->surface.bevel_dark_adjust = i;
1646 if (value->surface.grad == RR_SURFACE_SPLIT_VERTICAL) {
1649 if (!read_color(db, inst, csplitname,
1650 &value->surface.split_primary))
1652 r = value->surface.primary->r;
1654 g = value->surface.primary->g;
1656 b = value->surface.primary->b;
1658 if (r > 0xFF) r = 0xFF;
1659 if (g > 0xFF) g = 0xFF;
1660 if (b > 0xFF) b = 0xFF;
1661 value->surface.split_primary = RrColorNew(inst, r, g, b);
1664 if (!read_color(db, inst, ctosplitname,
1665 &value->surface.split_secondary))
1667 r = value->surface.secondary->r;
1669 g = value->surface.secondary->g;
1671 b = value->surface.secondary->b;
1673 if (r > 0xFF) r = 0xFF;
1674 if (g > 0xFF) g = 0xFF;
1675 if (b > 0xFF) b = 0xFF;
1676 value->surface.split_secondary = RrColorNew(inst, r, g, b);
1683 g_free(ctosplitname);
1695 static int parse_inline_number(const char *p)
1703 for (; isdigit(*p); ++p)
1704 res = res * 10 + *p - '0';
1709 static void set_default_appearance(RrAppearance *a)
1711 a->surface.grad = RR_SURFACE_SOLID;
1712 a->surface.relief = RR_RELIEF_FLAT;
1713 a->surface.bevel = RR_BEVEL_1;
1714 a->surface.interlaced = FALSE;
1715 a->surface.border = FALSE;
1716 a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
1717 a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
1720 /* Reads the output from gimp's C-Source file format into valid RGBA data for
1721 an RrTextureRGBA. */
1722 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data)
1727 p = im = g_memdup(data, width * height * sizeof(RrPixel32));
1729 for (i = 0; i < width * height; ++i) {
1730 guchar a = ((*p >> 24) & 0xff);
1731 guchar b = ((*p >> 16) & 0xff);
1732 guchar g = ((*p >> 8) & 0xff);
1733 guchar r = ((*p >> 0) & 0xff);
1735 *p = ((r << RrDefaultRedOffset) +
1736 (g << RrDefaultGreenOffset) +
1737 (b << RrDefaultBlueOffset) +
1738 (a << RrDefaultAlphaOffset));
1745 static void read_button_styles(XrmDatabase db, const RrInstance *inst,
1747 const RrTheme *theme, RrButton *btn,
1748 const gchar *btnname,
1749 struct fallbacks *fbs,
1750 guchar *normal_mask,
1751 guchar *toggled_mask)
1753 gchar name[128], name2[128];
1754 gboolean userdef = TRUE;
1756 g_snprintf(name, 128, "%s.xbm", btnname);
1757 if (!read_mask(inst, path, name, &btn->mask) && normal_mask)
1759 btn->mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)normal_mask);
1762 g_snprintf(name, 128, "%s_toggled.xbm", btnname);
1763 if (toggled_mask && !read_mask(inst, path, name, &btn->toggled_mask))
1766 btn->toggled_mask = RrPixmapMaskCopy(btn->mask);
1767 else if (toggled_mask)
1768 btn->toggled_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)toggled_mask);
1770 #define READ_BUTTON_MASK_COPY(type, fallback) \
1771 g_snprintf(name, 128, "%s_" #type ".xbm", btnname); \
1772 READ_MASK_COPY(name, btn->type##_mask, fallback);
1774 READ_BUTTON_MASK_COPY(pressed, btn->mask);
1775 READ_BUTTON_MASK_COPY(disabled, btn->mask);
1776 READ_BUTTON_MASK_COPY(hover, btn->mask);
1778 READ_BUTTON_MASK_COPY(pressed_toggled, btn->toggled_mask);
1779 READ_BUTTON_MASK_COPY(hover_toggled, btn->toggled_mask);
1782 #define READ_BUTTON_APPEARANCE(typedots, type, fallback) \
1783 g_snprintf(name, 128, "window.active.button.%s." typedots ".image.color", btnname); \
1784 READ_COLOR(name, btn->focused_##type##_color, RrColorCopy(theme->titlebut_focused_##type##_color)); \
1785 g_snprintf(name, 128, "window.inactive.button.%s." typedots ".image.color", btnname); \
1786 READ_COLOR(name, btn->unfocused_##type##_color, RrColorCopy(theme->titlebut_unfocused_##type##_color)); \
1788 g_snprintf(name, 128, "window.active.button.%s." typedots ".bg", btnname); \
1789 g_snprintf(name2, 128, "window.active.button.%s.toggled.bg", btnname); \
1790 READ_APPEARANCE_(name, name2, btn->a_focused_##type, TRUE, fbs->focused_##type); \
1791 g_snprintf(name, 128, "window.inactive.button.%s." typedots ".bg", btnname); \
1792 g_snprintf(name2, 128, "window.inactive.button.%s.toggled.bg", btnname); \
1793 READ_APPEARANCE_(name, name2, btn->a_unfocused_##type, TRUE, fbs->unfocused_##type); \
1795 g_snprintf(name, 128, "window.active.button.%s." typedots ".bg", btnname); \
1796 READ_APPEARANCE_COPY(name, btn->a_focused_##type, TRUE, fbs->focused_##type); \
1797 g_snprintf(name, 128, "window.inactive.button.%s." typedots ".bg", btnname); \
1798 READ_APPEARANCE_COPY(name, btn->a_unfocused_##type, TRUE, fbs->unfocused_##type); \
1801 READ_BUTTON_APPEARANCE("unpressed", unpressed, 0);
1802 READ_BUTTON_APPEARANCE("pressed", pressed, 0);
1803 READ_BUTTON_APPEARANCE("disabled", disabled, 0);
1804 READ_BUTTON_APPEARANCE("hover", hover, 0);
1806 READ_BUTTON_APPEARANCE("unpressed.toggled", unpressed_toggled, 1);
1807 READ_BUTTON_APPEARANCE("pressed.toggled", pressed_toggled, 0);
1808 READ_BUTTON_APPEARANCE("hover.toggled", hover_toggled, 0);