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