]> icculus.org git repositories - mikachu/openbox.git/blob - render/theme.c
Need to allocate appearances!
[mikachu/openbox.git] / render / theme.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    theme.c for the Openbox window manager
4    Copyright (c) 2006        Mikael Magnusson
5    Copyright (c) 2003-2007   Dana Jansens
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "render.h"
21 #include "color.h"
22 #include "font.h"
23 #include "mask.h"
24 #include "theme.h"
25 #include "icon.h"
26 #include "parser/parse.h"
27
28 #include <X11/Xlib.h>
29 #include <X11/Xresource.h>
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 static XrmDatabase loaddb(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                           RrTheme *theme, const gchar *maskname,
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);
48
49 #define READ_INT(x_resstr, x_var, x_min, x_max, x_def) \
50     if (!read_int(db, x_resstr, & x_var) || \
51             x_var < x_min || x_var > x_max) \
52         x_var = x_def;
53
54 #define READ_COLOR(x_resstr, x_var, x_def) \
55     if (!read_color(db, inst, x_resstr, & x_var)) \
56         x_var = x_def;
57
58 #define READ_COLOR_(x_res1, x_res2, x_var, x_def) \
59     if (!read_color(db, inst, x_res1, & x_var) && \
60         !read_color(db, inst, x_res2, & x_var)) \
61         x_var = x_def;
62
63 #define READ_MASK_COPY(x_file, x_var, x_copysrc) \
64     if (!read_mask(inst, path, theme, x_file, & x_var)) \
65         x_var = RrPixmapMaskCopy(x_copysrc);
66
67 #define READ_APPEARANCE(x_resstr, x_var, x_parrel) \
68     if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) \
69         set_default_appearance(x_var);
70
71 #define READ_APPEARANCE_COPY(x_resstr, x_var, x_parrel, x_defval) \
72     if (!read_appearance(db, inst, x_resstr, x_var, x_parrel)) {\
73         RrAppearanceFree(x_var); \
74         x_var = RrAppearanceCopy(x_defval); }
75
76 #define READ_APPEARANCE_(x_res1, x_res2, x_var, x_parrel, x_defval) \
77     if (!read_appearance(db, inst, x_res1, x_var, x_parrel) && \
78         !read_appearance(db, inst, x_res2, x_var, x_parrel)) {\
79         RrAppearanceFree(x_var); \
80         x_var = RrAppearanceCopy(x_defval); }
81
82 RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
83                     gboolean allow_fallback,
84                     RrFont *active_window_font, RrFont *inactive_window_font,
85                     RrFont *menu_title_font, RrFont *menu_item_font,
86                     RrFont *osd_font)
87 {
88     XrmDatabase db = NULL;
89     RrJustify winjust, mtitlejust;
90     gchar *str;
91     RrTheme *theme;
92     gchar *path;
93     gboolean userdef;
94     RrAppearance *a_disabled_focused_tmp;
95     RrAppearance *a_disabled_unfocused_tmp;
96     RrAppearance *a_hover_focused_tmp;
97     RrAppearance *a_hover_unfocused_tmp;
98     RrAppearance *a_focused_unpressed_tmp;
99     RrAppearance *a_focused_pressed_tmp;
100     RrAppearance *a_unfocused_unpressed_tmp;
101     RrAppearance *a_unfocused_pressed_tmp;
102     RrAppearance *a_toggled_hover_focused_tmp;
103     RrAppearance *a_toggled_hover_unfocused_tmp;
104     RrAppearance *a_toggled_focused_unpressed_tmp;
105     RrAppearance *a_toggled_focused_pressed_tmp;
106     RrAppearance *a_toggled_unfocused_unpressed_tmp;
107     RrAppearance *a_toggled_unfocused_pressed_tmp;
108
109     if (name) {
110         db = loaddb(name, &path);
111         if (db == NULL) {
112             g_message("Unable to load the theme '%s'", name);
113             if (allow_fallback)
114                 g_message("Falling back to the default theme '%s'",
115                           DEFAULT_THEME);
116             /* fallback to the default theme */
117             name = NULL;
118         }
119     }
120     if (name == NULL) {
121         if (allow_fallback) {
122             db = loaddb(DEFAULT_THEME, &path);
123             if (db == NULL) {
124                 g_message("Unable to load the theme '%s'", DEFAULT_THEME);
125                 return NULL;
126             }
127         } else
128             return NULL;
129     }
130
131     /* initialize temp reading textures */
132     a_disabled_focused_tmp = RrAppearanceNew(inst, 1);
133     a_disabled_unfocused_tmp = RrAppearanceNew(inst, 1);
134     a_hover_focused_tmp = RrAppearanceNew(inst, 1);
135     a_hover_unfocused_tmp = RrAppearanceNew(inst, 1);
136     a_toggled_focused_unpressed_tmp = RrAppearanceNew(inst, 1);
137     a_toggled_unfocused_unpressed_tmp = RrAppearanceNew(inst, 1);
138     a_toggled_hover_focused_tmp = RrAppearanceNew(inst, 1);
139     a_toggled_hover_unfocused_tmp = RrAppearanceNew(inst, 1);
140     a_toggled_focused_pressed_tmp = RrAppearanceNew(inst, 1);
141     a_toggled_unfocused_pressed_tmp = RrAppearanceNew(inst, 1);
142     a_focused_unpressed_tmp = RrAppearanceNew(inst, 1);
143     a_focused_pressed_tmp = RrAppearanceNew(inst, 1);
144     a_unfocused_unpressed_tmp = RrAppearanceNew(inst, 1);
145     a_unfocused_pressed_tmp = RrAppearanceNew(inst, 1);
146
147     /* initialize theme */
148     theme = g_new0(RrTheme, 1);
149
150     theme->inst = inst;
151     theme->name = g_strdup(name ? name : DEFAULT_THEME);
152
153     theme->a_disabled_focused_max = RrAppearanceNew(inst, 1);
154     theme->a_disabled_unfocused_max = RrAppearanceNew(inst, 1);
155     theme->a_hover_focused_max = RrAppearanceNew(inst, 1);
156     theme->a_hover_unfocused_max = RrAppearanceNew(inst, 1);
157     theme->a_toggled_focused_unpressed_max = RrAppearanceNew(inst, 1);
158     theme->a_toggled_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
159     theme->a_toggled_hover_focused_max = RrAppearanceNew(inst, 1);
160     theme->a_toggled_hover_unfocused_max = RrAppearanceNew(inst, 1);
161     theme->a_toggled_focused_pressed_max = RrAppearanceNew(inst, 1);
162     theme->a_toggled_unfocused_pressed_max = RrAppearanceNew(inst, 1);
163     theme->a_focused_unpressed_max = RrAppearanceNew(inst, 1);
164     theme->a_focused_pressed_max = RrAppearanceNew(inst, 1);
165     theme->a_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
166     theme->a_unfocused_pressed_max = RrAppearanceNew(inst, 1);
167     theme->a_disabled_focused_desk = RrAppearanceNew(inst, 1);
168     theme->a_disabled_unfocused_desk = RrAppearanceNew(inst, 1);
169     theme->a_hover_focused_desk = RrAppearanceNew(inst, 1);
170     theme->a_hover_unfocused_desk = RrAppearanceNew(inst, 1);
171     theme->a_toggled_focused_unpressed_desk = RrAppearanceNew(inst, 1);
172     theme->a_toggled_unfocused_unpressed_desk = RrAppearanceNew(inst, 1);
173     theme->a_toggled_hover_focused_desk = RrAppearanceNew(inst, 1);
174     theme->a_toggled_hover_unfocused_desk = RrAppearanceNew(inst, 1);
175     theme->a_toggled_focused_pressed_desk = RrAppearanceNew(inst, 1);
176     theme->a_toggled_unfocused_pressed_desk = RrAppearanceNew(inst, 1);
177     theme->a_focused_unpressed_desk = RrAppearanceNew(inst, 1);
178     theme->a_focused_pressed_desk = RrAppearanceNew(inst, 1);
179     theme->a_unfocused_unpressed_desk = RrAppearanceNew(inst, 1);
180     theme->a_unfocused_pressed_desk = RrAppearanceNew(inst, 1);
181     theme->a_disabled_focused_shade = RrAppearanceNew(inst, 1);
182     theme->a_disabled_unfocused_shade = RrAppearanceNew(inst, 1);
183     theme->a_hover_focused_shade = RrAppearanceNew(inst, 1);
184     theme->a_hover_unfocused_shade = RrAppearanceNew(inst, 1);
185     theme->a_toggled_focused_unpressed_shade = RrAppearanceNew(inst, 1);
186     theme->a_toggled_unfocused_unpressed_shade = RrAppearanceNew(inst, 1);
187     theme->a_toggled_hover_focused_shade = RrAppearanceNew(inst, 1);
188     theme->a_toggled_hover_unfocused_shade = RrAppearanceNew(inst, 1);
189     theme->a_toggled_focused_pressed_shade = RrAppearanceNew(inst, 1);
190     theme->a_toggled_unfocused_pressed_shade = RrAppearanceNew(inst, 1);
191     theme->a_focused_unpressed_shade = RrAppearanceNew(inst, 1);
192     theme->a_focused_pressed_shade = RrAppearanceNew(inst, 1);
193     theme->a_unfocused_unpressed_shade = RrAppearanceNew(inst, 1);
194     theme->a_unfocused_pressed_shade = RrAppearanceNew(inst, 1);
195     theme->a_disabled_focused_close = RrAppearanceNew(inst, 1);
196     theme->a_disabled_unfocused_close = RrAppearanceNew(inst, 1);
197     theme->a_hover_focused_close = RrAppearanceNew(inst, 1);
198     theme->a_hover_unfocused_close = RrAppearanceNew(inst, 1);
199     theme->a_focused_unpressed_close = RrAppearanceNew(inst, 1);
200     theme->a_focused_pressed_close = RrAppearanceNew(inst, 1);
201     theme->a_unfocused_unpressed_close = RrAppearanceNew(inst, 1);
202     theme->a_unfocused_pressed_close = RrAppearanceNew(inst, 1);
203     theme->a_disabled_focused_iconify = RrAppearanceNew(inst, 1);
204     theme->a_disabled_unfocused_iconify = RrAppearanceNew(inst, 1);
205     theme->a_hover_focused_iconify = RrAppearanceNew(inst, 1);
206     theme->a_hover_unfocused_iconify = RrAppearanceNew(inst, 1);
207     theme->a_focused_unpressed_iconify = RrAppearanceNew(inst, 1);
208     theme->a_focused_pressed_iconify = RrAppearanceNew(inst, 1);
209     theme->a_unfocused_unpressed_iconify = RrAppearanceNew(inst, 1);
210     theme->a_unfocused_pressed_iconify = RrAppearanceNew(inst, 1);
211     theme->a_focused_grip = RrAppearanceNew(inst, 0);
212     theme->a_unfocused_grip = RrAppearanceNew(inst, 0);
213     theme->a_focused_title = RrAppearanceNew(inst, 0);
214     theme->a_unfocused_title = RrAppearanceNew(inst, 0);
215     theme->a_focused_label = RrAppearanceNew(inst, 1);
216     theme->a_unfocused_label = RrAppearanceNew(inst, 1);
217     theme->a_icon = RrAppearanceNew(inst, 1);
218     theme->a_focused_handle = RrAppearanceNew(inst, 0);
219     theme->a_unfocused_handle = RrAppearanceNew(inst, 0);
220     theme->a_menu = RrAppearanceNew(inst, 0);
221     theme->a_menu_title = RrAppearanceNew(inst, 0);
222     theme->a_menu_text_title = RrAppearanceNew(inst, 1);
223     theme->a_menu_normal = RrAppearanceNew(inst, 0);
224     theme->a_menu_selected = RrAppearanceNew(inst, 0);
225     theme->a_menu_disabled = RrAppearanceNew(inst, 0);
226     /* a_menu_disabled_selected is copied from a_menu_selected */
227     theme->a_menu_text_normal = RrAppearanceNew(inst, 1);
228     theme->a_menu_text_selected = RrAppearanceNew(inst, 1);
229     theme->a_menu_text_disabled = RrAppearanceNew(inst, 1);
230     theme->a_menu_text_disabled_selected = RrAppearanceNew(inst, 1);
231     theme->a_menu_bullet_normal = RrAppearanceNew(inst, 1);
232     theme->a_menu_bullet_selected = RrAppearanceNew(inst, 1);
233     theme->a_clear = RrAppearanceNew(inst, 0);
234     theme->a_clear_tex = RrAppearanceNew(inst, 1);
235     theme->osd_hilite_bg = RrAppearanceNew(inst, 0);
236     theme->osd_hilite_label = RrAppearanceNew(inst, 1);
237     theme->osd_hilite_fg = RrAppearanceNew(inst, 0);
238     theme->osd_unhilite_fg = RrAppearanceNew(inst, 0);
239
240     /* load the font stuff */
241     if (active_window_font) {
242         theme->win_font_focused = active_window_font;
243         RrFontRef(active_window_font);
244     } else
245         theme->win_font_focused = RrFontOpenDefault(inst);
246
247     if (inactive_window_font) {
248         theme->win_font_unfocused = inactive_window_font;
249         RrFontRef(inactive_window_font);
250     } else
251         theme->win_font_unfocused = RrFontOpenDefault(inst);
252
253     winjust = RR_JUSTIFY_LEFT;
254     if (read_string(db, "window.label.text.justify", &str)) {
255         if (!g_ascii_strcasecmp(str, "right"))
256             winjust = RR_JUSTIFY_RIGHT;
257         else if (!g_ascii_strcasecmp(str, "center"))
258             winjust = RR_JUSTIFY_CENTER;
259     }
260
261     if (menu_title_font) {
262         theme->menu_title_font = menu_title_font;
263         RrFontRef(menu_title_font);
264     } else
265         theme->menu_title_font = RrFontOpenDefault(inst);
266
267     mtitlejust = RR_JUSTIFY_LEFT;
268     if (read_string(db, "menu.title.text.justify", &str)) {
269         if (!g_ascii_strcasecmp(str, "right"))
270             mtitlejust = RR_JUSTIFY_RIGHT;
271         else if (!g_ascii_strcasecmp(str, "center"))
272             mtitlejust = RR_JUSTIFY_CENTER;
273     }
274
275     if (menu_item_font) {
276         theme->menu_font = menu_item_font;
277         RrFontRef(menu_item_font);
278     } else
279         theme->menu_font = RrFontOpenDefault(inst);
280
281     if (osd_font) {
282         theme->osd_font = osd_font;
283         RrFontRef(osd_font);
284     } else
285         theme->osd_font = RrFontOpenDefault(inst);
286
287     /* load direct dimensions */
288     READ_INT("menu.overlap", theme->menu_overlap, -100, 100, 0);
289     READ_INT("window.handle.width", theme->handle_height, 0, 100, 6);
290     READ_INT("padding.width", theme->paddingx, 0, 100, 3);
291     READ_INT("padding.height", theme->paddingy, 0, 100, theme->paddingx);
292     READ_INT("border.width", theme->fbwidth, 0, 100, 1);
293     READ_INT("menu.border.width", theme->mbwidth, 0, 100, theme->fbwidth);
294     READ_INT("osd.border.width", theme->obwidth, 0, 100, theme->fbwidth);
295     READ_INT("window.client.padding.width", theme->cbwidthx, 0, 100,
296              theme->paddingx);
297     READ_INT("window.client.padding.height", theme->cbwidthy, 0, 100,
298              theme->cbwidthx);
299
300     /* load colors */
301     READ_COLOR_("window.active.border.color", "border.color",
302                 theme->frame_focused_border_color, RrColorNew(inst, 0, 0, 0));
303
304     /* title separator focused color inherits from focused boder color */
305     READ_COLOR("window.active.title.separator.color",
306                theme->title_separator_focused_color,
307                RrColorCopy(theme->frame_focused_border_color));
308
309     /* unfocused border color inherits from frame focused border color */
310     READ_COLOR("window.inactive.border.color",
311                theme->frame_unfocused_border_color,
312                RrColorCopy(theme->frame_focused_border_color));
313
314     /* title separator unfocused color inherits from unfocused boder color */
315     READ_COLOR("window.inactive.title.separator.color",
316                theme->title_separator_unfocused_color,
317                RrColorCopy(theme->frame_unfocused_border_color));
318
319     /* menu border color inherits from frame focused border color */
320     READ_COLOR("menu.border.color", theme->menu_border_color,
321                RrColorCopy(theme->frame_focused_border_color));
322
323     /* osd border color inherits from frame focused border color */
324     READ_COLOR("osd.border.color", theme->osd_border_color,
325                RrColorCopy(theme->frame_focused_border_color));
326
327     READ_COLOR("window.active.client.color", theme->cb_focused_color,
328                RrColorNew(inst, 0xff, 0xff, 0xff));
329
330     READ_COLOR("window.inactive.client.color", theme->cb_unfocused_color,
331                RrColorNew(inst, 0xff, 0xff, 0xff));
332
333     READ_COLOR("window.active.label.text.color", theme->title_focused_color,
334                RrColorNew(inst, 0x0, 0x0, 0x0));
335
336     READ_COLOR("osd.label.text.color", theme->osd_color,
337                RrColorCopy(theme->title_focused_color));
338
339     READ_COLOR("window.inactive.label.text.color",
340                theme->title_unfocused_color,
341                RrColorNew(inst, 0xff, 0xff, 0xff));
342
343     READ_COLOR("window.active.button.unpressed.image.color",
344                theme->titlebut_focused_unpressed_color,
345                RrColorNew(inst, 0, 0, 0));
346
347     READ_COLOR("window.inactive.button.unpressed.image.color",
348                theme->titlebut_unfocused_unpressed_color,
349                RrColorNew(inst, 0xff, 0xff, 0xff));
350
351     READ_COLOR("window.active.button.pressed.image.color",
352                theme->titlebut_focused_pressed_color,
353                RrColorCopy(theme->titlebut_focused_unpressed_color));
354
355     READ_COLOR("window.inactive.button.pressed.image.color",
356                theme->titlebut_unfocused_pressed_color,
357                RrColorCopy(theme->titlebut_unfocused_unpressed_color));
358
359     READ_COLOR("window.active.button.disabled.image.color",
360                theme->titlebut_disabled_focused_color,
361                RrColorNew(inst, 0xff, 0xff, 0xff));
362
363     READ_COLOR("window.inactive.button.disabled.image.color",
364                theme->titlebut_disabled_unfocused_color,
365                RrColorNew(inst, 0, 0, 0));
366
367     READ_COLOR("window.active.button.hover.image.color",
368                theme->titlebut_hover_focused_color,
369                RrColorCopy(theme->titlebut_focused_unpressed_color));
370
371     READ_COLOR("window.inactive.button.hover.image.color",
372                theme->titlebut_hover_unfocused_color,
373                RrColorCopy(theme->titlebut_unfocused_unpressed_color));
374
375     READ_COLOR_("window.active.button.toggled.unpressed.image.color",
376                 "window.active.button.toggled.image.color",
377                 theme->titlebut_toggled_focused_unpressed_color,
378                 RrColorCopy(theme->titlebut_focused_pressed_color));
379
380     READ_COLOR_("window.inactive.button.toggled.unpressed.image.color",
381                 "window.inactive.button.toggled.image.color",
382                 theme->titlebut_toggled_unfocused_unpressed_color,
383                 RrColorCopy(theme->titlebut_unfocused_pressed_color));
384
385     READ_COLOR("window.active.button.toggled.hover.image.color",
386                theme->titlebut_toggled_hover_focused_color,
387                RrColorCopy(theme->titlebut_toggled_focused_unpressed_color));
388
389     READ_COLOR("window.inactive.button.toggled.hover.image.color",
390                theme->titlebut_toggled_hover_unfocused_color,
391                RrColorCopy(theme->titlebut_toggled_unfocused_unpressed_color));
392
393     READ_COLOR("window.active.button.toggled.pressed.image.color",
394                theme->titlebut_toggled_focused_pressed_color,
395                RrColorCopy(theme->titlebut_focused_pressed_color));
396
397     READ_COLOR("window.inactive.button.toggled.pressed.image.color",
398                theme->titlebut_toggled_unfocused_pressed_color,
399                RrColorCopy(theme->titlebut_unfocused_pressed_color));
400
401     READ_COLOR("menu.title.text.color", theme->menu_title_color,
402                RrColorNew(inst, 0, 0, 0));
403
404     READ_COLOR("menu.items.text.color", theme->menu_color,
405                RrColorNew(inst, 0xff, 0xff, 0xff));
406
407     READ_COLOR("menu.items.disabled.text.color", theme->menu_disabled_color,
408                RrColorNew(inst, 0, 0, 0));
409
410     READ_COLOR("menu.items.active.disabled.text.color",
411                theme->menu_disabled_selected_color,
412                RrColorCopy(theme->menu_disabled_color));
413
414     READ_COLOR("menu.items.active.text.color", theme->menu_selected_color,
415                RrColorNew(inst, 0, 0, 0));
416
417
418     /* load the image masks */
419
420     /* maximize button masks */
421     userdef = TRUE;
422     if (!read_mask(inst, path, theme, "max.xbm", &theme->max_mask)) {
423             guchar data[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f };
424             theme->max_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
425             userdef = FALSE;
426     }
427     if (!read_mask(inst, path, theme, "max_toggled.xbm",
428                    &theme->max_toggled_mask))
429     {
430         if (userdef)
431             theme->max_toggled_mask = RrPixmapMaskCopy(theme->max_mask);
432         else {
433             guchar data[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f };
434             theme->max_toggled_mask = RrPixmapMaskNew(inst, 6, 6,(gchar*)data);
435         }
436     }
437     READ_MASK_COPY("max_pressed.xbm", theme->max_pressed_mask,
438                    theme->max_mask);
439     READ_MASK_COPY("max_disabled.xbm", theme->max_disabled_mask,
440                    theme->max_mask);
441     READ_MASK_COPY("max_hover.xbm", theme->max_hover_mask, theme->max_mask);
442     READ_MASK_COPY("max_toggled_pressed.xbm", theme->max_toggled_pressed_mask,
443                    theme->max_toggled_mask);
444     READ_MASK_COPY("max_toggled_hover.xbm", theme->max_toggled_hover_mask,
445                    theme->max_toggled_mask);
446
447     /* iconify button masks */
448     if (!read_mask(inst, path, theme, "iconify.xbm", &theme->iconify_mask)) {
449         guchar data[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f };
450         theme->iconify_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
451     }
452     READ_MASK_COPY("iconify_pressed.xbm", theme->iconify_pressed_mask,
453                    theme->iconify_mask);
454     READ_MASK_COPY("iconify_disabled.xbm", theme->iconify_disabled_mask,
455                    theme->iconify_mask);
456     READ_MASK_COPY("iconify_hover.xbm", theme->iconify_hover_mask,
457                    theme->iconify_mask);
458
459     /* all desktops button masks */
460     userdef = TRUE;
461     if (!read_mask(inst, path, theme, "desk.xbm", &theme->desk_mask)) {
462         guchar data[] = { 0x33, 0x33, 0x00, 0x00, 0x33, 0x33 };
463         theme->desk_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
464         userdef = FALSE;
465     }
466     if (!read_mask(inst, path, theme, "desk_toggled.xbm",
467                    &theme->desk_toggled_mask)) {
468         if (userdef)
469             theme->desk_toggled_mask = RrPixmapMaskCopy(theme->desk_mask);
470         else {
471             guchar data[] = { 0x00, 0x1e, 0x1a, 0x16, 0x1e, 0x00 };
472             theme->desk_toggled_mask =
473                 RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
474         }
475     }
476     READ_MASK_COPY("desk_pressed.xbm", theme->desk_pressed_mask,
477                    theme->desk_mask);
478     READ_MASK_COPY("desk_disabled.xbm", theme->desk_disabled_mask,
479                    theme->desk_mask);
480     READ_MASK_COPY("desk_hover.xbm", theme->desk_hover_mask, theme->desk_mask);
481     READ_MASK_COPY("desk_toggled_pressed.xbm",
482                    theme->desk_toggled_pressed_mask, theme->desk_toggled_mask);
483     READ_MASK_COPY("desk_toggled_hover.xbm", theme->desk_toggled_hover_mask,
484                    theme->desk_toggled_mask);
485
486     /* shade button masks */
487     if (!read_mask(inst, path, theme, "shade.xbm", &theme->shade_mask)) {
488         guchar data[] = { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 };
489         theme->shade_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
490     }
491     READ_MASK_COPY("shade_toggled.xbm", theme->shade_toggled_mask,
492                    theme->shade_mask);
493     READ_MASK_COPY("shade_pressed.xbm", theme->shade_pressed_mask,
494                    theme->shade_mask);
495     READ_MASK_COPY("shade_disabled.xbm", theme->shade_disabled_mask,
496                    theme->shade_mask);
497     READ_MASK_COPY("shade_hover.xbm", theme->shade_hover_mask,
498                    theme->shade_mask);
499     READ_MASK_COPY("shade_toggled_pressed.xbm",
500                    theme->shade_toggled_pressed_mask,
501                    theme->shade_toggled_mask);
502     READ_MASK_COPY("shade_toggled_hover.xbm",
503                    theme->shade_toggled_hover_mask, theme->shade_toggled_mask);
504
505     /* close button masks */
506     if (!read_mask(inst, path, theme, "close.xbm", &theme->close_mask)) {
507         guchar data[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
508         theme->close_mask = RrPixmapMaskNew(inst, 6, 6, (gchar*)data);
509     }
510     READ_MASK_COPY("close_pressed.xbm", theme->close_pressed_mask,
511                    theme->close_mask);
512     READ_MASK_COPY("close_disabled.xbm", theme->close_disabled_mask,
513                    theme->close_mask);
514     READ_MASK_COPY("close_hover.xbm", theme->close_hover_mask,
515                    theme->close_mask);
516
517     /* submenu bullet mask */
518     if (!read_mask(inst, path, theme, "bullet.xbm", &theme->menu_bullet_mask))
519     {
520         guchar data[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01 };
521         theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
522     }
523
524     /* setup the default window icon */
525     theme->def_win_icon = read_c_image(OB_DEFAULT_ICON_WIDTH,
526                                        OB_DEFAULT_ICON_HEIGHT,
527                                        OB_DEFAULT_ICON_pixel_data);
528
529     /* read the decoration textures */
530     READ_APPEARANCE("window.active.title.bg", theme->a_focused_title, FALSE);
531     READ_APPEARANCE("window.inactive.title.bg", theme->a_unfocused_title,
532                     FALSE);
533     READ_APPEARANCE("window.active.label.bg", theme->a_focused_label, TRUE);
534     READ_APPEARANCE("window.inactive.label.bg", theme->a_unfocused_label,
535                     TRUE);
536     READ_APPEARANCE("window.active.handle.bg", theme->a_focused_handle, FALSE);
537     READ_APPEARANCE("window.inactive.handle.bg",theme->a_unfocused_handle,
538                     FALSE);
539     READ_APPEARANCE("window.active.grip.bg", theme->a_focused_grip, TRUE);
540     READ_APPEARANCE("window.inactive.grip.bg", theme->a_unfocused_grip, TRUE);
541     READ_APPEARANCE("menu.items.bg", theme->a_menu, FALSE);
542     READ_APPEARANCE("menu.title.bg", theme->a_menu_title, TRUE);
543     READ_APPEARANCE("menu.items.active.bg", theme->a_menu_selected, TRUE);
544
545     theme->a_menu_disabled_selected =
546         RrAppearanceCopy(theme->a_menu_selected);
547
548     /* read appearances for non-decorations (on-screen-display) */
549     if (!read_appearance(db, inst, "osd.bg", theme->osd_hilite_bg, FALSE)) {
550         RrAppearanceFree(theme->osd_hilite_bg);
551         theme->osd_hilite_bg = RrAppearanceCopy(theme->a_focused_title);
552     }
553     if (!read_appearance(db, inst, "osd.label.bg",
554                          theme->osd_hilite_label, TRUE)) {
555         RrAppearanceFree(theme->osd_hilite_label);
556         theme->osd_hilite_label = RrAppearanceCopy(theme->a_focused_label);
557     }
558     /* osd_hilite_fg can't be parentrel */
559     if (!read_appearance(db, inst, "osd.hilight.bg",
560                          theme->osd_hilite_fg, FALSE)) {
561         RrAppearanceFree(theme->osd_hilite_fg);
562         if (theme->a_focused_label->surface.grad != RR_SURFACE_PARENTREL)
563             theme->osd_hilite_fg = RrAppearanceCopy(theme->a_focused_label);
564         else
565             theme->osd_hilite_fg = RrAppearanceCopy(theme->a_focused_title);
566     }
567     /* osd_unhilite_fg can't be parentrel either */
568     if (!read_appearance(db, inst, "osd.unhilight.bg",
569                          theme->osd_unhilite_fg, FALSE)) {
570         RrAppearanceFree(theme->osd_unhilite_fg);
571         if (theme->a_unfocused_label->surface.grad != RR_SURFACE_PARENTREL)
572             theme->osd_unhilite_fg=RrAppearanceCopy(theme->a_unfocused_label);
573         else
574             theme->osd_unhilite_fg=RrAppearanceCopy(theme->a_unfocused_title);
575     }
576
577     /* read buttons textures */
578     READ_APPEARANCE("window.active.button.disabled.bg",
579                     a_disabled_focused_tmp, TRUE);
580     READ_APPEARANCE("window.inactive.button.disabled.bg",
581                     a_disabled_unfocused_tmp, TRUE);
582     READ_APPEARANCE("window.active.button.pressed.bg",
583                     a_focused_pressed_tmp, TRUE);
584     READ_APPEARANCE("window.inactive.button.pressed.bg",
585                     a_unfocused_pressed_tmp, TRUE);
586
587     READ_APPEARANCE_("window.active.button.toggled.unpressed.bg",
588                      "window.active.button.toggled.bg",
589                      a_toggled_focused_unpressed_tmp, TRUE,
590                      a_focused_pressed_tmp);
591     READ_APPEARANCE_("window.inactive.button.toggled.unpressed.bg",
592                      "window.inactive.button.toggled.bg",
593                      a_toggled_unfocused_unpressed_tmp, TRUE,
594                      a_unfocused_pressed_tmp);
595
596     READ_APPEARANCE_COPY("window.active.button.toggled.hover.bg",
597                          a_toggled_hover_focused_tmp, TRUE,
598                          a_toggled_focused_unpressed_tmp);
599     READ_APPEARANCE_COPY("window.inactive.button.toggled.hover.bg",
600                          a_toggled_hover_unfocused_tmp, TRUE,
601                          a_toggled_unfocused_unpressed_tmp);
602
603     READ_APPEARANCE_COPY("window.active.button.toggled.pressed.bg",
604                          a_toggled_focused_pressed_tmp, TRUE,
605                          a_focused_pressed_tmp);
606     READ_APPEARANCE_COPY("window.inactive.button.toggled.pressed.bg",
607                          a_toggled_unfocused_pressed_tmp, TRUE,
608                          a_unfocused_pressed_tmp);
609
610     READ_APPEARANCE("window.active.button.unpressed.bg",
611                     a_focused_unpressed_tmp, TRUE);
612     READ_APPEARANCE("window.inactive.button.unpressed.bg",
613                     a_unfocused_unpressed_tmp, TRUE);
614
615     READ_APPEARANCE_COPY("window.active.button.hover.bg",
616                          a_hover_focused_tmp, TRUE,
617                          a_focused_unpressed_tmp);
618     READ_APPEARANCE_COPY("window.inactive.button.hover.bg",
619                          a_hover_unfocused_tmp, TRUE,
620                          a_unfocused_unpressed_tmp);
621
622     /* now do individual buttons, if specified */
623
624     /* max button */
625     READ_APPEARANCE_COPY("window.active.button-max.disabled.bg",
626                          theme->a_disabled_focused_max, TRUE,
627                          a_disabled_focused_tmp);
628     READ_APPEARANCE_COPY("window.inactive.button-max.disabled.bg",
629                          theme->a_disabled_unfocused_max, TRUE,
630                          a_disabled_unfocused_tmp);
631     READ_APPEARANCE_COPY("window.active.button-max.pressed.bg",
632                          theme->a_hover_focused_max, TRUE,
633                          a_hover_focused_tmp);
634     READ_APPEARANCE_COPY("window.inactive.button-max.pressed.bg",
635                          theme->a_hover_unfocused_max, TRUE,
636                          a_hover_unfocused_tmp);
637     READ_APPEARANCE_COPY("window.active.button-max.unpressed.bg",
638                          theme->a_focused_unpressed_max, TRUE,
639                          a_focused_unpressed_tmp);
640     READ_APPEARANCE_COPY("window.active.button-max.pressed.bg",
641                          theme->a_focused_pressed_max, TRUE,
642                          a_focused_pressed_tmp);
643     READ_APPEARANCE_COPY("window.inactive.button-max.unpressed.bg",
644                          theme->a_unfocused_unpressed_max, TRUE,
645                          a_unfocused_unpressed_tmp);
646     READ_APPEARANCE_COPY("window.inactive.button-max.pressed.bg",
647                          theme->a_unfocused_pressed_max, TRUE,
648                          a_unfocused_pressed_tmp);
649     READ_APPEARANCE_COPY("window.active.button-max.toggled.hover.bg",
650                          theme->a_toggled_hover_focused_max, TRUE,
651                          a_toggled_hover_focused_tmp);
652     READ_APPEARANCE_COPY("window.inactive.button-max.toggled.hover.bg",
653                          theme->a_toggled_hover_unfocused_max, TRUE,
654                          a_toggled_hover_unfocused_tmp);
655     READ_APPEARANCE_COPY("window.active.button-max.toggled.unpressed.bg",
656                          theme->a_toggled_focused_unpressed_max, TRUE,
657                          a_toggled_focused_unpressed_tmp);
658     READ_APPEARANCE_COPY("window.active.button-max.toggled.pressed.bg",
659                          theme->a_toggled_focused_pressed_max, TRUE,
660                          a_toggled_focused_pressed_tmp);
661     READ_APPEARANCE_COPY("window.inactive.button-max.toggled.unpressed.bg",
662                          theme->a_toggled_unfocused_unpressed_max, TRUE,
663                          a_toggled_unfocused_unpressed_tmp);
664     READ_APPEARANCE_COPY("window.inactive.button-max.toggled.pressed.bg",
665                          theme->a_toggled_unfocused_pressed_max, TRUE,
666                          a_toggled_unfocused_pressed_tmp);
667
668     /* close button */
669     READ_APPEARANCE_COPY("window.active.button-close.disabled.bg",
670                          theme->a_disabled_focused_close, TRUE,
671                          a_disabled_focused_tmp);
672     READ_APPEARANCE_COPY("window.inactive.button-close.disabled.bg",
673                          theme->a_disabled_unfocused_close, TRUE,
674                          a_disabled_unfocused_tmp);
675     READ_APPEARANCE_COPY("window.active.button-close.hover.bg",
676                          theme->a_hover_focused_close, TRUE,
677                          a_hover_focused_tmp);
678     READ_APPEARANCE_COPY("window.inactive.button-close.hover.bg",
679                          theme->a_hover_unfocused_close, TRUE,
680                          a_hover_unfocused_tmp);
681     READ_APPEARANCE_COPY("window.active.button-close.unpressed.bg",
682                          theme->a_focused_unpressed_close, TRUE,
683                          a_focused_unpressed_tmp);
684     READ_APPEARANCE_COPY("window.active.button-close.pressed.bg",
685                          theme->a_focused_pressed_close, TRUE,
686                          a_focused_pressed_tmp);
687     READ_APPEARANCE_COPY("window.inactive.button-close.unpressed.bg",
688                          theme->a_unfocused_unpressed_close, TRUE,
689                          a_unfocused_unpressed_tmp);
690     READ_APPEARANCE_COPY("window.inactive.button-close.pressed.bg",
691                          theme->a_unfocused_pressed_close, TRUE,
692                          a_unfocused_pressed_tmp);
693
694     /* desk button */
695     READ_APPEARANCE_COPY("window.active.button-desk.disabled.bg",
696                          theme->a_disabled_focused_desk, TRUE,
697                          a_disabled_focused_tmp);
698     READ_APPEARANCE_COPY("window.inactive.button-desk.disabled.bg",
699                          theme->a_disabled_unfocused_desk, TRUE,
700                          a_disabled_unfocused_tmp);
701     READ_APPEARANCE_COPY("window.active.button-desk.pressed.bg",
702                          theme->a_hover_focused_desk, TRUE,
703                          a_hover_focused_tmp);
704     READ_APPEARANCE_COPY("window.inactive.button-desk.pressed.bg",
705                          theme->a_hover_unfocused_desk, TRUE,
706                          a_hover_unfocused_tmp);
707     READ_APPEARANCE_COPY("window.active.button-desk.unpressed.bg",
708                          theme->a_focused_unpressed_desk, TRUE,
709                          a_focused_unpressed_tmp);
710     READ_APPEARANCE_COPY("window.active.button-desk.pressed.bg",
711                          theme->a_focused_pressed_desk, TRUE,
712                          a_focused_pressed_tmp);
713     READ_APPEARANCE_COPY("window.inactive.button-desk.unpressed.bg",
714                          theme->a_unfocused_unpressed_desk, TRUE,
715                          a_unfocused_unpressed_tmp);
716     READ_APPEARANCE_COPY("window.inactive.button-desk.pressed.bg",
717                          theme->a_unfocused_pressed_desk, TRUE,
718                          a_unfocused_pressed_tmp);
719     READ_APPEARANCE_COPY("window.active.button-desk.toggled.hover.bg",
720                          theme->a_toggled_hover_focused_desk, TRUE,
721                          a_toggled_hover_focused_tmp);
722     READ_APPEARANCE_COPY("window.inactive.button-desk.toggled.hover.bg",
723                          theme->a_toggled_hover_unfocused_desk, TRUE,
724                          a_toggled_hover_unfocused_tmp);
725     READ_APPEARANCE_COPY("window.active.button-desk.toggled.unpressed.bg",
726                          theme->a_toggled_focused_unpressed_desk, TRUE,
727                          a_toggled_focused_unpressed_tmp);
728     READ_APPEARANCE_COPY("window.active.button-desk.toggled.pressed.bg",
729                          theme->a_toggled_focused_pressed_desk, TRUE,
730                          a_toggled_focused_pressed_tmp);
731     READ_APPEARANCE_COPY("window.inactive.button-desk.toggled.unpressed.bg",
732                          theme->a_toggled_unfocused_unpressed_desk, TRUE,
733                          a_toggled_unfocused_unpressed_tmp);
734     READ_APPEARANCE_COPY("window.inactive.button-desk.toggled.pressed.bg",
735                          theme->a_toggled_unfocused_pressed_desk, TRUE,
736                          a_toggled_unfocused_pressed_tmp);
737
738     /* shade button */
739     READ_APPEARANCE_COPY("window.active.button-shade.disabled.bg",
740                          theme->a_disabled_focused_shade, TRUE,
741                          a_disabled_focused_tmp);
742     READ_APPEARANCE_COPY("window.inactive.button-shade.disabled.bg",
743                          theme->a_disabled_unfocused_shade, TRUE,
744                          a_disabled_unfocused_tmp);
745     READ_APPEARANCE_COPY("window.active.button-shade.pressed.bg",
746                          theme->a_hover_focused_shade, TRUE,
747                          a_hover_focused_tmp);
748     READ_APPEARANCE_COPY("window.inactive.button-shade.pressed.bg",
749                          theme->a_hover_unfocused_shade, TRUE,
750                          a_hover_unfocused_tmp);
751     READ_APPEARANCE_COPY("window.active.button-shade.unpressed.bg",
752                          theme->a_focused_unpressed_shade, TRUE,
753                          a_focused_unpressed_tmp);
754     READ_APPEARANCE_COPY("window.active.button-shade.pressed.bg",
755                          theme->a_focused_pressed_shade, TRUE,
756                          a_focused_pressed_tmp);
757     READ_APPEARANCE_COPY("window.inactive.button-shade.unpressed.bg",
758                          theme->a_unfocused_unpressed_shade, TRUE,
759                          a_unfocused_unpressed_tmp);
760     READ_APPEARANCE_COPY("window.inactive.button-shade.pressed.bg",
761                          theme->a_unfocused_pressed_shade, TRUE,
762                          a_unfocused_pressed_tmp);
763     READ_APPEARANCE_COPY("window.active.button-shade.toggled.hover.bg",
764                          theme->a_toggled_hover_focused_shade, TRUE,
765                          a_toggled_hover_focused_tmp);
766     READ_APPEARANCE_COPY("window.inactive.button-shade.toggled.hover.bg",
767                          theme->a_toggled_hover_unfocused_shade, TRUE,
768                          a_toggled_hover_unfocused_tmp);
769     READ_APPEARANCE_COPY("window.active.button-shade.toggled.unpressed.bg",
770                          theme->a_toggled_focused_unpressed_shade, TRUE,
771                          a_toggled_focused_unpressed_tmp);
772     READ_APPEARANCE_COPY("window.active.button-shade.toggled.pressed.bg",
773                          theme->a_toggled_focused_pressed_shade, TRUE,
774                          a_toggled_focused_pressed_tmp);
775     READ_APPEARANCE_COPY("window.inactive.button-shade.toggled.unpressed.bg",
776                          theme->a_toggled_unfocused_unpressed_shade, TRUE,
777                          a_toggled_unfocused_unpressed_tmp);
778     READ_APPEARANCE_COPY("window.inactive.button-shade.toggled.pressed.bg",
779                          theme->a_toggled_unfocused_pressed_shade, TRUE,
780                          a_toggled_unfocused_pressed_tmp);
781
782     /* iconify button */
783     READ_APPEARANCE_COPY("window.active.button-iconify.disabled.bg",
784                          theme->a_disabled_focused_iconify, TRUE,
785                          a_disabled_focused_tmp);
786     READ_APPEARANCE_COPY("window.inactive.button-iconify.disabled.bg",
787                          theme->a_disabled_unfocused_iconify, TRUE,
788                          a_disabled_unfocused_tmp);
789     READ_APPEARANCE_COPY("window.active.button-iconify.hover.bg",
790                          theme->a_hover_focused_iconify, TRUE,
791                          a_hover_focused_tmp);
792     READ_APPEARANCE_COPY("window.inactive.button-iconify.hover.bg",
793                          theme->a_hover_unfocused_iconify, TRUE,
794                          a_hover_unfocused_tmp);
795     READ_APPEARANCE_COPY("window.active.button-iconify.unpressed.bg",
796                          theme->a_focused_unpressed_iconify, TRUE,
797                          a_focused_unpressed_tmp);
798     READ_APPEARANCE_COPY("window.active.button-iconify.pressed.bg",
799                          theme->a_focused_pressed_iconify, TRUE,
800                          a_focused_pressed_tmp);
801     READ_APPEARANCE_COPY("window.inactive.button-iconify.unpressed.bg",
802                          theme->a_unfocused_unpressed_iconify, TRUE,
803                          a_unfocused_unpressed_tmp);
804     READ_APPEARANCE_COPY("window.inactive.button-iconify.pressed.bg",
805                          theme->a_unfocused_pressed_iconify, TRUE,
806                          a_unfocused_pressed_tmp);
807
808     theme->a_icon->surface.grad =
809         theme->a_clear->surface.grad =
810         theme->a_clear_tex->surface.grad =
811         theme->a_menu_text_title->surface.grad =
812         theme->a_menu_normal->surface.grad =
813         theme->a_menu_disabled->surface.grad =
814         theme->a_menu_text_normal->surface.grad =
815         theme->a_menu_text_selected->surface.grad =
816         theme->a_menu_text_disabled->surface.grad =
817         theme->a_menu_text_disabled_selected->surface.grad =
818         theme->a_menu_bullet_normal->surface.grad =
819         theme->a_menu_bullet_selected->surface.grad = RR_SURFACE_PARENTREL;
820
821     /* set up the textures */
822     theme->a_focused_label->texture[0].type = RR_TEXTURE_TEXT;
823     theme->a_focused_label->texture[0].data.text.justify = winjust;
824     theme->a_focused_label->texture[0].data.text.font=theme->win_font_focused;
825     theme->a_focused_label->texture[0].data.text.color =
826         theme->title_focused_color;
827
828     if (read_string(db, "window.active.label.text.font", &str)) {
829         char *p;
830         gint i = 0;
831         gint j;
832         if (strstr(str, "shadow=y")) {
833             if ((p = strstr(str, "shadowoffset=")))
834                 i = parse_inline_number(p + strlen("shadowoffset="));
835             else
836                 i = 1;
837             theme->a_focused_label->texture[0].data.text.shadow_offset_x = i;
838             theme->a_focused_label->texture[0].data.text.shadow_offset_y = i;
839         }
840         if ((p = strstr(str, "shadowtint=")))
841         {
842             i = parse_inline_number(p + strlen("shadowtint="));
843             j = (i > 0 ? 0 : 255);
844             i = ABS(i*255/100);
845
846             theme->title_focused_shadow_color = RrColorNew(inst, j, j, j);
847             theme->title_focused_shadow_alpha = i;
848         } else {
849             theme->title_focused_shadow_color = RrColorNew(inst, 0, 0, 0);
850             theme->title_focused_shadow_alpha = 50;
851         }
852     }
853
854     theme->a_focused_label->texture[0].data.text.shadow_color =
855         theme->title_focused_shadow_color;
856     theme->a_focused_label->texture[0].data.text.shadow_alpha =
857         theme->title_focused_shadow_alpha;
858
859     theme->osd_hilite_label->texture[0].type = RR_TEXTURE_TEXT;
860     theme->osd_hilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
861     theme->osd_hilite_label->texture[0].data.text.font = theme->osd_font;
862     theme->osd_hilite_label->texture[0].data.text.color = theme->osd_color;
863
864     if (read_string(db, "osd.label.text.font", &str)) {
865         char *p;
866         gint i = 0;
867         gint j;
868         if (strstr(str, "shadow=y")) {
869             if ((p = strstr(str, "shadowoffset=")))
870                 i = parse_inline_number(p + strlen("shadowoffset="));
871             else
872                 i = 1;
873             theme->a_focused_label->texture[0].data.text.shadow_offset_x = i;
874             theme->a_focused_label->texture[0].data.text.shadow_offset_y = i;
875             theme->osd_hilite_label->texture[0].data.text.shadow_offset_x = i;
876             theme->osd_hilite_label->texture[0].data.text.shadow_offset_y = i;
877         }
878         if ((p = strstr(str, "shadowtint=")))
879         {
880             i = parse_inline_number(p + strlen("shadowtint="));
881             j = (i > 0 ? 0 : 255);
882             i = ABS(i*255/100);
883
884             theme->title_focused_shadow_color = RrColorNew(inst, j, j, j);
885             theme->title_focused_shadow_alpha = i;
886             theme->osd_shadow_color = RrColorNew(inst, j, j, j);
887             theme->osd_shadow_alpha = i;
888         } else {
889             theme->title_focused_shadow_color = RrColorNew(inst, 0, 0, 0);
890             theme->title_focused_shadow_alpha = 50;
891             theme->osd_shadow_color = RrColorNew(inst, 0, 0, 0);
892             theme->osd_shadow_alpha = 50;
893         }
894     } else {
895         /* inherit the font settings from the focused label */
896         theme->osd_hilite_label->texture[0].data.text.shadow_offset_x =
897             theme->a_focused_label->texture[0].data.text.shadow_offset_x;
898         theme->osd_hilite_label->texture[0].data.text.shadow_offset_y =
899             theme->a_focused_label->texture[0].data.text.shadow_offset_y;
900         if (theme->title_focused_shadow_color)
901             theme->osd_shadow_color =
902                 RrColorNew(inst,
903                            theme->title_focused_shadow_color->r,
904                            theme->title_focused_shadow_color->g,
905                            theme->title_focused_shadow_color->b);
906         else
907             theme->osd_shadow_color = RrColorNew(inst, 0, 0, 0);
908         theme->osd_shadow_alpha = theme->title_focused_shadow_alpha;
909     }
910
911     theme->osd_hilite_label->texture[0].data.text.shadow_color =
912         theme->osd_shadow_color;
913     theme->osd_hilite_label->texture[0].data.text.shadow_alpha =
914         theme->osd_shadow_alpha;
915
916     theme->a_unfocused_label->texture[0].type = RR_TEXTURE_TEXT;
917     theme->a_unfocused_label->texture[0].data.text.justify = winjust;
918     theme->a_unfocused_label->texture[0].data.text.font =
919         theme->win_font_unfocused;
920     theme->a_unfocused_label->texture[0].data.text.color =
921         theme->title_unfocused_color;
922
923     if (read_string(db, "window.inactive.label.text.font", &str)) {
924         char *p;
925         gint i = 0;
926         gint j;
927         if (strstr(str, "shadow=y")) {
928             if ((p = strstr(str, "shadowoffset=")))
929                 i = parse_inline_number(p + strlen("shadowoffset="));
930             else
931                 i = 1;
932             theme->a_unfocused_label->texture[0].data.text.shadow_offset_x = i;
933             theme->a_unfocused_label->texture[0].data.text.shadow_offset_y = i;
934         }
935         if ((p = strstr(str, "shadowtint=")))
936         {
937             i = parse_inline_number(p + strlen("shadowtint="));
938             j = (i > 0 ? 0 : 255);
939             i = ABS(i*255/100);
940
941             theme->title_unfocused_shadow_color = RrColorNew(inst, j, j, j);
942             theme->title_unfocused_shadow_alpha = i;
943         } else {
944             theme->title_unfocused_shadow_color = RrColorNew(inst, 0, 0, 0);
945             theme->title_unfocused_shadow_alpha = 50;
946         }
947     }
948
949     theme->a_unfocused_label->texture[0].data.text.shadow_color =
950         theme->title_unfocused_shadow_color;
951     theme->a_unfocused_label->texture[0].data.text.shadow_alpha =
952         theme->title_unfocused_shadow_alpha;
953
954     theme->a_menu_text_title->texture[0].type = RR_TEXTURE_TEXT;
955     theme->a_menu_text_title->texture[0].data.text.justify = mtitlejust;
956     theme->a_menu_text_title->texture[0].data.text.font =
957         theme->menu_title_font;
958     theme->a_menu_text_title->texture[0].data.text.color =
959         theme->menu_title_color;
960
961     if (read_string(db, "menu.title.text.font", &str)) {
962         char *p;
963         gint i = 0;
964         gint j;
965         if (strstr(str, "shadow=y")) {
966             if ((p = strstr(str, "shadowoffset=")))
967                 i = parse_inline_number(p + strlen("shadowoffset="));
968             else
969                 i = 1;
970             theme->a_menu_text_title->texture[0].data.text.shadow_offset_x = i;
971             theme->a_menu_text_title->texture[0].data.text.shadow_offset_y = i;
972         }
973         if ((p = strstr(str, "shadowtint=")))
974         {
975             i = parse_inline_number(p + strlen("shadowtint="));
976             j = (i > 0 ? 0 : 255);
977             i = ABS(i*255/100);
978
979             theme->menu_title_shadow_color = RrColorNew(inst, j, j, j);
980             theme->menu_title_shadow_alpha = i;
981         } else {
982             theme->menu_title_shadow_color = RrColorNew(inst, 0, 0, 0);
983             theme->menu_title_shadow_alpha = 50;
984         }
985     }
986
987     theme->a_menu_text_title->texture[0].data.text.shadow_color =
988         theme->menu_title_shadow_color;
989     theme->a_menu_text_title->texture[0].data.text.shadow_alpha =
990         theme->menu_title_shadow_alpha;
991
992     theme->a_menu_text_normal->texture[0].type =
993         theme->a_menu_text_selected->texture[0].type =
994         theme->a_menu_text_disabled->texture[0].type =
995         theme->a_menu_text_disabled_selected->texture[0].type =
996         RR_TEXTURE_TEXT;
997     theme->a_menu_text_normal->texture[0].data.text.justify =
998         theme->a_menu_text_selected->texture[0].data.text.justify =
999         theme->a_menu_text_disabled->texture[0].data.text.justify =
1000         theme->a_menu_text_disabled_selected->texture[0].data.text.justify =
1001         RR_JUSTIFY_LEFT;
1002     theme->a_menu_text_normal->texture[0].data.text.font =
1003         theme->a_menu_text_selected->texture[0].data.text.font =
1004         theme->a_menu_text_disabled->texture[0].data.text.font =
1005         theme->a_menu_text_disabled_selected->texture[0].data.text.font =
1006         theme->menu_font;
1007     theme->a_menu_text_normal->texture[0].data.text.color = theme->menu_color;
1008     theme->a_menu_text_selected->texture[0].data.text.color =
1009         theme->menu_selected_color;
1010     theme->a_menu_text_disabled->texture[0].data.text.color =
1011         theme->menu_disabled_color;
1012     theme->a_menu_text_disabled_selected->texture[0].data.text.color =
1013         theme->menu_disabled_selected_color;
1014
1015     if (read_string(db, "menu.items.font", &str)) {
1016         char *p;
1017         gint i = 0;
1018         gint j;
1019         if (strstr(str, "shadow=y")) {
1020             if ((p = strstr(str, "shadowoffset=")))
1021                 i = parse_inline_number(p + strlen("shadowoffset="));
1022             else
1023                 i = 1;
1024             theme->a_menu_text_normal->
1025                 texture[0].data.text.shadow_offset_x = i;
1026             theme->a_menu_text_normal->
1027                 texture[0].data.text.shadow_offset_y = i;
1028             theme->a_menu_text_selected->
1029                 texture[0].data.text.shadow_offset_x = i;
1030             theme->a_menu_text_selected->
1031                 texture[0].data.text.shadow_offset_y = i;
1032             theme->a_menu_text_disabled->
1033                 texture[0].data.text.shadow_offset_x = i;
1034             theme->a_menu_text_disabled->
1035                 texture[0].data.text.shadow_offset_y = i;
1036             theme->a_menu_text_disabled_selected->
1037                 texture[0].data.text.shadow_offset_x = i;
1038             theme->a_menu_text_disabled_selected->
1039                 texture[0].data.text.shadow_offset_y = i;
1040         }
1041         if ((p = strstr(str, "shadowtint=")))
1042         {
1043             i = parse_inline_number(p + strlen("shadowtint="));
1044             j = (i > 0 ? 0 : 255);
1045             i = ABS(i*255/100);
1046
1047             theme->menu_text_normal_shadow_color = RrColorNew(inst, j, j, j);
1048             theme->menu_text_selected_shadow_color = RrColorNew(inst, j, j, j);
1049             theme->menu_text_disabled_shadow_color = RrColorNew(inst, j, j, j);
1050             theme->menu_text_normal_shadow_alpha = i;
1051             theme->menu_text_selected_shadow_alpha = i;
1052             theme->menu_text_disabled_shadow_alpha = i;
1053             theme->menu_text_disabled_selected_shadow_alpha = i;
1054         } else {
1055             theme->menu_text_normal_shadow_color = RrColorNew(inst, 0, 0, 0);
1056             theme->menu_text_selected_shadow_color = RrColorNew(inst, 0, 0, 0);
1057             theme->menu_text_disabled_shadow_color = RrColorNew(inst, 0, 0, 0);
1058             theme->menu_text_normal_shadow_alpha = 50;
1059             theme->menu_text_selected_shadow_alpha = 50;
1060             theme->menu_text_disabled_selected_shadow_alpha = 50;
1061         }
1062     }
1063
1064     theme->a_menu_text_normal->texture[0].data.text.shadow_color =
1065         theme->menu_text_normal_shadow_color;
1066     theme->a_menu_text_normal->texture[0].data.text.shadow_alpha =
1067         theme->menu_text_normal_shadow_alpha;
1068     theme->a_menu_text_selected->texture[0].data.text.shadow_color =
1069         theme->menu_text_selected_shadow_color;
1070     theme->a_menu_text_selected->texture[0].data.text.shadow_alpha =
1071         theme->menu_text_selected_shadow_alpha;
1072     theme->a_menu_text_disabled->texture[0].data.text.shadow_color =
1073         theme->menu_text_disabled_shadow_color;
1074     theme->a_menu_text_disabled->texture[0].data.text.shadow_alpha =
1075         theme->menu_text_disabled_shadow_alpha;
1076     theme->a_menu_text_disabled_selected->texture[0].data.text.shadow_color =
1077         theme->menu_text_disabled_shadow_color;
1078     theme->a_menu_text_disabled_selected->texture[0].data.text.shadow_alpha =
1079         theme->menu_text_disabled_shadow_alpha;
1080
1081     theme->a_disabled_focused_max->texture[0].type =
1082         theme->a_disabled_unfocused_max->texture[0].type =
1083         theme->a_hover_focused_max->texture[0].type =
1084         theme->a_hover_unfocused_max->texture[0].type =
1085         theme->a_toggled_hover_focused_max->texture[0].type =
1086         theme->a_toggled_hover_unfocused_max->texture[0].type =
1087         theme->a_toggled_focused_unpressed_max->texture[0].type =
1088         theme->a_toggled_unfocused_unpressed_max->texture[0].type =
1089         theme->a_toggled_focused_pressed_max->texture[0].type =
1090         theme->a_toggled_unfocused_pressed_max->texture[0].type =
1091         theme->a_focused_unpressed_max->texture[0].type =
1092         theme->a_focused_pressed_max->texture[0].type =
1093         theme->a_unfocused_unpressed_max->texture[0].type =
1094         theme->a_unfocused_pressed_max->texture[0].type =
1095         theme->a_disabled_focused_close->texture[0].type =
1096         theme->a_disabled_unfocused_close->texture[0].type =
1097         theme->a_hover_focused_close->texture[0].type =
1098         theme->a_hover_unfocused_close->texture[0].type =
1099         theme->a_focused_unpressed_close->texture[0].type =
1100         theme->a_focused_pressed_close->texture[0].type =
1101         theme->a_unfocused_unpressed_close->texture[0].type =
1102         theme->a_unfocused_pressed_close->texture[0].type =
1103         theme->a_disabled_focused_desk->texture[0].type =
1104         theme->a_disabled_unfocused_desk->texture[0].type =
1105         theme->a_hover_focused_desk->texture[0].type =
1106         theme->a_hover_unfocused_desk->texture[0].type =
1107         theme->a_toggled_hover_focused_desk->texture[0].type =
1108         theme->a_toggled_hover_unfocused_desk->texture[0].type =
1109         theme->a_toggled_focused_unpressed_desk->texture[0].type =
1110         theme->a_toggled_unfocused_unpressed_desk->texture[0].type =
1111         theme->a_toggled_focused_pressed_desk->texture[0].type =
1112         theme->a_toggled_unfocused_pressed_desk->texture[0].type =
1113         theme->a_focused_unpressed_desk->texture[0].type =
1114         theme->a_focused_pressed_desk->texture[0].type =
1115         theme->a_unfocused_unpressed_desk->texture[0].type =
1116         theme->a_unfocused_pressed_desk->texture[0].type =
1117         theme->a_disabled_focused_shade->texture[0].type =
1118         theme->a_disabled_unfocused_shade->texture[0].type =
1119         theme->a_hover_focused_shade->texture[0].type =
1120         theme->a_hover_unfocused_shade->texture[0].type =
1121         theme->a_toggled_hover_focused_shade->texture[0].type =
1122         theme->a_toggled_hover_unfocused_shade->texture[0].type =
1123         theme->a_toggled_focused_unpressed_shade->texture[0].type =
1124         theme->a_toggled_unfocused_unpressed_shade->texture[0].type =
1125         theme->a_toggled_focused_pressed_shade->texture[0].type =
1126         theme->a_toggled_unfocused_pressed_shade->texture[0].type =
1127         theme->a_focused_unpressed_shade->texture[0].type =
1128         theme->a_focused_pressed_shade->texture[0].type =
1129         theme->a_unfocused_unpressed_shade->texture[0].type =
1130         theme->a_unfocused_pressed_shade->texture[0].type =
1131         theme->a_disabled_focused_iconify->texture[0].type =
1132         theme->a_disabled_unfocused_iconify->texture[0].type =
1133         theme->a_hover_focused_iconify->texture[0].type =
1134         theme->a_hover_unfocused_iconify->texture[0].type =
1135         theme->a_focused_unpressed_iconify->texture[0].type =
1136         theme->a_focused_pressed_iconify->texture[0].type =
1137         theme->a_unfocused_unpressed_iconify->texture[0].type =
1138         theme->a_unfocused_pressed_iconify->texture[0].type =
1139         theme->a_menu_bullet_normal->texture[0].type =
1140         theme->a_menu_bullet_selected->texture[0].type = RR_TEXTURE_MASK;
1141
1142     theme->a_disabled_focused_max->texture[0].data.mask.mask =
1143         theme->a_disabled_unfocused_max->texture[0].data.mask.mask =
1144         theme->max_disabled_mask;
1145     theme->a_hover_focused_max->texture[0].data.mask.mask =
1146         theme->a_hover_unfocused_max->texture[0].data.mask.mask =
1147         theme->max_hover_mask;
1148     theme->a_focused_pressed_max->texture[0].data.mask.mask =
1149         theme->a_unfocused_pressed_max->texture[0].data.mask.mask =
1150         theme->max_pressed_mask;
1151     theme->a_focused_unpressed_max->texture[0].data.mask.mask =
1152         theme->a_unfocused_unpressed_max->texture[0].data.mask.mask =
1153         theme->max_mask;
1154     theme->a_toggled_hover_focused_max->texture[0].data.mask.mask =
1155         theme->a_toggled_hover_unfocused_max->texture[0].data.mask.mask =
1156         theme->max_toggled_hover_mask;
1157     theme->a_toggled_focused_unpressed_max->texture[0].data.mask.mask =
1158         theme->a_toggled_unfocused_unpressed_max->texture[0].data.mask.mask =
1159         theme->max_toggled_mask;
1160     theme->a_toggled_focused_pressed_max->texture[0].data.mask.mask =
1161         theme->a_toggled_unfocused_pressed_max->texture[0].data.mask.mask =
1162         theme->max_toggled_pressed_mask;
1163     theme->a_disabled_focused_close->texture[0].data.mask.mask =
1164         theme->a_disabled_unfocused_close->texture[0].data.mask.mask =
1165         theme->close_disabled_mask;
1166     theme->a_hover_focused_close->texture[0].data.mask.mask =
1167         theme->a_hover_unfocused_close->texture[0].data.mask.mask =
1168         theme->close_hover_mask;
1169     theme->a_focused_pressed_close->texture[0].data.mask.mask =
1170         theme->a_unfocused_pressed_close->texture[0].data.mask.mask =
1171         theme->close_pressed_mask;
1172     theme->a_focused_unpressed_close->texture[0].data.mask.mask =
1173         theme->a_unfocused_unpressed_close->texture[0].data.mask.mask =
1174         theme->close_mask;
1175     theme->a_disabled_focused_desk->texture[0].data.mask.mask =
1176         theme->a_disabled_unfocused_desk->texture[0].data.mask.mask =
1177         theme->desk_disabled_mask;
1178     theme->a_hover_focused_desk->texture[0].data.mask.mask =
1179         theme->a_hover_unfocused_desk->texture[0].data.mask.mask =
1180         theme->desk_hover_mask;
1181     theme->a_focused_pressed_desk->texture[0].data.mask.mask =
1182         theme->a_unfocused_pressed_desk->texture[0].data.mask.mask =
1183         theme->desk_pressed_mask;
1184     theme->a_focused_unpressed_desk->texture[0].data.mask.mask =
1185         theme->a_unfocused_unpressed_desk->texture[0].data.mask.mask =
1186         theme->desk_mask;
1187     theme->a_toggled_hover_focused_desk->texture[0].data.mask.mask =
1188         theme->a_toggled_hover_unfocused_desk->texture[0].data.mask.mask =
1189         theme->desk_toggled_hover_mask;
1190     theme->a_toggled_focused_unpressed_desk->texture[0].data.mask.mask =
1191         theme->a_toggled_unfocused_unpressed_desk->texture[0].data.mask.mask =
1192         theme->desk_toggled_mask;
1193     theme->a_toggled_focused_pressed_desk->texture[0].data.mask.mask =
1194         theme->a_toggled_unfocused_pressed_desk->texture[0].data.mask.mask =
1195         theme->desk_toggled_pressed_mask;
1196     theme->a_disabled_focused_shade->texture[0].data.mask.mask =
1197         theme->a_disabled_unfocused_shade->texture[0].data.mask.mask =
1198         theme->shade_disabled_mask;
1199     theme->a_hover_focused_shade->texture[0].data.mask.mask =
1200         theme->a_hover_unfocused_shade->texture[0].data.mask.mask =
1201         theme->shade_hover_mask;
1202     theme->a_focused_pressed_shade->texture[0].data.mask.mask =
1203         theme->a_unfocused_pressed_shade->texture[0].data.mask.mask =
1204         theme->shade_pressed_mask;
1205     theme->a_focused_unpressed_shade->texture[0].data.mask.mask =
1206         theme->a_unfocused_unpressed_shade->texture[0].data.mask.mask =
1207         theme->shade_mask;
1208     theme->a_toggled_hover_focused_shade->texture[0].data.mask.mask =
1209         theme->a_toggled_hover_unfocused_shade->texture[0].data.mask.mask =
1210         theme->shade_toggled_hover_mask;
1211     theme->a_toggled_focused_unpressed_shade->texture[0].data.mask.mask =
1212         theme->a_toggled_unfocused_unpressed_shade->texture[0].data.mask.mask =
1213         theme->shade_toggled_mask;
1214     theme->a_toggled_focused_pressed_shade->texture[0].data.mask.mask =
1215         theme->a_toggled_unfocused_pressed_shade->texture[0].data.mask.mask =
1216         theme->shade_toggled_pressed_mask;
1217     theme->a_disabled_focused_iconify->texture[0].data.mask.mask =
1218         theme->a_disabled_unfocused_iconify->texture[0].data.mask.mask =
1219         theme->iconify_disabled_mask;
1220     theme->a_hover_focused_iconify->texture[0].data.mask.mask =
1221         theme->a_hover_unfocused_iconify->texture[0].data.mask.mask =
1222         theme->iconify_hover_mask;
1223     theme->a_focused_pressed_iconify->texture[0].data.mask.mask =
1224         theme->a_unfocused_pressed_iconify->texture[0].data.mask.mask =
1225         theme->iconify_pressed_mask;
1226     theme->a_focused_unpressed_iconify->texture[0].data.mask.mask =
1227         theme->a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
1228         theme->iconify_mask;
1229     theme->a_menu_bullet_normal->texture[0].data.mask.mask =
1230     theme->a_menu_bullet_selected->texture[0].data.mask.mask =
1231         theme->menu_bullet_mask;
1232     theme->a_disabled_focused_max->texture[0].data.mask.color =
1233         theme->a_disabled_focused_close->texture[0].data.mask.color =
1234         theme->a_disabled_focused_desk->texture[0].data.mask.color =
1235         theme->a_disabled_focused_shade->texture[0].data.mask.color =
1236         theme->a_disabled_focused_iconify->texture[0].data.mask.color =
1237         theme->titlebut_disabled_focused_color;
1238     theme->a_disabled_unfocused_max->texture[0].data.mask.color =
1239         theme->a_disabled_unfocused_close->texture[0].data.mask.color =
1240         theme->a_disabled_unfocused_desk->texture[0].data.mask.color =
1241         theme->a_disabled_unfocused_shade->texture[0].data.mask.color =
1242         theme->a_disabled_unfocused_iconify->texture[0].data.mask.color =
1243         theme->titlebut_disabled_unfocused_color;
1244     theme->a_hover_focused_max->texture[0].data.mask.color =
1245         theme->a_hover_focused_close->texture[0].data.mask.color =
1246         theme->a_hover_focused_desk->texture[0].data.mask.color =
1247         theme->a_hover_focused_shade->texture[0].data.mask.color =
1248         theme->a_hover_focused_iconify->texture[0].data.mask.color =
1249         theme->titlebut_hover_focused_color;
1250     theme->a_hover_unfocused_max->texture[0].data.mask.color =
1251         theme->a_hover_unfocused_close->texture[0].data.mask.color =
1252         theme->a_hover_unfocused_desk->texture[0].data.mask.color =
1253         theme->a_hover_unfocused_shade->texture[0].data.mask.color =
1254         theme->a_hover_unfocused_iconify->texture[0].data.mask.color =
1255         theme->titlebut_hover_unfocused_color;
1256     theme->a_toggled_hover_focused_max->texture[0].data.mask.color =
1257         theme->a_toggled_hover_focused_desk->texture[0].data.mask.color =
1258         theme->a_toggled_hover_focused_shade->texture[0].data.mask.color =
1259         theme->titlebut_toggled_hover_focused_color;
1260     theme->a_toggled_hover_unfocused_max->texture[0].data.mask.color =
1261         theme->a_toggled_hover_unfocused_desk->texture[0].data.mask.color =
1262         theme->a_toggled_hover_unfocused_shade->texture[0].data.mask.color =
1263         theme->titlebut_toggled_hover_unfocused_color;
1264     theme->a_toggled_focused_unpressed_max->texture[0].data.mask.color =
1265         theme->a_toggled_focused_unpressed_desk->texture[0].data.mask.color =
1266         theme->a_toggled_focused_unpressed_shade->texture[0].data.mask.color =
1267         theme->titlebut_toggled_focused_unpressed_color;
1268     theme->a_toggled_unfocused_unpressed_max->texture[0].data.mask.color =
1269         theme->a_toggled_unfocused_unpressed_desk->texture[0].data.mask.color =
1270         theme->a_toggled_unfocused_unpressed_shade->texture[0].data.mask.color=
1271         theme->titlebut_toggled_unfocused_unpressed_color;
1272     theme->a_toggled_focused_pressed_max->texture[0].data.mask.color =
1273         theme->a_toggled_focused_pressed_desk->texture[0].data.mask.color =
1274         theme->a_toggled_focused_pressed_shade->texture[0].data.mask.color =
1275         theme->titlebut_toggled_focused_pressed_color;
1276     theme->a_toggled_unfocused_pressed_max->texture[0].data.mask.color =
1277         theme->a_toggled_unfocused_pressed_desk->texture[0].data.mask.color =
1278         theme->a_toggled_unfocused_pressed_shade->texture[0].data.mask.color =
1279         theme->titlebut_toggled_unfocused_pressed_color;
1280     theme->a_focused_unpressed_max->texture[0].data.mask.color =
1281         theme->a_focused_unpressed_close->texture[0].data.mask.color =
1282         theme->a_focused_unpressed_desk->texture[0].data.mask.color =
1283         theme->a_focused_unpressed_shade->texture[0].data.mask.color =
1284         theme->a_focused_unpressed_iconify->texture[0].data.mask.color =
1285         theme->titlebut_focused_unpressed_color;
1286     theme->a_focused_pressed_max->texture[0].data.mask.color =
1287         theme->a_focused_pressed_close->texture[0].data.mask.color =
1288         theme->a_focused_pressed_desk->texture[0].data.mask.color =
1289         theme->a_focused_pressed_shade->texture[0].data.mask.color =
1290         theme->a_focused_pressed_iconify->texture[0].data.mask.color =
1291         theme->titlebut_focused_pressed_color;
1292     theme->a_unfocused_unpressed_max->texture[0].data.mask.color =
1293         theme->a_unfocused_unpressed_close->texture[0].data.mask.color =
1294         theme->a_unfocused_unpressed_desk->texture[0].data.mask.color =
1295         theme->a_unfocused_unpressed_shade->texture[0].data.mask.color =
1296         theme->a_unfocused_unpressed_iconify->texture[0].data.mask.color =
1297         theme->titlebut_unfocused_unpressed_color;
1298     theme->a_unfocused_pressed_max->texture[0].data.mask.color =
1299         theme->a_unfocused_pressed_close->texture[0].data.mask.color =
1300         theme->a_unfocused_pressed_desk->texture[0].data.mask.color =
1301         theme->a_unfocused_pressed_shade->texture[0].data.mask.color =
1302         theme->a_unfocused_pressed_iconify->texture[0].data.mask.color =
1303         theme->titlebut_unfocused_pressed_color;
1304     theme->a_menu_bullet_normal->texture[0].data.mask.color =
1305         theme->menu_color;
1306     theme->a_menu_bullet_selected->texture[0].data.mask.color =
1307         theme->menu_selected_color;
1308
1309     g_free(path);
1310     XrmDestroyDatabase(db);
1311
1312     /* set the font heights */
1313     theme->win_font_height = RrFontHeight
1314         (theme->win_font_focused,
1315          theme->a_focused_label->texture[0].data.text.shadow_offset_y);
1316     theme->win_font_height =
1317         MAX(theme->win_font_height,
1318             RrFontHeight
1319             (theme->win_font_focused,
1320              theme->a_unfocused_label->texture[0].data.text.shadow_offset_y));
1321     theme->menu_title_font_height = RrFontHeight
1322         (theme->menu_title_font,
1323          theme->a_menu_text_title->texture[0].data.text.shadow_offset_y);
1324     theme->menu_font_height = RrFontHeight
1325         (theme->menu_font,
1326          theme->a_menu_text_normal->texture[0].data.text.shadow_offset_y);
1327
1328     /* calculate some last extents */
1329     {
1330         gint ft, fb, fl, fr, ut, ub, ul, ur;
1331
1332         RrMargins(theme->a_focused_label, &fl, &ft, &fr, &fb);
1333         RrMargins(theme->a_unfocused_label, &ul, &ut, &ur, &ub);
1334         theme->label_height = theme->win_font_height + MAX(ft + fb, ut + ub);
1335         theme->label_height += theme->label_height % 2;
1336
1337         /* this would be nice I think, since padding.width can now be 0,
1338            but it breaks frame.c horribly and I don't feel like fixing that
1339            right now, so if anyone complains, here is how to keep text from
1340            going over the title's bevel/border with a padding.width of 0 and a
1341            bevelless/borderless label
1342            RrMargins(theme->a_focused_title, &fl, &ft, &fr, &fb);
1343            RrMargins(theme->a_unfocused_title, &ul, &ut, &ur, &ub);
1344            theme->title_height = theme->label_height +
1345            MAX(MAX(theme->padding * 2, ft + fb),
1346            MAX(theme->padding * 2, ut + ub));
1347         */
1348         theme->title_height = theme->label_height + theme->paddingy * 2;
1349
1350         RrMargins(theme->a_menu_title, &ul, &ut, &ur, &ub);
1351         theme->menu_title_label_height = theme->menu_title_font_height+ut+ub;
1352         theme->menu_title_height = theme->menu_title_label_height +
1353             theme->paddingy * 2;
1354     }
1355     theme->button_size = theme->label_height - 2;
1356     theme->grip_width = 25;
1357
1358     RrAppearanceFree(a_disabled_focused_tmp);
1359     RrAppearanceFree(a_disabled_unfocused_tmp);
1360     RrAppearanceFree(a_hover_focused_tmp);
1361     RrAppearanceFree(a_hover_unfocused_tmp);
1362     RrAppearanceFree(a_focused_unpressed_tmp);
1363     RrAppearanceFree(a_focused_pressed_tmp);
1364     RrAppearanceFree(a_unfocused_unpressed_tmp);
1365     RrAppearanceFree(a_unfocused_pressed_tmp);
1366     RrAppearanceFree(a_toggled_hover_focused_tmp);
1367     RrAppearanceFree(a_toggled_hover_unfocused_tmp);
1368     RrAppearanceFree(a_toggled_focused_unpressed_tmp);
1369     RrAppearanceFree(a_toggled_focused_pressed_tmp);
1370     RrAppearanceFree(a_toggled_unfocused_unpressed_tmp);
1371     RrAppearanceFree(a_toggled_unfocused_pressed_tmp);
1372
1373     return theme;
1374 }
1375
1376 void RrThemeFree(RrTheme *theme)
1377 {
1378     if (theme) {
1379         g_free(theme->name);
1380
1381         RrColorFree(theme->menu_border_color);
1382         RrColorFree(theme->osd_border_color);
1383         RrColorFree(theme->frame_focused_border_color);
1384         RrColorFree(theme->frame_unfocused_border_color);
1385         RrColorFree(theme->title_separator_focused_color);
1386         RrColorFree(theme->title_separator_unfocused_color);
1387         RrColorFree(theme->cb_unfocused_color);
1388         RrColorFree(theme->cb_focused_color);
1389         RrColorFree(theme->title_focused_color);
1390         RrColorFree(theme->title_unfocused_color);
1391         RrColorFree(theme->titlebut_disabled_focused_color);
1392         RrColorFree(theme->titlebut_disabled_unfocused_color);
1393         RrColorFree(theme->titlebut_hover_focused_color);
1394         RrColorFree(theme->titlebut_hover_unfocused_color);
1395         RrColorFree(theme->titlebut_toggled_hover_focused_color);
1396         RrColorFree(theme->titlebut_toggled_hover_unfocused_color);
1397         RrColorFree(theme->titlebut_toggled_focused_pressed_color);
1398         RrColorFree(theme->titlebut_toggled_unfocused_pressed_color);
1399         RrColorFree(theme->titlebut_toggled_focused_unpressed_color);
1400         RrColorFree(theme->titlebut_toggled_unfocused_unpressed_color);
1401         RrColorFree(theme->titlebut_focused_pressed_color);
1402         RrColorFree(theme->titlebut_unfocused_pressed_color);
1403         RrColorFree(theme->titlebut_focused_unpressed_color);
1404         RrColorFree(theme->titlebut_unfocused_unpressed_color);
1405         RrColorFree(theme->menu_title_color);
1406         RrColorFree(theme->menu_color);
1407         RrColorFree(theme->menu_selected_color);
1408         RrColorFree(theme->menu_disabled_color);
1409         RrColorFree(theme->menu_disabled_selected_color);
1410         RrColorFree(theme->title_focused_shadow_color);
1411         RrColorFree(theme->title_unfocused_shadow_color);
1412         RrColorFree(theme->osd_color);
1413         RrColorFree(theme->osd_shadow_color);
1414         RrColorFree(theme->menu_title_shadow_color);
1415         RrColorFree(theme->menu_text_normal_shadow_color);
1416         RrColorFree(theme->menu_text_selected_shadow_color);
1417         RrColorFree(theme->menu_text_disabled_shadow_color);
1418         RrColorFree(theme->menu_text_disabled_selected_shadow_color);
1419
1420         g_free(theme->def_win_icon);
1421
1422         RrPixmapMaskFree(theme->max_mask);
1423         RrPixmapMaskFree(theme->max_toggled_mask);
1424         RrPixmapMaskFree(theme->max_toggled_hover_mask);
1425         RrPixmapMaskFree(theme->max_toggled_pressed_mask);
1426         RrPixmapMaskFree(theme->max_disabled_mask);
1427         RrPixmapMaskFree(theme->max_hover_mask);
1428         RrPixmapMaskFree(theme->max_pressed_mask);
1429         RrPixmapMaskFree(theme->desk_mask);
1430         RrPixmapMaskFree(theme->desk_toggled_mask);
1431         RrPixmapMaskFree(theme->desk_toggled_hover_mask);
1432         RrPixmapMaskFree(theme->desk_toggled_pressed_mask);
1433         RrPixmapMaskFree(theme->desk_disabled_mask);
1434         RrPixmapMaskFree(theme->desk_hover_mask);
1435         RrPixmapMaskFree(theme->desk_pressed_mask);
1436         RrPixmapMaskFree(theme->shade_mask);
1437         RrPixmapMaskFree(theme->shade_toggled_mask);
1438         RrPixmapMaskFree(theme->shade_toggled_hover_mask);
1439         RrPixmapMaskFree(theme->shade_toggled_pressed_mask);
1440         RrPixmapMaskFree(theme->shade_disabled_mask);
1441         RrPixmapMaskFree(theme->shade_hover_mask);
1442         RrPixmapMaskFree(theme->shade_pressed_mask);
1443         RrPixmapMaskFree(theme->iconify_mask);
1444         RrPixmapMaskFree(theme->iconify_disabled_mask);
1445         RrPixmapMaskFree(theme->iconify_hover_mask);
1446         RrPixmapMaskFree(theme->iconify_pressed_mask);
1447         RrPixmapMaskFree(theme->close_mask);
1448         RrPixmapMaskFree(theme->close_disabled_mask);
1449         RrPixmapMaskFree(theme->close_hover_mask);
1450         RrPixmapMaskFree(theme->close_pressed_mask);
1451         RrPixmapMaskFree(theme->menu_bullet_mask);
1452
1453         RrFontClose(theme->win_font_focused);
1454         RrFontClose(theme->win_font_unfocused);
1455         RrFontClose(theme->menu_title_font);
1456         RrFontClose(theme->menu_font);
1457
1458         RrAppearanceFree(theme->a_disabled_focused_max);
1459         RrAppearanceFree(theme->a_disabled_unfocused_max);
1460         RrAppearanceFree(theme->a_hover_focused_max);
1461         RrAppearanceFree(theme->a_hover_unfocused_max);
1462         RrAppearanceFree(theme->a_toggled_hover_focused_max);
1463         RrAppearanceFree(theme->a_toggled_hover_unfocused_max);
1464         RrAppearanceFree(theme->a_toggled_focused_unpressed_max);
1465         RrAppearanceFree(theme->a_toggled_focused_pressed_max);
1466         RrAppearanceFree(theme->a_toggled_unfocused_unpressed_max);
1467         RrAppearanceFree(theme->a_toggled_unfocused_pressed_max);
1468         RrAppearanceFree(theme->a_focused_unpressed_max);
1469         RrAppearanceFree(theme->a_focused_pressed_max);
1470         RrAppearanceFree(theme->a_unfocused_unpressed_max);
1471         RrAppearanceFree(theme->a_unfocused_pressed_max);
1472         RrAppearanceFree(theme->a_disabled_focused_close);
1473         RrAppearanceFree(theme->a_disabled_unfocused_close);
1474         RrAppearanceFree(theme->a_hover_focused_close);
1475         RrAppearanceFree(theme->a_hover_unfocused_close);
1476         RrAppearanceFree(theme->a_focused_unpressed_close);
1477         RrAppearanceFree(theme->a_focused_pressed_close);
1478         RrAppearanceFree(theme->a_unfocused_unpressed_close);
1479         RrAppearanceFree(theme->a_unfocused_pressed_close);
1480         RrAppearanceFree(theme->a_disabled_focused_desk);
1481         RrAppearanceFree(theme->a_disabled_unfocused_desk);
1482         RrAppearanceFree(theme->a_hover_focused_desk);
1483         RrAppearanceFree(theme->a_hover_unfocused_desk);
1484         RrAppearanceFree(theme->a_toggled_hover_focused_desk);
1485         RrAppearanceFree(theme->a_toggled_hover_unfocused_desk);
1486         RrAppearanceFree(theme->a_toggled_focused_unpressed_desk);
1487         RrAppearanceFree(theme->a_toggled_focused_pressed_desk);
1488         RrAppearanceFree(theme->a_toggled_unfocused_unpressed_desk);
1489         RrAppearanceFree(theme->a_toggled_unfocused_pressed_desk);
1490         RrAppearanceFree(theme->a_focused_unpressed_desk);
1491         RrAppearanceFree(theme->a_focused_pressed_desk);
1492         RrAppearanceFree(theme->a_unfocused_unpressed_desk);
1493         RrAppearanceFree(theme->a_unfocused_pressed_desk);
1494         RrAppearanceFree(theme->a_disabled_focused_shade);
1495         RrAppearanceFree(theme->a_disabled_unfocused_shade);
1496         RrAppearanceFree(theme->a_hover_focused_shade);
1497         RrAppearanceFree(theme->a_hover_unfocused_shade);
1498         RrAppearanceFree(theme->a_toggled_hover_focused_shade);
1499         RrAppearanceFree(theme->a_toggled_hover_unfocused_shade);
1500         RrAppearanceFree(theme->a_toggled_focused_unpressed_shade);
1501         RrAppearanceFree(theme->a_toggled_focused_pressed_shade);
1502         RrAppearanceFree(theme->a_toggled_unfocused_unpressed_shade);
1503         RrAppearanceFree(theme->a_toggled_unfocused_pressed_shade);
1504         RrAppearanceFree(theme->a_focused_unpressed_shade);
1505         RrAppearanceFree(theme->a_focused_pressed_shade);
1506         RrAppearanceFree(theme->a_unfocused_unpressed_shade);
1507         RrAppearanceFree(theme->a_unfocused_pressed_shade);
1508         RrAppearanceFree(theme->a_disabled_focused_iconify);
1509         RrAppearanceFree(theme->a_disabled_unfocused_iconify);
1510         RrAppearanceFree(theme->a_hover_focused_iconify);
1511         RrAppearanceFree(theme->a_hover_unfocused_iconify);
1512         RrAppearanceFree(theme->a_focused_unpressed_iconify);
1513         RrAppearanceFree(theme->a_focused_pressed_iconify);
1514         RrAppearanceFree(theme->a_unfocused_unpressed_iconify);
1515         RrAppearanceFree(theme->a_unfocused_pressed_iconify);
1516         RrAppearanceFree(theme->a_focused_grip);
1517         RrAppearanceFree(theme->a_unfocused_grip);
1518         RrAppearanceFree(theme->a_focused_title);
1519         RrAppearanceFree(theme->a_unfocused_title);
1520         RrAppearanceFree(theme->a_focused_label);
1521         RrAppearanceFree(theme->a_unfocused_label);
1522         RrAppearanceFree(theme->a_icon);
1523         RrAppearanceFree(theme->a_focused_handle);
1524         RrAppearanceFree(theme->a_unfocused_handle);
1525         RrAppearanceFree(theme->a_menu);
1526         RrAppearanceFree(theme->a_menu_title);
1527         RrAppearanceFree(theme->a_menu_text_title);
1528         RrAppearanceFree(theme->a_menu_normal);
1529         RrAppearanceFree(theme->a_menu_selected);
1530         RrAppearanceFree(theme->a_menu_disabled);
1531         RrAppearanceFree(theme->a_menu_disabled_selected);
1532         RrAppearanceFree(theme->a_menu_text_normal);
1533         RrAppearanceFree(theme->a_menu_text_selected);
1534         RrAppearanceFree(theme->a_menu_text_disabled);
1535         RrAppearanceFree(theme->a_menu_text_disabled_selected);
1536         RrAppearanceFree(theme->a_menu_bullet_normal);
1537         RrAppearanceFree(theme->a_menu_bullet_selected);
1538         RrAppearanceFree(theme->a_clear);
1539         RrAppearanceFree(theme->a_clear_tex);
1540         RrAppearanceFree(theme->osd_hilite_bg);
1541         RrAppearanceFree(theme->osd_hilite_fg);
1542         RrAppearanceFree(theme->osd_hilite_label);
1543         RrAppearanceFree(theme->osd_unhilite_fg);
1544
1545         g_free(theme);
1546     }
1547 }
1548
1549 static XrmDatabase loaddb(const gchar *name, gchar **path)
1550 {
1551     GSList *it;
1552     XrmDatabase db = NULL;
1553     gchar *s;
1554
1555     if (name[0] == '/') {
1556         s = g_build_filename(name, "openbox-3", "themerc", NULL);
1557         if ((db = XrmGetFileDatabase(s)))
1558             *path = g_path_get_dirname(s);
1559         g_free(s);
1560     } else {
1561         /* XXX backwards compatibility, remove me sometime later */
1562         s = g_build_filename(g_get_home_dir(), ".themes", name,
1563                              "openbox-3", "themerc", NULL);
1564         if ((db = XrmGetFileDatabase(s)))
1565             *path = g_path_get_dirname(s);
1566         g_free(s);
1567
1568         for (it = parse_xdg_data_dir_paths(); !db && it;
1569              it = g_slist_next(it))
1570         {
1571             s = g_build_filename(it->data, "themes", name,
1572                                  "openbox-3", "themerc", NULL);
1573             if ((db = XrmGetFileDatabase(s)))
1574                 *path = g_path_get_dirname(s);
1575             g_free(s);
1576         }
1577     }
1578
1579     if (db == NULL) {
1580         s = g_build_filename(name, "themerc", NULL);
1581         if ((db = XrmGetFileDatabase(s)))
1582             *path = g_path_get_dirname(s);
1583         g_free(s);
1584     }
1585
1586     return db;
1587 }
1588
1589 static gchar *create_class_name(const gchar *rname)
1590 {
1591     gchar *rclass = g_strdup(rname);
1592     gchar *p = rclass;
1593
1594     while (TRUE) {
1595         *p = toupper(*p);
1596         p = strchr(p+1, '.');
1597         if (p == NULL) break;
1598         ++p;
1599         if (*p == '\0') break;
1600     }
1601     return rclass;
1602 }
1603
1604 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value)
1605 {
1606     gboolean ret = FALSE;
1607     gchar *rclass = create_class_name(rname);
1608     gchar *rettype, *end;
1609     XrmValue retvalue;
1610
1611     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1612         retvalue.addr != NULL) {
1613         *value = (gint)strtol(retvalue.addr, &end, 10);
1614         if (end != retvalue.addr)
1615             ret = TRUE;
1616     }
1617
1618     g_free(rclass);
1619     return ret;
1620 }
1621
1622 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)
1623 {
1624     gboolean ret = FALSE;
1625     gchar *rclass = create_class_name(rname);
1626     gchar *rettype;
1627     XrmValue retvalue;
1628
1629     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1630         retvalue.addr != NULL) {
1631         *value = retvalue.addr;
1632         ret = TRUE;
1633     }
1634
1635     g_free(rclass);
1636     return ret;
1637 }
1638
1639 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
1640                            const gchar *rname, RrColor **value)
1641 {
1642     gboolean ret = FALSE;
1643     gchar *rclass = create_class_name(rname);
1644     gchar *rettype;
1645     XrmValue retvalue;
1646
1647     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1648         retvalue.addr != NULL) {
1649         RrColor *c = RrColorParse(inst, retvalue.addr);
1650         if (c != NULL) {
1651             *value = c;
1652             ret = TRUE;
1653         }
1654     }
1655
1656     g_free(rclass);
1657     return ret;
1658 }
1659
1660 static gboolean read_mask(const RrInstance *inst, const gchar *path,
1661                           RrTheme *theme, const gchar *maskname,
1662                           RrPixmapMask **value)
1663 {
1664     gboolean ret = FALSE;
1665     gchar *s;
1666     gint hx, hy; /* ignored */
1667     guint w, h;
1668     guchar *b;
1669
1670     s = g_build_filename(path, maskname, NULL);
1671     if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) {
1672         ret = TRUE;
1673         *value = RrPixmapMaskNew(inst, w, h, (gchar*)b);
1674         XFree(b);
1675     }
1676     g_free(s);
1677
1678     return ret;
1679 }
1680
1681 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
1682                              RrReliefType *relief, RrBevelType *bevel,
1683                              gboolean *interlaced, gboolean *border,
1684                              gboolean allow_trans)
1685 {
1686     gchar *t;
1687
1688     /* convert to all lowercase */
1689     for (t = tex; *t != '\0'; ++t)
1690         *t = g_ascii_tolower(*t);
1691
1692     if (allow_trans && strstr(tex, "parentrelative") != NULL) {
1693         *grad = RR_SURFACE_PARENTREL;
1694     } else {
1695         if (strstr(tex, "gradient") != NULL) {
1696             if (strstr(tex, "crossdiagonal") != NULL)
1697                 *grad = RR_SURFACE_CROSS_DIAGONAL;
1698             else if (strstr(tex, "pyramid") != NULL)
1699                 *grad = RR_SURFACE_PYRAMID;
1700             else if (strstr(tex, "mirrorhorizontal") != NULL)
1701                 *grad = RR_SURFACE_MIRROR_HORIZONTAL;
1702             else if (strstr(tex, "horizontal") != NULL)
1703                 *grad = RR_SURFACE_HORIZONTAL;
1704             else if (strstr(tex, "splitvertical") != NULL)
1705                 *grad = RR_SURFACE_SPLIT_VERTICAL;
1706             else if (strstr(tex, "vertical") != NULL)
1707                 *grad = RR_SURFACE_VERTICAL;
1708             else
1709                 *grad = RR_SURFACE_DIAGONAL;
1710         } else {
1711             *grad = RR_SURFACE_SOLID;
1712         }
1713     }
1714
1715     if (strstr(tex, "sunken") != NULL)
1716         *relief = RR_RELIEF_SUNKEN;
1717     else if (strstr(tex, "flat") != NULL)
1718         *relief = RR_RELIEF_FLAT;
1719     else if (strstr(tex, "raised") != NULL)
1720         *relief = RR_RELIEF_RAISED;
1721     else
1722         *relief = (*grad == RR_SURFACE_PARENTREL) ?
1723                   RR_RELIEF_FLAT : RR_RELIEF_RAISED;
1724
1725     *border = FALSE;
1726     if (*relief == RR_RELIEF_FLAT) {
1727         if (strstr(tex, "border") != NULL)
1728             *border = TRUE;
1729     } else {
1730         if (strstr(tex, "bevel2") != NULL)
1731             *bevel = RR_BEVEL_2;
1732         else
1733             *bevel = RR_BEVEL_1;
1734     }
1735
1736     if (strstr(tex, "interlaced") != NULL)
1737         *interlaced = TRUE;
1738     else
1739         *interlaced = FALSE;
1740 }
1741
1742
1743 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
1744                                 const gchar *rname, RrAppearance *value,
1745                                 gboolean allow_trans)
1746 {
1747     gboolean ret = FALSE;
1748     gchar *rclass = create_class_name(rname);
1749     gchar *cname, *ctoname, *bcname, *icname, *hname, *sname;
1750     gchar *csplitname, *ctosplitname;
1751     gchar *rettype;
1752     XrmValue retvalue;
1753     gint i;
1754
1755     cname = g_strconcat(rname, ".color", NULL);
1756     ctoname = g_strconcat(rname, ".colorTo", NULL);
1757     bcname = g_strconcat(rname, ".border.color", NULL);
1758     icname = g_strconcat(rname, ".interlace.color", NULL);
1759     hname = g_strconcat(rname, ".highlight", NULL);
1760     sname = g_strconcat(rname, ".shadow", NULL);
1761     csplitname = g_strconcat(rname, ".color.splitTo", NULL);
1762     ctosplitname = g_strconcat(rname, ".colorTo.splitTo", NULL);
1763
1764     if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
1765         retvalue.addr != NULL) {
1766         parse_appearance(retvalue.addr,
1767                          &value->surface.grad,
1768                          &value->surface.relief,
1769                          &value->surface.bevel,
1770                          &value->surface.interlaced,
1771                          &value->surface.border,
1772                          allow_trans);
1773         if (!read_color(db, inst, cname, &value->surface.primary))
1774             value->surface.primary = RrColorNew(inst, 0, 0, 0);
1775         if (!read_color(db, inst, ctoname, &value->surface.secondary))
1776             value->surface.secondary = RrColorNew(inst, 0, 0, 0);
1777         if (value->surface.border)
1778             if (!read_color(db, inst, bcname,
1779                             &value->surface.border_color))
1780                 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
1781         if (value->surface.interlaced)
1782             if (!read_color(db, inst, icname,
1783                             &value->surface.interlace_color))
1784                 value->surface.interlace_color = RrColorNew(inst, 0, 0, 0);
1785         if (read_int(db, hname, &i) && i >= 0)
1786             value->surface.bevel_light_adjust = i;
1787         if (read_int(db, sname, &i) && i >= 0 && i <= 256)
1788             value->surface.bevel_dark_adjust = i;
1789
1790         if (value->surface.grad == RR_SURFACE_SPLIT_VERTICAL) {
1791             gint r, g, b;
1792
1793             if (!read_color(db, inst, csplitname,
1794                             &value->surface.split_primary))
1795             {
1796                 r = value->surface.primary->r;
1797                 r += r >> 2;
1798                 g = value->surface.primary->g;
1799                 g += g >> 2;
1800                 b = value->surface.primary->b;
1801                 b += b >> 2;
1802                 if (r > 0xFF) r = 0xFF;
1803                 if (g > 0xFF) g = 0xFF;
1804                 if (b > 0xFF) b = 0xFF;
1805                 value->surface.split_primary = RrColorNew(inst, r, g, b);
1806             }
1807
1808             if (!read_color(db, inst, ctosplitname,
1809                             &value->surface.split_secondary))
1810             {
1811                 r = value->surface.secondary->r;
1812                 r += r >> 4;
1813                 g = value->surface.secondary->g;
1814                 g += g >> 4;
1815                 b = value->surface.secondary->b;
1816                 b += b >> 4;
1817                 if (r > 0xFF) r = 0xFF;
1818                 if (g > 0xFF) g = 0xFF;
1819                 if (b > 0xFF) b = 0xFF;
1820                 value->surface.split_secondary = RrColorNew(inst, r, g, b);
1821             }
1822         }
1823
1824         ret = TRUE;
1825     }
1826
1827     g_free(ctosplitname);
1828     g_free(csplitname);
1829     g_free(sname);
1830     g_free(hname);
1831     g_free(icname);
1832     g_free(bcname);
1833     g_free(ctoname);
1834     g_free(cname);
1835     g_free(rclass);
1836     return ret;
1837 }
1838
1839 static int parse_inline_number(const char *p)
1840 {
1841     int neg = 1;
1842     int res = 0;
1843     if (*p == '-') {
1844         neg = -1;
1845         ++p;
1846     }
1847     for (; isdigit(*p); ++p)
1848         res = res * 10 + *p - '0';
1849     res *= neg;
1850     return res;
1851 }
1852
1853 static void set_default_appearance(RrAppearance *a)
1854 {
1855     a->surface.grad = RR_SURFACE_SOLID;
1856     a->surface.relief = RR_RELIEF_FLAT;
1857     a->surface.bevel = RR_BEVEL_1;
1858     a->surface.interlaced = FALSE;
1859     a->surface.border = FALSE;
1860     a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
1861     a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
1862 }
1863
1864 /* Reads the output from gimp's C-Source file format into valid RGBA data for
1865    an RrTextureRGBA. */
1866 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data)
1867 {
1868     RrPixel32 *im, *p;
1869     gint i;
1870
1871     p = im = g_memdup(data, width * height * sizeof(RrPixel32));
1872
1873     for (i = 0; i < width * height; ++i) {
1874         guchar a = ((*p >> 24) & 0xff);
1875         guchar b = ((*p >> 16) & 0xff);
1876         guchar g = ((*p >>  8) & 0xff);
1877         guchar r = ((*p >>  0) & 0xff);
1878
1879         *p = ((r << RrDefaultRedOffset) +
1880               (g << RrDefaultGreenOffset) +
1881               (b << RrDefaultBlueOffset) +
1882               (a << RrDefaultAlphaOffset));
1883         p++;
1884     }
1885
1886     return im;
1887 }