]> Dogcows Code - chaz/openbox/blob - render/theme.c
add --g-fatal-warnings
[chaz/openbox] / render / theme.c
1 #include "render.h"
2 #include "color.h"
3 #include "font.h"
4 #include "mask.h"
5 #include "theme.h"
6
7 #include <X11/Xlib.h>
8 #include <X11/Xresource.h>
9
10 static XrmDatabase loaddb(RrTheme *theme, char *name);
11 static gboolean read_int(XrmDatabase db, char *rname, int *value);
12 static gboolean read_string(XrmDatabase db, char *rname, char **value);
13 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
14 gchar *rname, RrColor **value);
15 static gboolean read_mask(const RrInstance *inst,
16 gchar *maskname, RrTheme *theme,
17 RrPixmapMask **value);
18 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
19 gchar *rname, RrAppearance *value);
20 static void set_default_appearance(RrAppearance *a);
21
22 RrTheme* RrThemeNew(const RrInstance *inst, gchar *name)
23 {
24 XrmDatabase db = NULL;
25 RrJustify winjust, mtitlejust, mjust;
26 gchar *str;
27 gchar *font_str;
28 RrTheme *theme;
29
30 theme = g_new0(RrTheme, 1);
31
32 theme->inst = inst;
33
34 theme->a_disabled_focused_max = RrAppearanceNew(inst, 1);
35 theme->a_disabled_unfocused_max = RrAppearanceNew(inst, 1);
36 theme->a_focused_unpressed_max = RrAppearanceNew(inst, 1);
37 theme->a_focused_pressed_max = RrAppearanceNew(inst, 1);
38 theme->a_focused_pressed_set_max = RrAppearanceNew(inst, 1);
39 theme->a_unfocused_unpressed_max = RrAppearanceNew(inst, 1);
40 theme->a_unfocused_pressed_max = RrAppearanceNew(inst, 1);
41 theme->a_unfocused_pressed_set_max = RrAppearanceNew(inst, 1);
42 theme->a_focused_grip = RrAppearanceNew(inst, 0);
43 theme->a_unfocused_grip = RrAppearanceNew(inst, 0);
44 theme->a_focused_title = RrAppearanceNew(inst, 0);
45 theme->a_unfocused_title = RrAppearanceNew(inst, 0);
46 theme->a_focused_label = RrAppearanceNew(inst, 1);
47 theme->a_unfocused_label = RrAppearanceNew(inst, 1);
48 theme->a_icon = RrAppearanceNew(inst, 1);
49 theme->a_focused_handle = RrAppearanceNew(inst, 0);
50 theme->a_unfocused_handle = RrAppearanceNew(inst, 0);
51 theme->a_menu = RrAppearanceNew(inst, 0);
52 theme->a_menu_title = RrAppearanceNew(inst, 1);
53 theme->a_menu_item = RrAppearanceNew(inst, 1);
54 theme->a_menu_disabled = RrAppearanceNew(inst, 1);
55 theme->a_menu_hilite = RrAppearanceNew(inst, 1);
56
57 theme->app_hilite_bg = RrAppearanceNew(inst, 0);
58 theme->app_unhilite_bg = RrAppearanceNew(inst, 0);
59 theme->app_hilite_label = RrAppearanceNew(inst, 1);
60 theme->app_unhilite_label = RrAppearanceNew(inst, 1);
61 theme->app_icon = RrAppearanceNew(inst, 1);
62
63 if (name) {
64 db = loaddb(theme, name);
65 if (db == NULL) {
66 g_warning("Failed to load the theme '%s'", name);
67 g_message("Falling back to the default: '%s'", DEFAULT_THEME);
68 } else
69 theme->name = g_path_get_basename(name);
70 }
71 if (db == NULL) {
72 db = loaddb(theme, DEFAULT_THEME);
73 if (db == NULL) {
74 g_warning("Failed to load the theme '%s'.", DEFAULT_THEME);
75 return NULL;
76 } else
77 theme->name = g_path_get_basename(DEFAULT_THEME);
78 }
79
80 /* load the font stuff */
81 if (!read_string(db, "window.title.xftfont", &font_str))
82 font_str = "arial,sans:bold:pixelsize=10:shadow=y:shadowtint=50";
83
84 if (!(theme->winfont = RrFontOpen(inst, font_str))) {
85 RrThemeFree(theme);
86 return NULL;
87 }
88 theme->winfont_height = RrFontHeight(theme->winfont);
89
90 winjust = RR_JUSTIFY_LEFT;
91 if (read_string(db, "window.justify", &str)) {
92 if (!g_ascii_strcasecmp(str, "right"))
93 winjust = RR_JUSTIFY_RIGHT;
94 else if (!g_ascii_strcasecmp(str, "center"))
95 winjust = RR_JUSTIFY_CENTER;
96 }
97
98 if (!read_string(db, "menu.title.xftfont", &font_str))
99 font_str = "arial,sans:bold:pixelsize=12:shadow=y";
100
101 if (!(theme->mtitlefont = RrFontOpen(inst, font_str))) {
102 RrThemeFree(theme);
103 return NULL;
104 }
105 theme->mtitlefont_height = RrFontHeight(theme->mtitlefont);
106
107 mtitlejust = RR_JUSTIFY_LEFT;
108 if (read_string(db, "menu.title.justify", &str)) {
109 if (!g_ascii_strcasecmp(str, "right"))
110 mtitlejust = RR_JUSTIFY_RIGHT;
111 else if (!g_ascii_strcasecmp(str, "center"))
112 mtitlejust = RR_JUSTIFY_CENTER;
113 }
114
115 if (!read_string(db, "menu.frame.xftfont", &font_str))
116 font_str = "arial,sans:bold:pixelsize=11:shadow=y";
117
118 if (!(theme->mfont = RrFontOpen(inst, font_str))) {
119 RrThemeFree(theme);
120 return NULL;
121 }
122 theme->mfont_height = RrFontHeight(theme->mfont);
123
124 mjust = RR_JUSTIFY_LEFT;
125 if (read_string(db, "menu.frame.justify", &str)) {
126 if (!g_ascii_strcasecmp(str, "right"))
127 mjust = RR_JUSTIFY_RIGHT;
128 else if (!g_ascii_strcasecmp(str, "center"))
129 mjust = RR_JUSTIFY_CENTER;
130 }
131
132 /* load the title layout */
133 if (!read_string(db, "window.title.layout", &font_str))
134 font_str = "NLIMC";
135 theme->title_layout = g_strdup(font_str);
136
137 /* load direct dimensions */
138 if (!read_int(db, "handleWidth", &theme->handle_height) ||
139 theme->handle_height < 0 || theme->handle_height > 100)
140 theme->handle_height = 6;
141 if (!read_int(db, "bevelWidth", &theme->bevel) ||
142 theme->bevel <= 0 || theme->bevel > 100) theme->bevel = 3;
143 if (!read_int(db, "borderWidth", &theme->bwidth) ||
144 theme->bwidth < 0 || theme->bwidth > 100) theme->bwidth = 1;
145 if (!read_int(db, "frameWidth", &theme->cbwidth) ||
146 theme->cbwidth < 0 || theme->cbwidth > 100)
147 theme->cbwidth = theme->bevel;
148
149 /* load colors */
150 if (!read_color(db, inst,
151 "borderColor", &theme->b_color))
152 theme->b_color = RrColorNew(inst, 0, 0, 0);
153 if (!read_color(db, inst,
154 "window.frame.focusColor", &theme->cb_focused_color))
155 theme->cb_focused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
156 if (!read_color(db, inst,
157 "window.frame.unfocusColor",&theme->cb_unfocused_color))
158 theme->cb_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
159 if (!read_color(db, inst,
160 "window.label.focus.textColor",
161 &theme->title_focused_color))
162 theme->title_focused_color = RrColorNew(inst, 0x0, 0x0, 0x0);
163 if (!read_color(db, inst,
164 "window.label.unfocus.textColor",
165 &theme->title_unfocused_color))
166 theme->title_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
167 if (!read_color(db, inst,
168 "window.button.disabled.focus.picColor",
169 &theme->titlebut_disabled_focused_color))
170 theme->titlebut_disabled_focused_color =
171 RrColorNew(inst, 0xff, 0xff, 0xff);
172 if (!read_color(db, inst,
173 "window.button.disabled.unfocus.picColor",
174 &theme->titlebut_disabled_unfocused_color))
175 theme->titlebut_disabled_unfocused_color = RrColorNew(inst, 0, 0, 0);
176 if (!read_color(db, inst,
177 "window.button.focus.picColor",
178 &theme->titlebut_focused_color))
179 theme->titlebut_focused_color = RrColorNew(inst, 0, 0, 0);
180 if (!read_color(db, inst,
181 "window.button.unfocus.picColor",
182 &theme->titlebut_unfocused_color))
183 theme->titlebut_unfocused_color = RrColorNew(inst, 0xff, 0xff, 0xff);
184 if (!read_color(db, inst,
185 "menu.title.textColor", &theme->menu_title_color))
186 theme->menu_title_color = RrColorNew(inst, 0, 0, 0);
187 if (!read_color(db, inst,
188 "menu.frame.textColor", &theme->menu_color))
189 theme->menu_color = RrColorNew(inst, 0xff, 0xff, 0xff);
190 if (!read_color(db, inst,
191 "menu.frame.disableColor", &theme->menu_disabled_color))
192 theme->menu_disabled_color = RrColorNew(inst, 0, 0, 0);
193 if (!read_color(db, inst,
194 "menu.hilite.textColor", &theme->menu_hilite_color))
195 theme->menu_hilite_color = RrColorNew(inst, 0, 0, 0);
196
197 if (read_mask(inst, "max.xbm", theme, &theme->max_unset_mask)){
198 if (!read_mask(inst, "max_t.xbm", theme, &theme->max_set_mask)) {
199 theme->max_set_mask = RrPixmapMaskCopy(theme->max_unset_mask);
200 }
201 } else {
202 {
203 char data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
204 theme->max_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
205 }
206 {
207 char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
208 theme->max_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
209 }
210 }
211
212 if (!read_mask(inst, "iconify.xbm", theme, &theme->iconify_mask)) {
213 char data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
214 theme->iconify_mask = RrPixmapMaskNew(inst, 7, 7, data);
215 }
216
217 if (read_mask(inst, "stick.xbm", theme, &theme->desk_unset_mask)) {
218 if (!read_mask(inst, "stick_t.xbm", theme, &theme->desk_set_mask)) {
219 theme->desk_set_mask =
220 RrPixmapMaskCopy(theme->desk_unset_mask);
221 }
222 } else {
223 {
224 char data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
225 theme->desk_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
226 }
227 {
228 char data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
229 theme->desk_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
230 }
231 }
232
233 if (read_mask(inst, "shade.xbm", theme, &theme->shade_unset_mask)) {
234 if (!read_mask(inst, "shade_t.xbm", theme, &theme->shade_set_mask)) {
235 theme->shade_set_mask =
236 RrPixmapMaskCopy(theme->shade_unset_mask);
237 }
238 } else {
239 {
240 char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
241 theme->shade_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
242 }
243 {
244 char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
245 theme->shade_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
246 }
247 }
248
249 if (!read_mask(inst, "close.xbm", theme, &theme->close_mask)) {
250 char data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
251 theme->close_mask = RrPixmapMaskNew(inst, 7, 7, data);
252 }
253
254 /* read the decoration textures */
255 if (!read_appearance(db, inst,
256 "window.title.focus", theme->a_focused_title))
257 set_default_appearance(theme->a_focused_title);
258 if (!read_appearance(db, inst,
259 "window.title.unfocus", theme->a_unfocused_title))
260 set_default_appearance(theme->a_unfocused_title);
261 if (!read_appearance(db, inst,
262 "window.label.focus", theme->a_focused_label))
263 set_default_appearance(theme->a_focused_label);
264 if (!read_appearance(db, inst,
265 "window.label.unfocus", theme->a_unfocused_label))
266 set_default_appearance(theme->a_unfocused_label);
267 if (!read_appearance(db, inst,
268 "window.handle.focus", theme->a_focused_handle))
269 set_default_appearance(theme->a_focused_handle);
270 if (!read_appearance(db, inst,
271 "window.handle.unfocus",theme->a_unfocused_handle))
272 set_default_appearance(theme->a_unfocused_handle);
273 if (!read_appearance(db, inst,
274 "window.grip.focus", theme->a_focused_grip))
275 set_default_appearance(theme->a_focused_grip);
276 if (!read_appearance(db, inst,
277 "window.grip.unfocus", theme->a_unfocused_grip))
278 set_default_appearance(theme->a_unfocused_grip);
279 if (!read_appearance(db, inst,
280 "menu.frame", theme->a_menu))
281 set_default_appearance(theme->a_menu);
282 if (!read_appearance(db, inst,
283 "menu.title", theme->a_menu_title))
284 set_default_appearance(theme->a_menu_title);
285 if (!read_appearance(db, inst,
286 "menu.hilite", theme->a_menu_hilite))
287 set_default_appearance(theme->a_menu_hilite);
288
289 /* read the appearances for rendering non-decorations */
290 if (!read_appearance(db, inst,
291 "window.title.focus", theme->app_hilite_bg))
292 set_default_appearance(theme->app_hilite_bg);
293 if (!read_appearance(db, inst,
294 "window.label.focus", theme->app_hilite_label))
295 set_default_appearance(theme->app_hilite_label);
296 if (!read_appearance(db, inst,
297 "window.title.unfocus", theme->app_unhilite_bg))
298 set_default_appearance(theme->app_unhilite_bg);
299 if (!read_appearance(db, inst,
300 "window.label.unfocus", theme->app_unhilite_label))
301 set_default_appearance(theme->app_unhilite_label);
302
303 /* read buttons textures */
304 if (!read_appearance(db, inst,
305 "window.button.disabled.focus",
306 theme->a_disabled_focused_max))
307 set_default_appearance(theme->a_disabled_focused_max);
308 if (!read_appearance(db, inst,
309 "window.button.disabled.unfocus",
310 theme->a_disabled_unfocused_max))
311 set_default_appearance(theme->a_disabled_unfocused_max);
312 if (!read_appearance(db, inst,
313 "window.button.pressed.focus",
314 theme->a_focused_pressed_max))
315 if (!read_appearance(db, inst,
316 "window.button.pressed",
317 theme->a_focused_pressed_max))
318 set_default_appearance(theme->a_focused_pressed_max);
319 if (!read_appearance(db, inst,
320 "window.button.pressed.unfocus",
321 theme->a_unfocused_pressed_max))
322 if (!read_appearance(db, inst,
323 "window.button.pressed",
324 theme->a_unfocused_pressed_max))
325 set_default_appearance(theme->a_unfocused_pressed_max);
326 if (!read_appearance(db, inst,
327 "window.button.focus",
328 theme->a_focused_unpressed_max))
329 set_default_appearance(theme->a_focused_unpressed_max);
330 if (!read_appearance(db, inst,
331 "window.button.unfocus",
332 theme->a_unfocused_unpressed_max))
333 set_default_appearance(theme->a_unfocused_unpressed_max);
334
335 theme->a_disabled_focused_close =
336 RrAppearanceCopy(theme->a_disabled_focused_max);
337 theme->a_disabled_unfocused_close =
338 RrAppearanceCopy(theme->a_disabled_unfocused_max);
339 theme->a_unfocused_unpressed_close =
340 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
341 theme->a_unfocused_pressed_close =
342 RrAppearanceCopy(theme->a_unfocused_pressed_max);
343 theme->a_focused_unpressed_close =
344 RrAppearanceCopy(theme->a_focused_unpressed_max);
345 theme->a_focused_pressed_close =
346 RrAppearanceCopy(theme->a_focused_pressed_max);
347 theme->a_disabled_focused_desk =
348 RrAppearanceCopy(theme->a_disabled_focused_max);
349 theme->a_disabled_unfocused_desk =
350 RrAppearanceCopy(theme->a_disabled_unfocused_max);
351 theme->a_unfocused_unpressed_desk =
352 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
353 theme->a_unfocused_pressed_desk =
354 RrAppearanceCopy(theme->a_unfocused_pressed_max);
355 theme->a_unfocused_pressed_set_desk =
356 RrAppearanceCopy(theme->a_unfocused_pressed_max);
357 theme->a_focused_unpressed_desk =
358 RrAppearanceCopy(theme->a_focused_unpressed_max);
359 theme->a_focused_pressed_desk =
360 RrAppearanceCopy(theme->a_focused_pressed_max);
361 theme->a_focused_pressed_set_desk =
362 RrAppearanceCopy(theme->a_focused_pressed_max);
363 theme->a_disabled_focused_shade =
364 RrAppearanceCopy(theme->a_disabled_focused_max);
365 theme->a_disabled_unfocused_shade =
366 RrAppearanceCopy(theme->a_disabled_unfocused_max);
367 theme->a_unfocused_unpressed_shade =
368 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
369 theme->a_unfocused_pressed_shade =
370 RrAppearanceCopy(theme->a_unfocused_pressed_max);
371 theme->a_unfocused_pressed_set_shade =
372 RrAppearanceCopy(theme->a_unfocused_pressed_max);
373 theme->a_focused_unpressed_shade =
374 RrAppearanceCopy(theme->a_focused_unpressed_max);
375 theme->a_focused_pressed_shade =
376 RrAppearanceCopy(theme->a_focused_pressed_max);
377 theme->a_focused_pressed_set_shade =
378 RrAppearanceCopy(theme->a_focused_pressed_max);
379 theme->a_disabled_focused_iconify =
380 RrAppearanceCopy(theme->a_disabled_focused_max);
381 theme->a_disabled_unfocused_iconify =
382 RrAppearanceCopy(theme->a_disabled_focused_max);
383 theme->a_unfocused_unpressed_iconify =
384 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
385 theme->a_unfocused_pressed_iconify =
386 RrAppearanceCopy(theme->a_unfocused_pressed_max);
387 theme->a_focused_unpressed_iconify =
388 RrAppearanceCopy(theme->a_focused_unpressed_max);
389 theme->a_focused_pressed_iconify =
390 RrAppearanceCopy(theme->a_focused_pressed_max);
391 theme->a_unfocused_pressed_set_max =
392 RrAppearanceCopy(theme->a_unfocused_pressed_max);
393 theme->a_focused_pressed_set_max =
394 RrAppearanceCopy(theme->a_focused_pressed_max);
395
396 theme->a_icon->surface.grad = RR_SURFACE_PARENTREL;
397
398 /* set up the textures */
399 theme->a_focused_label->texture[0].type =
400 theme->app_hilite_label->texture[0].type = RR_TEXTURE_TEXT;
401 theme->a_focused_label->texture[0].data.text.justify = winjust;
402 theme->app_hilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
403 theme->a_focused_label->texture[0].data.text.font =
404 theme->app_hilite_label->texture[0].data.text.font = theme->winfont;
405 theme->a_focused_label->texture[0].data.text.color =
406 theme->app_hilite_label->texture[0].data.text.color =
407 theme->title_focused_color;
408
409 theme->a_unfocused_label->texture[0].type =
410 theme->app_unhilite_label->texture[0].type = RR_TEXTURE_TEXT;
411 theme->a_unfocused_label->texture[0].data.text.justify = winjust;
412 theme->app_unhilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
413 theme->a_unfocused_label->texture[0].data.text.font =
414 theme->app_unhilite_label->texture[0].data.text.font = theme->winfont;
415 theme->a_unfocused_label->texture[0].data.text.color =
416 theme->app_unhilite_label->texture[0].data.text.color =
417 theme->title_unfocused_color;
418
419 theme->a_menu_title->texture[0].type = RR_TEXTURE_TEXT;
420 theme->a_menu_title->texture[0].data.text.justify = mtitlejust;
421 theme->a_menu_title->texture[0].data.text.font = theme->mtitlefont;
422 theme->a_menu_title->texture[0].data.text.color = theme->menu_title_color;
423
424 theme->a_menu_item->surface.grad =
425 theme->a_menu_disabled->surface.grad =
426 theme->app_icon->surface.grad = RR_SURFACE_PARENTREL;
427
428 theme->a_menu_item->texture[0].type =
429 theme->a_menu_disabled->texture[0].type =
430 theme->a_menu_hilite->texture[0].type = RR_TEXTURE_TEXT;
431 theme->a_menu_item->texture[0].data.text.justify =
432 theme->a_menu_disabled->texture[0].data.text.justify =
433 theme->a_menu_hilite->texture[0].data.text.justify = mjust;
434 theme->a_menu_item->texture[0].data.text.font =
435 theme->a_menu_disabled->texture[0].data.text.font =
436 theme->a_menu_hilite->texture[0].data.text.font = theme->mfont;
437 theme->a_menu_item->texture[0].data.text.color = theme->menu_color;
438 theme->a_menu_disabled->texture[0].data.text.color =
439 theme->menu_disabled_color;
440 theme->a_menu_hilite->texture[0].data.text.color =
441 theme->menu_hilite_color;
442
443 theme->a_disabled_focused_max->texture[0].type =
444 theme->a_disabled_unfocused_max->texture[0].type =
445 theme->a_focused_unpressed_max->texture[0].type =
446 theme->a_focused_pressed_max->texture[0].type =
447 theme->a_focused_pressed_set_max->texture[0].type =
448 theme->a_unfocused_unpressed_max->texture[0].type =
449 theme->a_unfocused_pressed_max->texture[0].type =
450 theme->a_unfocused_pressed_set_max->texture[0].type =
451 theme->a_disabled_focused_close->texture[0].type =
452 theme->a_disabled_unfocused_close->texture[0].type =
453 theme->a_focused_unpressed_close->texture[0].type =
454 theme->a_focused_pressed_close->texture[0].type =
455 theme->a_unfocused_unpressed_close->texture[0].type =
456 theme->a_unfocused_pressed_close->texture[0].type =
457 theme->a_disabled_focused_desk->texture[0].type =
458 theme->a_disabled_unfocused_desk->texture[0].type =
459 theme->a_focused_unpressed_desk->texture[0].type =
460 theme->a_focused_pressed_desk->texture[0].type =
461 theme->a_focused_pressed_set_desk->texture[0].type =
462 theme->a_unfocused_unpressed_desk->texture[0].type =
463 theme->a_unfocused_pressed_desk->texture[0].type =
464 theme->a_unfocused_pressed_set_desk->texture[0].type =
465 theme->a_disabled_focused_shade->texture[0].type =
466 theme->a_disabled_unfocused_shade->texture[0].type =
467 theme->a_focused_unpressed_shade->texture[0].type =
468 theme->a_focused_pressed_shade->texture[0].type =
469 theme->a_focused_pressed_set_shade->texture[0].type =
470 theme->a_unfocused_unpressed_shade->texture[0].type =
471 theme->a_unfocused_pressed_shade->texture[0].type =
472 theme->a_unfocused_pressed_set_shade->texture[0].type =
473 theme->a_disabled_focused_iconify->texture[0].type =
474 theme->a_disabled_unfocused_iconify->texture[0].type =
475 theme->a_focused_unpressed_iconify->texture[0].type =
476 theme->a_focused_pressed_iconify->texture[0].type =
477 theme->a_unfocused_unpressed_iconify->texture[0].type =
478 theme->a_unfocused_pressed_iconify->texture[0].type = RR_TEXTURE_MASK;
479 theme->a_disabled_focused_max->texture[0].data.mask.mask =
480 theme->a_disabled_unfocused_max->texture[0].data.mask.mask =
481 theme->a_focused_unpressed_max->texture[0].data.mask.mask =
482 theme->a_unfocused_unpressed_max->texture[0].data.mask.mask =
483 theme->a_focused_pressed_max->texture[0].data.mask.mask =
484 theme->a_unfocused_pressed_max->texture[0].data.mask.mask =
485 theme->max_unset_mask;
486 theme->a_focused_pressed_set_max->texture[0].data.mask.mask =
487 theme->a_unfocused_pressed_set_max->texture[0].data.mask.mask =
488 theme->max_set_mask;
489 theme->a_disabled_focused_close->texture[0].data.mask.mask =
490 theme->a_disabled_unfocused_close->texture[0].data.mask.mask =
491 theme->a_focused_pressed_close->texture[0].data.mask.mask =
492 theme->a_unfocused_pressed_close->texture[0].data.mask.mask =
493 theme->a_focused_unpressed_close->texture[0].data.mask.mask =
494 theme->a_unfocused_unpressed_close->texture[0].data.mask.mask =
495 theme->close_mask;
496 theme->a_disabled_focused_desk->texture[0].data.mask.mask =
497 theme->a_disabled_unfocused_desk->texture[0].data.mask.mask =
498 theme->a_focused_unpressed_desk->texture[0].data.mask.mask =
499 theme->a_unfocused_unpressed_desk->texture[0].data.mask.mask =
500 theme->a_focused_pressed_desk->texture[0].data.mask.mask =
501 theme->a_unfocused_pressed_desk->texture[0].data.mask.mask =
502 theme->desk_unset_mask;
503 theme->a_focused_pressed_set_desk->texture[0].data.mask.mask =
504 theme->a_unfocused_pressed_set_desk->texture[0].data.mask.mask =
505 theme->desk_set_mask;
506 theme->a_disabled_focused_shade->texture[0].data.mask.mask =
507 theme->a_disabled_unfocused_shade->texture[0].data.mask.mask =
508 theme->a_focused_unpressed_shade->texture[0].data.mask.mask =
509 theme->a_unfocused_unpressed_shade->texture[0].data.mask.mask =
510 theme->a_focused_pressed_shade->texture[0].data.mask.mask =
511 theme->a_unfocused_pressed_shade->texture[0].data.mask.mask =
512 theme->shade_unset_mask;
513 theme->a_focused_pressed_set_shade->texture[0].data.mask.mask =
514 theme->a_unfocused_pressed_set_shade->texture[0].data.mask.mask =
515 theme->shade_set_mask;
516 theme->a_disabled_focused_iconify->texture[0].data.mask.mask =
517 theme->a_disabled_unfocused_iconify->texture[0].data.mask.mask =
518 theme->a_focused_unpressed_iconify->texture[0].data.mask.mask =
519 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
520 theme->a_focused_pressed_iconify->texture[0].data.mask.mask =
521 theme->a_unfocused_pressed_iconify->texture[0].data.mask.mask =
522 theme->iconify_mask;
523 theme->a_disabled_focused_max->texture[0].data.mask.color =
524 theme->a_disabled_focused_close->texture[0].data.mask.color =
525 theme->a_disabled_focused_desk->texture[0].data.mask.color =
526 theme->a_disabled_focused_shade->texture[0].data.mask.color =
527 theme->a_disabled_focused_iconify->texture[0].data.mask.color =
528 theme->titlebut_disabled_focused_color;
529 theme->a_disabled_unfocused_max->texture[0].data.mask.color =
530 theme->a_disabled_unfocused_close->texture[0].data.mask.color =
531 theme->a_disabled_unfocused_desk->texture[0].data.mask.color =
532 theme->a_disabled_unfocused_shade->texture[0].data.mask.color =
533 theme->a_disabled_unfocused_iconify->texture[0].data.mask.color =
534 theme->titlebut_disabled_unfocused_color;
535 theme->a_focused_unpressed_max->texture[0].data.mask.color =
536 theme->a_focused_pressed_max->texture[0].data.mask.color =
537 theme->a_focused_pressed_set_max->texture[0].data.mask.color =
538 theme->a_focused_unpressed_close->texture[0].data.mask.color =
539 theme->a_focused_pressed_close->texture[0].data.mask.color =
540 theme->a_focused_unpressed_desk->texture[0].data.mask.color =
541 theme->a_focused_pressed_desk->texture[0].data.mask.color =
542 theme->a_focused_pressed_set_desk->texture[0].data.mask.color =
543 theme->a_focused_unpressed_shade->texture[0].data.mask.color =
544 theme->a_focused_pressed_shade->texture[0].data.mask.color =
545 theme->a_focused_pressed_set_shade->texture[0].data.mask.color =
546 theme->a_focused_unpressed_iconify->texture[0].data.mask.color =
547 theme->a_focused_pressed_iconify->texture[0].data.mask.color =
548 theme->titlebut_focused_color;
549 theme->a_unfocused_unpressed_max->texture[0].data.mask.color =
550 theme->a_unfocused_pressed_max->texture[0].data.mask.color =
551 theme->a_unfocused_pressed_set_max->texture[0].data.mask.color =
552 theme->a_unfocused_unpressed_close->texture[0].data.mask.color =
553 theme->a_unfocused_pressed_close->texture[0].data.mask.color =
554 theme->a_unfocused_unpressed_desk->texture[0].data.mask.color =
555 theme->a_unfocused_pressed_desk->texture[0].data.mask.color =
556 theme->a_unfocused_pressed_set_desk->texture[0].data.mask.color =
557 theme->a_unfocused_unpressed_shade->texture[0].data.mask.color =
558 theme->a_unfocused_pressed_shade->texture[0].data.mask.color =
559 theme->a_unfocused_pressed_set_shade->texture[0].data.mask.color =
560 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.color =
561 theme->a_unfocused_pressed_iconify->texture[0].data.mask.color =
562 theme->titlebut_unfocused_color;
563
564 XrmDestroyDatabase(db);
565
566 theme->label_height = theme->winfont_height;
567 theme->title_height = theme->label_height + theme->bevel * 2;
568 theme->button_size = theme->label_height - 2;
569 theme->grip_width = theme->button_size * 2;
570
571 return theme;
572 }
573
574 void RrThemeFree(RrTheme *theme)
575 {
576 if (theme) {
577 g_free(theme->name);
578
579 RrColorFree(theme->b_color);
580 RrColorFree(theme->cb_unfocused_color);
581 RrColorFree(theme->cb_focused_color);
582 RrColorFree(theme->title_unfocused_color);
583 RrColorFree(theme->title_focused_color);
584 RrColorFree(theme->titlebut_unfocused_color);
585 RrColorFree(theme->titlebut_focused_color);
586 RrColorFree(theme->menu_color);
587 RrColorFree(theme->menu_title_color);
588 RrColorFree(theme->menu_disabled_color);
589 RrColorFree(theme->menu_hilite_color);
590
591 RrPixmapMaskFree(theme->max_set_mask);
592 RrPixmapMaskFree(theme->max_unset_mask);
593 RrPixmapMaskFree(theme->desk_set_mask);
594 RrPixmapMaskFree(theme->desk_unset_mask);
595 RrPixmapMaskFree(theme->shade_set_mask);
596 RrPixmapMaskFree(theme->shade_unset_mask);
597 RrPixmapMaskFree(theme->iconify_mask);
598 RrPixmapMaskFree(theme->close_mask);
599
600 RrFontClose(theme->winfont);
601 RrFontClose(theme->mtitlefont);
602 RrFontClose(theme->mfont);
603
604 g_free(theme->title_layout);
605
606 RrAppearanceFree(theme->a_focused_unpressed_max);
607 RrAppearanceFree(theme->a_focused_pressed_max);
608 RrAppearanceFree(theme->a_focused_pressed_set_max);
609 RrAppearanceFree(theme->a_unfocused_unpressed_max);
610 RrAppearanceFree(theme->a_unfocused_pressed_max);
611 RrAppearanceFree(theme->a_unfocused_pressed_set_max);
612 RrAppearanceFree(theme->a_focused_unpressed_close);
613 RrAppearanceFree(theme->a_focused_pressed_close);
614 RrAppearanceFree(theme->a_unfocused_unpressed_close);
615 RrAppearanceFree(theme->a_unfocused_pressed_close);
616 RrAppearanceFree(theme->a_focused_unpressed_desk);
617 RrAppearanceFree(theme->a_focused_pressed_desk);
618 RrAppearanceFree(theme->a_unfocused_unpressed_desk);
619 RrAppearanceFree(theme->a_unfocused_pressed_desk);
620 RrAppearanceFree(theme->a_focused_unpressed_shade);
621 RrAppearanceFree(theme->a_focused_pressed_shade);
622 RrAppearanceFree(theme->a_unfocused_unpressed_shade);
623 RrAppearanceFree(theme->a_unfocused_pressed_shade);
624 RrAppearanceFree(theme->a_focused_unpressed_iconify);
625 RrAppearanceFree(theme->a_focused_pressed_iconify);
626 RrAppearanceFree(theme->a_unfocused_unpressed_iconify);
627 RrAppearanceFree(theme->a_unfocused_pressed_iconify);
628 RrAppearanceFree(theme->a_focused_grip);
629 RrAppearanceFree(theme->a_unfocused_grip);
630 RrAppearanceFree(theme->a_focused_title);
631 RrAppearanceFree(theme->a_unfocused_title);
632 RrAppearanceFree(theme->a_focused_label);
633 RrAppearanceFree(theme->a_unfocused_label);
634 RrAppearanceFree(theme->a_icon);
635 RrAppearanceFree(theme->a_focused_handle);
636 RrAppearanceFree(theme->a_unfocused_handle);
637 RrAppearanceFree(theme->a_menu);
638 RrAppearanceFree(theme->a_menu_title);
639 RrAppearanceFree(theme->a_menu_item);
640 RrAppearanceFree(theme->a_menu_disabled);
641 RrAppearanceFree(theme->a_menu_hilite);
642 RrAppearanceFree(theme->app_hilite_bg);
643 RrAppearanceFree(theme->app_unhilite_bg);
644 RrAppearanceFree(theme->app_hilite_label);
645 RrAppearanceFree(theme->app_unhilite_label);
646 RrAppearanceFree(theme->app_icon);
647 }
648 }
649
650 static XrmDatabase loaddb(RrTheme *theme, char *name)
651 {
652 XrmDatabase db;
653
654 if ((db = XrmGetFileDatabase(name)))
655 theme->path = g_path_get_dirname(name);
656 if (db == NULL) {
657 char *s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
658 name, NULL);
659 if ((db = XrmGetFileDatabase(s)))
660 theme->path = g_path_get_dirname(s);
661 g_free(s);
662 }
663 if (db == NULL) {
664 char *s = g_build_filename(THEMEDIR, name, NULL);
665 if ((db = XrmGetFileDatabase(s)))
666 theme->path = g_path_get_dirname(s);
667 g_free(s);
668 }
669
670 return db;
671 }
672
673 static char *create_class_name(char *rname)
674 {
675 char *rclass = g_strdup(rname);
676 char *p = rclass;
677
678 while (TRUE) {
679 *p = toupper(*p);
680 p = strchr(p+1, '.');
681 if (p == NULL) break;
682 ++p;
683 if (*p == '\0') break;
684 }
685 return rclass;
686 }
687
688 static gboolean read_int(XrmDatabase db, char *rname, int *value)
689 {
690 gboolean ret = FALSE;
691 char *rclass = create_class_name(rname);
692 char *rettype, *end;
693 XrmValue retvalue;
694
695 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
696 retvalue.addr != NULL) {
697 *value = (int)strtol(retvalue.addr, &end, 10);
698 if (end != retvalue.addr)
699 ret = TRUE;
700 }
701
702 g_free(rclass);
703 return ret;
704 }
705
706 static gboolean read_string(XrmDatabase db, char *rname, char **value)
707 {
708 gboolean ret = FALSE;
709 char *rclass = create_class_name(rname);
710 char *rettype;
711 XrmValue retvalue;
712
713 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
714 retvalue.addr != NULL) {
715 *value = retvalue.addr;
716 ret = TRUE;
717 }
718
719 g_free(rclass);
720 return ret;
721 }
722
723 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
724 gchar *rname, RrColor **value)
725 {
726 gboolean ret = FALSE;
727 char *rclass = create_class_name(rname);
728 char *rettype;
729 XrmValue retvalue;
730
731 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
732 retvalue.addr != NULL) {
733 RrColor *c = RrColorParse(inst, retvalue.addr);
734 if (c != NULL) {
735 *value = c;
736 ret = TRUE;
737 }
738 }
739
740 g_free(rclass);
741 return ret;
742 }
743
744 static gboolean read_mask(const RrInstance *inst,
745 gchar *maskname, RrTheme *theme,
746 RrPixmapMask **value)
747 {
748 gboolean ret = FALSE;
749 char *s;
750 char *data_dir;
751 int hx, hy; /* ignored */
752 unsigned int w, h;
753 unsigned char *b;
754
755 data_dir = g_strdup_printf("%s_data", theme->name);
756
757 s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
758 data_dir, maskname, NULL);
759 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
760 ret = TRUE;
761 else {
762 g_free(s);
763 s = g_build_filename(THEMEDIR, data_dir, maskname, NULL);
764 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
765 ret = TRUE;
766 else {
767 g_free(s);
768 s = g_build_filename(theme->path, data_dir, maskname, NULL);
769 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
770 ret = TRUE;
771 }
772 }
773
774 if (ret) {
775 *value = RrPixmapMaskNew(inst, w, h, (char*)b);
776 XFree(b);
777 }
778
779 g_free(s);
780 g_free(data_dir);
781
782 return ret;
783 }
784
785 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
786 RrReliefType *relief, RrBevelType *bevel,
787 gboolean *interlaced, gboolean *border)
788 {
789 char *t;
790
791 /* convert to all lowercase */
792 for (t = tex; *t != '\0'; ++t)
793 *t = g_ascii_tolower(*t);
794
795 if (strstr(tex, "parentrelative") != NULL) {
796 *grad = RR_SURFACE_PARENTREL;
797 } else {
798 if (strstr(tex, "gradient") != NULL) {
799 if (strstr(tex, "crossdiagonal") != NULL)
800 *grad = RR_SURFACE_CROSS_DIAGONAL;
801 else if (strstr(tex, "pyramid") != NULL)
802 *grad = RR_SURFACE_PYRAMID;
803 else if (strstr(tex, "horizontal") != NULL)
804 *grad = RR_SURFACE_HORIZONTAL;
805 else if (strstr(tex, "vertical") != NULL)
806 *grad = RR_SURFACE_VERTICAL;
807 else
808 *grad = RR_SURFACE_DIAGONAL;
809 } else {
810 *grad = RR_SURFACE_SOLID;
811 }
812
813 if (strstr(tex, "sunken") != NULL)
814 *relief = RR_RELIEF_SUNKEN;
815 else if (strstr(tex, "flat") != NULL)
816 *relief = RR_RELIEF_FLAT;
817 else
818 *relief = RR_RELIEF_RAISED;
819
820 *border = FALSE;
821 if (*relief == RR_RELIEF_FLAT) {
822 if (strstr(tex, "border") != NULL)
823 *border = TRUE;
824 } else {
825 if (strstr(tex, "bevel2") != NULL)
826 *bevel = RR_BEVEL_2;
827 else
828 *bevel = RR_BEVEL_1;
829 }
830
831 if (strstr(tex, "interlaced") != NULL)
832 *interlaced = TRUE;
833 else
834 *interlaced = FALSE;
835 }
836 }
837
838
839 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
840 gchar *rname, RrAppearance *value)
841 {
842 gboolean ret = FALSE;
843 char *rclass = create_class_name(rname), *cname, *ctoname, *bcname;
844 char *rettype;
845 XrmValue retvalue;
846
847 cname = g_strconcat(rname, ".color", NULL);
848 ctoname = g_strconcat(rname, ".colorTo", NULL);
849 bcname = g_strconcat(rname, ".borderColor", NULL);
850
851 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
852 retvalue.addr != NULL) {
853 parse_appearance(retvalue.addr,
854 &value->surface.grad,
855 &value->surface.relief,
856 &value->surface.bevel,
857 &value->surface.interlaced,
858 &value->surface.border);
859 if (!read_color(db, inst, cname, &value->surface.primary))
860 value->surface.primary = RrColorNew(inst, 0, 0, 0);
861 if (!read_color(db, inst, ctoname, &value->surface.secondary))
862 value->surface.secondary = RrColorNew(inst, 0, 0, 0);
863 if (value->surface.border)
864 if (!read_color(db, inst, bcname,
865 &value->surface.border_color))
866 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
867 ret = TRUE;
868 }
869
870 g_free(bcname);
871 g_free(ctoname);
872 g_free(cname);
873 g_free(rclass);
874 return ret;
875 }
876
877 static void set_default_appearance(RrAppearance *a)
878 {
879 a->surface.grad = RR_SURFACE_SOLID;
880 a->surface.relief = RR_RELIEF_FLAT;
881 a->surface.bevel = RR_BEVEL_1;
882 a->surface.interlaced = FALSE;
883 a->surface.border = FALSE;
884 a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
885 a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
886 }
This page took 0.08602 seconds and 4 git commands to generate.