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