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