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