]> Dogcows Code - chaz/openbox/blob - render/theme.c
rename the button_dir var to data_dir.. pointless :>
[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(char *theme);
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(XrmDatabase db, const RrInstance *inst,
16 gchar *rname, gchar *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(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_strdup(name);
100 }
101 if (db == NULL) {
102 db = loaddb(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_strdup(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(db, inst,
219 "window.button.max.mask", name, &theme->max_unset_mask)){
220 if (!read_mask(db, inst,
221 "window.button.max.toggled.mask", name,
222 &theme->max_set_mask)) {
223 theme->max_set_mask = RrPixmapMaskCopy(theme->max_unset_mask);
224 }
225 } else {
226 {
227 char data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
228 theme->max_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
229 }
230 {
231 char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
232 theme->max_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
233 }
234 }
235
236 if (!read_mask(db, inst,
237 "window.button.icon.mask", name,
238 &theme->iconify_mask)) {
239 char data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
240 theme->iconify_mask = RrPixmapMaskNew(inst, 7, 7, data);
241 }
242
243 if (read_mask(db, inst,
244 "window.button.stick.mask", name,
245 &theme->desk_unset_mask)) {
246 if (!read_mask(db, inst, "window.button.stick.toggled.mask", name,
247 &theme->desk_set_mask)) {
248 theme->desk_set_mask =
249 RrPixmapMaskCopy(theme->desk_unset_mask);
250 }
251 } else {
252 {
253 char data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
254 theme->desk_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
255 }
256 {
257 char data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
258 theme->desk_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
259 }
260 }
261
262 if (read_mask(db, inst, "window.button.shade.mask", name,
263 &theme->shade_unset_mask)) {
264 if (!read_mask(db, inst, "window.button.shade.toggled.mask", name,
265 &theme->shade_set_mask)) {
266 theme->shade_set_mask =
267 RrPixmapMaskCopy(theme->shade_unset_mask);
268 }
269 } else {
270 {
271 char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
272 theme->shade_unset_mask = RrPixmapMaskNew(inst, 7, 7, data);
273 }
274 {
275 char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
276 theme->shade_set_mask = RrPixmapMaskNew(inst, 7, 7, data);
277 }
278 }
279
280 if (!read_mask(db, inst, "window.button.close.mask", name,
281 &theme->close_mask)) {
282 char data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
283 theme->close_mask = RrPixmapMaskNew(inst, 7, 7, data);
284 }
285
286 /* read the decoration textures */
287 if (!read_appearance(db, inst,
288 "window.title.focus", theme->a_focused_title))
289 set_default_appearance(theme->a_focused_title);
290 if (!read_appearance(db, inst,
291 "window.title.unfocus", theme->a_unfocused_title))
292 set_default_appearance(theme->a_unfocused_title);
293 if (!read_appearance(db, inst,
294 "window.label.focus", theme->a_focused_label))
295 set_default_appearance(theme->a_focused_label);
296 if (!read_appearance(db, inst,
297 "window.label.unfocus", theme->a_unfocused_label))
298 set_default_appearance(theme->a_unfocused_label);
299 if (!read_appearance(db, inst,
300 "window.handle.focus", theme->a_focused_handle))
301 set_default_appearance(theme->a_focused_handle);
302 if (!read_appearance(db, inst,
303 "window.handle.unfocus",theme->a_unfocused_handle))
304 set_default_appearance(theme->a_unfocused_handle);
305 if (!read_appearance(db, inst,
306 "window.grip.focus", theme->a_focused_grip))
307 set_default_appearance(theme->a_focused_grip);
308 if (!read_appearance(db, inst,
309 "window.grip.unfocus", theme->a_unfocused_grip))
310 set_default_appearance(theme->a_unfocused_grip);
311 if (!read_appearance(db, inst,
312 "menu.frame", theme->a_menu))
313 set_default_appearance(theme->a_menu);
314 if (!read_appearance(db, inst,
315 "menu.title", theme->a_menu_title))
316 set_default_appearance(theme->a_menu_title);
317 if (!read_appearance(db, inst,
318 "menu.hilite", theme->a_menu_hilite))
319 set_default_appearance(theme->a_menu_hilite);
320
321 /* read the appearances for rendering non-decorations */
322 if (!read_appearance(db, inst,
323 "window.title.focus", theme->app_hilite_bg))
324 set_default_appearance(theme->app_hilite_bg);
325 if (!read_appearance(db, inst,
326 "window.label.focus", theme->app_hilite_label))
327 set_default_appearance(theme->app_hilite_label);
328 if (!read_appearance(db, inst,
329 "window.title.unfocus", theme->app_unhilite_bg))
330 set_default_appearance(theme->app_unhilite_bg);
331 if (!read_appearance(db, inst,
332 "window.label.unfocus", theme->app_unhilite_label))
333 set_default_appearance(theme->app_unhilite_label);
334
335 /* read buttons textures */
336 if (!read_appearance(db, inst,
337 "window.button.pressed.focus",
338 theme->a_focused_pressed_max))
339 if (!read_appearance(db, inst,
340 "window.button.pressed",
341 theme->a_focused_pressed_max))
342 set_default_appearance(theme->a_focused_pressed_max);
343 if (!read_appearance(db, inst,
344 "window.button.pressed.unfocus",
345 theme->a_unfocused_pressed_max))
346 if (!read_appearance(db, inst,
347 "window.button.pressed",
348 theme->a_unfocused_pressed_max))
349 set_default_appearance(theme->a_unfocused_pressed_max);
350 if (!read_appearance(db, inst,
351 "window.button.focus",
352 theme->a_focused_unpressed_max))
353 set_default_appearance(theme->a_focused_unpressed_max);
354 if (!read_appearance(db, inst,
355 "window.button.unfocus",
356 theme->a_unfocused_unpressed_max))
357 set_default_appearance(theme->a_unfocused_unpressed_max);
358
359 theme->a_unfocused_unpressed_close =
360 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
361 theme->a_unfocused_pressed_close =
362 RrAppearanceCopy(theme->a_unfocused_pressed_max);
363 theme->a_focused_unpressed_close =
364 RrAppearanceCopy(theme->a_focused_unpressed_max);
365 theme->a_focused_pressed_close =
366 RrAppearanceCopy(theme->a_focused_pressed_max);
367 theme->a_unfocused_unpressed_desk =
368 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
369 theme->a_unfocused_pressed_desk =
370 RrAppearanceCopy(theme->a_unfocused_pressed_max);
371 theme->a_unfocused_pressed_set_desk =
372 RrAppearanceCopy(theme->a_unfocused_pressed_max);
373 theme->a_focused_unpressed_desk =
374 RrAppearanceCopy(theme->a_focused_unpressed_max);
375 theme->a_focused_pressed_desk =
376 RrAppearanceCopy(theme->a_focused_pressed_max);
377 theme->a_focused_pressed_set_desk =
378 RrAppearanceCopy(theme->a_focused_pressed_max);
379 theme->a_unfocused_unpressed_shade =
380 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
381 theme->a_unfocused_pressed_shade =
382 RrAppearanceCopy(theme->a_unfocused_pressed_max);
383 theme->a_unfocused_pressed_set_shade =
384 RrAppearanceCopy(theme->a_unfocused_pressed_max);
385 theme->a_focused_unpressed_shade =
386 RrAppearanceCopy(theme->a_focused_unpressed_max);
387 theme->a_focused_pressed_shade =
388 RrAppearanceCopy(theme->a_focused_pressed_max);
389 theme->a_focused_pressed_set_shade =
390 RrAppearanceCopy(theme->a_focused_pressed_max);
391 theme->a_unfocused_unpressed_iconify =
392 RrAppearanceCopy(theme->a_unfocused_unpressed_max);
393 theme->a_unfocused_pressed_iconify =
394 RrAppearanceCopy(theme->a_unfocused_pressed_max);
395 theme->a_focused_unpressed_iconify =
396 RrAppearanceCopy(theme->a_focused_unpressed_max);
397 theme->a_focused_pressed_iconify =
398 RrAppearanceCopy(theme->a_focused_pressed_max);
399 theme->a_unfocused_pressed_set_max =
400 RrAppearanceCopy(theme->a_unfocused_pressed_max);
401 theme->a_focused_pressed_set_max =
402 RrAppearanceCopy(theme->a_focused_pressed_max);
403
404 theme->a_icon->surface.grad = RR_SURFACE_PARENTREL;
405
406 /* set up the textures */
407 theme->a_focused_label->texture[0].type =
408 theme->app_hilite_label->texture[0].type = RR_TEXTURE_TEXT;
409 theme->a_focused_label->texture[0].data.text.justify = winjust;
410 theme->app_hilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
411 theme->a_focused_label->texture[0].data.text.font =
412 theme->app_hilite_label->texture[0].data.text.font = theme->winfont;
413 theme->a_focused_label->texture[0].data.text.color =
414 theme->app_hilite_label->texture[0].data.text.color =
415 theme->title_focused_color;
416
417 theme->a_unfocused_label->texture[0].type =
418 theme->app_unhilite_label->texture[0].type = RR_TEXTURE_TEXT;
419 theme->a_unfocused_label->texture[0].data.text.justify = winjust;
420 theme->app_unhilite_label->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
421 theme->a_unfocused_label->texture[0].data.text.font =
422 theme->app_unhilite_label->texture[0].data.text.font = theme->winfont;
423 theme->a_unfocused_label->texture[0].data.text.color =
424 theme->app_unhilite_label->texture[0].data.text.color =
425 theme->title_unfocused_color;
426
427 theme->a_menu_title->texture[0].type = RR_TEXTURE_TEXT;
428 theme->a_menu_title->texture[0].data.text.justify = mtitlejust;
429 theme->a_menu_title->texture[0].data.text.font = theme->mtitlefont;
430 theme->a_menu_title->texture[0].data.text.color = theme->menu_title_color;
431
432 theme->a_menu_item->surface.grad =
433 theme->a_menu_disabled->surface.grad =
434 theme->app_icon->surface.grad = RR_SURFACE_PARENTREL;
435
436 theme->a_menu_item->texture[0].type =
437 theme->a_menu_disabled->texture[0].type =
438 theme->a_menu_hilite->texture[0].type = RR_TEXTURE_TEXT;
439 theme->a_menu_item->texture[0].data.text.justify =
440 theme->a_menu_disabled->texture[0].data.text.justify =
441 theme->a_menu_hilite->texture[0].data.text.justify = mjust;
442 theme->a_menu_item->texture[0].data.text.font =
443 theme->a_menu_disabled->texture[0].data.text.font =
444 theme->a_menu_hilite->texture[0].data.text.font = theme->mfont;
445 theme->a_menu_item->texture[0].data.text.color = theme->menu_color;
446 theme->a_menu_disabled->texture[0].data.text.color =
447 theme->menu_disabled_color;
448 theme->a_menu_hilite->texture[0].data.text.color =
449 theme->menu_hilite_color;
450
451 theme->a_focused_unpressed_max->texture[0].type =
452 theme->a_focused_pressed_max->texture[0].type =
453 theme->a_focused_pressed_set_max->texture[0].type =
454 theme->a_unfocused_unpressed_max->texture[0].type =
455 theme->a_unfocused_pressed_max->texture[0].type =
456 theme->a_unfocused_pressed_set_max->texture[0].type =
457 theme->a_focused_unpressed_close->texture[0].type =
458 theme->a_focused_pressed_close->texture[0].type =
459 theme->a_unfocused_unpressed_close->texture[0].type =
460 theme->a_unfocused_pressed_close->texture[0].type =
461 theme->a_focused_unpressed_desk->texture[0].type =
462 theme->a_focused_pressed_desk->texture[0].type =
463 theme->a_focused_pressed_set_desk->texture[0].type =
464 theme->a_unfocused_unpressed_desk->texture[0].type =
465 theme->a_unfocused_pressed_desk->texture[0].type =
466 theme->a_unfocused_pressed_set_desk->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_focused_unpressed_iconify->texture[0].type =
474 theme->a_focused_pressed_iconify->texture[0].type =
475 theme->a_unfocused_unpressed_iconify->texture[0].type =
476 theme->a_unfocused_pressed_iconify->texture[0].type = RR_TEXTURE_MASK;
477 theme->a_focused_unpressed_max->texture[0].data.mask.mask =
478 theme->a_unfocused_unpressed_max->texture[0].data.mask.mask =
479 theme->a_focused_pressed_max->texture[0].data.mask.mask =
480 theme->a_unfocused_pressed_max->texture[0].data.mask.mask =
481 theme->max_unset_mask;
482 theme->a_focused_pressed_set_max->texture[0].data.mask.mask =
483 theme->a_unfocused_pressed_set_max->texture[0].data.mask.mask =
484 theme->max_set_mask;
485 theme->a_focused_pressed_close->texture[0].data.mask.mask =
486 theme->a_unfocused_pressed_close->texture[0].data.mask.mask =
487 theme->a_focused_unpressed_close->texture[0].data.mask.mask =
488 theme->a_unfocused_unpressed_close->texture[0].data.mask.mask =
489 theme->close_mask;
490 theme->a_focused_unpressed_desk->texture[0].data.mask.mask =
491 theme->a_unfocused_unpressed_desk->texture[0].data.mask.mask =
492 theme->a_focused_pressed_desk->texture[0].data.mask.mask =
493 theme->a_unfocused_pressed_desk->texture[0].data.mask.mask =
494 theme->desk_unset_mask;
495 theme->a_focused_pressed_set_desk->texture[0].data.mask.mask =
496 theme->a_unfocused_pressed_set_desk->texture[0].data.mask.mask =
497 theme->desk_set_mask;
498 theme->a_focused_unpressed_shade->texture[0].data.mask.mask =
499 theme->a_unfocused_unpressed_shade->texture[0].data.mask.mask =
500 theme->a_focused_pressed_shade->texture[0].data.mask.mask =
501 theme->a_unfocused_pressed_shade->texture[0].data.mask.mask =
502 theme->shade_unset_mask;
503 theme->a_focused_pressed_set_shade->texture[0].data.mask.mask =
504 theme->a_unfocused_pressed_set_shade->texture[0].data.mask.mask =
505 theme->shade_set_mask;
506 theme->a_focused_unpressed_iconify->texture[0].data.mask.mask =
507 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.mask =
508 theme->a_focused_pressed_iconify->texture[0].data.mask.mask =
509 theme->a_unfocused_pressed_iconify->texture[0].data.mask.mask =
510 theme->iconify_mask;
511 theme->a_focused_unpressed_max->texture[0].data.mask.color =
512 theme->a_focused_pressed_max->texture[0].data.mask.color =
513 theme->a_focused_pressed_set_max->texture[0].data.mask.color =
514 theme->a_focused_unpressed_close->texture[0].data.mask.color =
515 theme->a_focused_pressed_close->texture[0].data.mask.color =
516 theme->a_focused_unpressed_desk->texture[0].data.mask.color =
517 theme->a_focused_pressed_desk->texture[0].data.mask.color =
518 theme->a_focused_pressed_set_desk->texture[0].data.mask.color =
519 theme->a_focused_unpressed_shade->texture[0].data.mask.color =
520 theme->a_focused_pressed_shade->texture[0].data.mask.color =
521 theme->a_focused_pressed_set_shade->texture[0].data.mask.color =
522 theme->a_focused_unpressed_iconify->texture[0].data.mask.color =
523 theme->a_focused_pressed_iconify->texture[0].data.mask.color =
524 theme->titlebut_focused_color;
525 theme->a_unfocused_unpressed_max->texture[0].data.mask.color =
526 theme->a_unfocused_pressed_max->texture[0].data.mask.color =
527 theme->a_unfocused_pressed_set_max->texture[0].data.mask.color =
528 theme->a_unfocused_unpressed_close->texture[0].data.mask.color =
529 theme->a_unfocused_pressed_close->texture[0].data.mask.color =
530 theme->a_unfocused_unpressed_desk->texture[0].data.mask.color =
531 theme->a_unfocused_pressed_desk->texture[0].data.mask.color =
532 theme->a_unfocused_pressed_set_desk->texture[0].data.mask.color =
533 theme->a_unfocused_unpressed_shade->texture[0].data.mask.color =
534 theme->a_unfocused_pressed_shade->texture[0].data.mask.color =
535 theme->a_unfocused_pressed_set_shade->texture[0].data.mask.color =
536 theme->a_unfocused_unpressed_iconify->texture[0].data.mask.color =
537 theme->a_unfocused_pressed_iconify->texture[0].data.mask.color =
538 theme->titlebut_unfocused_color;
539
540 XrmDestroyDatabase(db);
541
542 theme->label_height = theme->winfont_height;
543 theme->title_height = theme->label_height + theme->bevel * 2;
544 theme->button_size = theme->label_height - 2;
545 theme->grip_width = theme->button_size * 2;
546
547 return theme;
548 }
549
550 void RrThemeFree(RrTheme *theme)
551 {
552 if (theme) {
553 g_free(theme->name);
554
555 RrColorFree(theme->b_color);
556 RrColorFree(theme->cb_unfocused_color);
557 RrColorFree(theme->cb_focused_color);
558 RrColorFree(theme->title_unfocused_color);
559 RrColorFree(theme->title_focused_color);
560 RrColorFree(theme->titlebut_unfocused_color);
561 RrColorFree(theme->titlebut_focused_color);
562 RrColorFree(theme->menu_color);
563 RrColorFree(theme->menu_title_color);
564 RrColorFree(theme->menu_disabled_color);
565 RrColorFree(theme->menu_hilite_color);
566
567 RrPixmapMaskFree(theme->max_set_mask);
568 RrPixmapMaskFree(theme->max_unset_mask);
569 RrPixmapMaskFree(theme->desk_set_mask);
570 RrPixmapMaskFree(theme->desk_unset_mask);
571 RrPixmapMaskFree(theme->shade_set_mask);
572 RrPixmapMaskFree(theme->shade_unset_mask);
573 RrPixmapMaskFree(theme->iconify_mask);
574 RrPixmapMaskFree(theme->close_mask);
575
576 RrFontClose(theme->winfont);
577 RrFontClose(theme->mtitlefont);
578 RrFontClose(theme->mfont);
579
580 g_free(theme->title_layout);
581
582 RrAppearanceFree(theme->a_focused_unpressed_max);
583 RrAppearanceFree(theme->a_focused_pressed_max);
584 RrAppearanceFree(theme->a_focused_pressed_set_max);
585 RrAppearanceFree(theme->a_unfocused_unpressed_max);
586 RrAppearanceFree(theme->a_unfocused_pressed_max);
587 RrAppearanceFree(theme->a_unfocused_pressed_set_max);
588 RrAppearanceFree(theme->a_focused_unpressed_close);
589 RrAppearanceFree(theme->a_focused_pressed_close);
590 RrAppearanceFree(theme->a_unfocused_unpressed_close);
591 RrAppearanceFree(theme->a_unfocused_pressed_close);
592 RrAppearanceFree(theme->a_focused_unpressed_desk);
593 RrAppearanceFree(theme->a_focused_pressed_desk);
594 RrAppearanceFree(theme->a_unfocused_unpressed_desk);
595 RrAppearanceFree(theme->a_unfocused_pressed_desk);
596 RrAppearanceFree(theme->a_focused_unpressed_shade);
597 RrAppearanceFree(theme->a_focused_pressed_shade);
598 RrAppearanceFree(theme->a_unfocused_unpressed_shade);
599 RrAppearanceFree(theme->a_unfocused_pressed_shade);
600 RrAppearanceFree(theme->a_focused_unpressed_iconify);
601 RrAppearanceFree(theme->a_focused_pressed_iconify);
602 RrAppearanceFree(theme->a_unfocused_unpressed_iconify);
603 RrAppearanceFree(theme->a_unfocused_pressed_iconify);
604 RrAppearanceFree(theme->a_focused_grip);
605 RrAppearanceFree(theme->a_unfocused_grip);
606 RrAppearanceFree(theme->a_focused_title);
607 RrAppearanceFree(theme->a_unfocused_title);
608 RrAppearanceFree(theme->a_focused_label);
609 RrAppearanceFree(theme->a_unfocused_label);
610 RrAppearanceFree(theme->a_icon);
611 RrAppearanceFree(theme->a_focused_handle);
612 RrAppearanceFree(theme->a_unfocused_handle);
613 RrAppearanceFree(theme->a_menu);
614 RrAppearanceFree(theme->a_menu_title);
615 RrAppearanceFree(theme->a_menu_item);
616 RrAppearanceFree(theme->a_menu_disabled);
617 RrAppearanceFree(theme->a_menu_hilite);
618 RrAppearanceFree(theme->app_hilite_bg);
619 RrAppearanceFree(theme->app_unhilite_bg);
620 RrAppearanceFree(theme->app_hilite_label);
621 RrAppearanceFree(theme->app_unhilite_label);
622 RrAppearanceFree(theme->app_icon);
623 }
624 }
625
626 static XrmDatabase loaddb(char *theme)
627 {
628 XrmDatabase db;
629
630 db = XrmGetFileDatabase(theme);
631 if (db == NULL) {
632 char *s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
633 theme, NULL);
634 db = XrmGetFileDatabase(s);
635 g_free(s);
636 }
637 if (db == NULL) {
638 char *s = g_build_filename(THEMEDIR, theme, NULL);
639 db = XrmGetFileDatabase(s);
640 g_free(s);
641 }
642 return db;
643 }
644
645 static char *create_class_name(char *rname)
646 {
647 char *rclass = g_strdup(rname);
648 char *p = rclass;
649
650 while (TRUE) {
651 *p = toupper(*p);
652 p = strchr(p+1, '.');
653 if (p == NULL) break;
654 ++p;
655 if (*p == '\0') break;
656 }
657 return rclass;
658 }
659
660 static gboolean read_int(XrmDatabase db, char *rname, int *value)
661 {
662 gboolean ret = FALSE;
663 char *rclass = create_class_name(rname);
664 char *rettype, *end;
665 XrmValue retvalue;
666
667 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
668 retvalue.addr != NULL) {
669 *value = (int)strtol(retvalue.addr, &end, 10);
670 if (end != retvalue.addr)
671 ret = TRUE;
672 }
673
674 g_free(rclass);
675 return ret;
676 }
677
678 static gboolean read_string(XrmDatabase db, char *rname, char **value)
679 {
680 gboolean ret = FALSE;
681 char *rclass = create_class_name(rname);
682 char *rettype;
683 XrmValue retvalue;
684
685 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
686 retvalue.addr != NULL) {
687 *value = retvalue.addr;
688 ret = TRUE;
689 }
690
691 g_free(rclass);
692 return ret;
693 }
694
695 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
696 gchar *rname, RrColor **value)
697 {
698 gboolean ret = FALSE;
699 char *rclass = create_class_name(rname);
700 char *rettype;
701 XrmValue retvalue;
702
703 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
704 retvalue.addr != NULL) {
705 RrColor *c = RrColorParse(inst, retvalue.addr);
706 if (c != NULL) {
707 *value = c;
708 ret = TRUE;
709 }
710 }
711
712 g_free(rclass);
713 return ret;
714 }
715
716 static gboolean read_mask(XrmDatabase db, const RrInstance *inst,
717 gchar *rname, gchar *theme,
718 RrPixmapMask **value)
719 {
720 gboolean ret = FALSE;
721 char *rclass = create_class_name(rname);
722 char *rettype;
723 char *s;
724 char *data_dir;
725 XrmValue retvalue;
726 int hx, hy; /* ignored */
727 unsigned int w, h;
728 unsigned char *b;
729
730 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
731 retvalue.addr != NULL) {
732
733 data_dir = g_strdup_printf("%s_data", theme);
734
735 s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
736 data_dir, retvalue.addr, NULL);
737
738 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
739 ret = TRUE;
740 else {
741 g_free(s);
742 s = g_build_filename(THEMEDIR, data_dir, retvalue.addr, NULL);
743
744 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
745 ret = TRUE;
746 else {
747 char *themename;
748
749 g_free(s);
750 themename = g_path_get_basename(theme);
751 s = g_strdup_printf("%s/%s_data/%s", theme,
752 themename, retvalue.addr);
753 g_free(themename);
754 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) ==
755 BitmapSuccess)
756 ret = TRUE;
757 else
758 g_message("Unable to find bitmap '%s'", retvalue.addr);
759 }
760 }
761
762 if (ret) {
763 *value = RrPixmapMaskNew(inst, w, h, (char*)b);
764 XFree(b);
765 }
766
767 g_free(s);
768 g_free(data_dir);
769 }
770
771 g_free(rclass);
772 return ret;
773 }
774
775 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
776 RrReliefType *relief, RrBevelType *bevel,
777 gboolean *interlaced, gboolean *border)
778 {
779 char *t;
780
781 /* convert to all lowercase */
782 for (t = tex; *t != '\0'; ++t)
783 *t = g_ascii_tolower(*t);
784
785 if (strstr(tex, "parentrelative") != NULL) {
786 *grad = RR_SURFACE_PARENTREL;
787 } else {
788 if (strstr(tex, "gradient") != NULL) {
789 if (strstr(tex, "crossdiagonal") != NULL)
790 *grad = RR_SURFACE_CROSS_DIAGONAL;
791 else if (strstr(tex, "pyramid") != NULL)
792 *grad = RR_SURFACE_PYRAMID;
793 else if (strstr(tex, "horizontal") != NULL)
794 *grad = RR_SURFACE_HORIZONTAL;
795 else if (strstr(tex, "vertical") != NULL)
796 *grad = RR_SURFACE_VERTICAL;
797 else
798 *grad = RR_SURFACE_DIAGONAL;
799 } else {
800 *grad = RR_SURFACE_SOLID;
801 }
802
803 if (strstr(tex, "sunken") != NULL)
804 *relief = RR_RELIEF_SUNKEN;
805 else if (strstr(tex, "flat") != NULL)
806 *relief = RR_RELIEF_FLAT;
807 else
808 *relief = RR_RELIEF_RAISED;
809
810 *border = FALSE;
811 if (*relief == RR_RELIEF_FLAT) {
812 if (strstr(tex, "border") != NULL)
813 *border = TRUE;
814 } else {
815 if (strstr(tex, "bevel2") != NULL)
816 *bevel = RR_BEVEL_2;
817 else
818 *bevel = RR_BEVEL_1;
819 }
820
821 if (strstr(tex, "interlaced") != NULL)
822 *interlaced = TRUE;
823 else
824 *interlaced = FALSE;
825 }
826 }
827
828
829 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
830 gchar *rname, RrAppearance *value)
831 {
832 gboolean ret = FALSE;
833 char *rclass = create_class_name(rname), *cname, *ctoname, *bcname;
834 char *rettype;
835 XrmValue retvalue;
836
837 cname = g_strconcat(rname, ".color", NULL);
838 ctoname = g_strconcat(rname, ".colorTo", NULL);
839 bcname = g_strconcat(rname, ".borderColor", NULL);
840
841 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
842 retvalue.addr != NULL) {
843 parse_appearance(retvalue.addr,
844 &value->surface.grad,
845 &value->surface.relief,
846 &value->surface.bevel,
847 &value->surface.interlaced,
848 &value->surface.border);
849 if (!read_color(db, inst, cname, &value->surface.primary))
850 value->surface.primary = RrColorNew(inst, 0, 0, 0);
851 if (!read_color(db, inst, ctoname, &value->surface.secondary))
852 value->surface.secondary = RrColorNew(inst, 0, 0, 0);
853 if (value->surface.border)
854 if (!read_color(db, inst, bcname,
855 &value->surface.border_color))
856 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
857 ret = TRUE;
858 }
859
860 g_free(bcname);
861 g_free(ctoname);
862 g_free(cname);
863 g_free(rclass);
864 return ret;
865 }
866
867 static void set_default_appearance(RrAppearance *a)
868 {
869 a->surface.grad = RR_SURFACE_SOLID;
870 a->surface.relief = RR_RELIEF_FLAT;
871 a->surface.bevel = RR_BEVEL_1;
872 a->surface.interlaced = FALSE;
873 a->surface.border = FALSE;
874 a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
875 a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
876 }
This page took 0.077782 seconds and 5 git commands to generate.