1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 frame_default_config.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
26 #include "render/render.h"
27 #include "render/color.h"
28 #include "render/font.h"
29 #include "render/mask.h"
30 #include "render/icon.h"
31 #include "obt/parse.h"
36 void load_pixmap(const gchar * theme_name, const gchar * base_name,
37 GdkPixbuf ** gp, Pixmap * p);
38 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value);
39 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value);
40 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
41 const gchar *rname, RrColor **value);
42 static gboolean read_mask(const RrInstance *inst, const gchar *path,
43 ObFrameThemeConfig *theme, const gchar *maskname, RrPixmapMask **value);
44 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
45 const gchar *rname, RrAppearance *value, gboolean allow_trans);
46 static int parse_inline_number(const char *p);
47 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
48 static void set_default_appearance(RrAppearance *a);
50 gint load_theme_config(const RrInstance *inst, const gchar *name,
51 const gchar * path, XrmDatabase db, RrFont *active_window_font,
52 RrFont *inactive_window_font, RrFont *menu_title_font,
53 RrFont *menu_item_font, RrFont *osd_font)
57 if (!read_int(db, "concept.border_width", &theme_config.border_width)) {
58 theme_config.border_width = 2;
60 if (!read_color(db, inst, "concept.focus_border_color",
61 &theme_config.focus_border_color)) {
62 theme_config.focus_border_color = RrColorNew(inst, 0, 0, 0);
65 if (!read_color(db, inst, "concept.focus_corner_color",
66 &theme_config.focus_corner_color)) {
67 theme_config.focus_corner_color = RrColorNew(inst, 0, 0, 0);
70 if (!read_color(db, inst, "concept.unfocus_border_color",
71 &theme_config.unfocus_border_color)) {
72 theme_config.focus_border_color = RrColorNew(inst, 0, 0, 0);
75 if (!read_color(db, inst, "concept.unfocus_corner_color",
76 &theme_config.unfocus_corner_color)) {
77 theme_config.focus_corner_color = RrColorNew(inst, 0, 0, 0);
80 theme_config.inst = inst;
81 theme_config.name = g_strdup(name ? name : DEFAULT_THEME);
83 gdk_pixbuf_xlib_init(plugin.ob_display, plugin.ob_screen);
85 load_pixmap(name, "focus-top.png", &theme_config.focus_top,
86 &theme_config.px_focus_top);
87 load_pixmap(name, "focus-left.png", &theme_config.focus_left,
88 &theme_config.px_focus_left);
89 load_pixmap(name, "focus-right.png", &theme_config.focus_right,
90 &theme_config.px_focus_right);
91 load_pixmap(name, "focus-bottom.png", &theme_config.focus_bottom,
92 &theme_config.px_focus_bottom);
94 load_pixmap(name, "unfocus-top.png", &theme_config.unfocus_top,
95 &theme_config.px_unfocus_top);
96 load_pixmap(name, "unfocus-left.png", &theme_config.unfocus_left,
97 &theme_config.px_unfocus_left);
98 load_pixmap(name, "unfocus-right.png", &theme_config.unfocus_right,
99 &theme_config.px_unfocus_right);
100 load_pixmap(name, "unfocus-bottom.png", &theme_config.unfocus_bottom,
101 &theme_config.px_unfocus_bottom);
103 load_pixmap(name, "focus-topleft.png", &theme_config.focus_topleft,
104 &theme_config.px_focus_topleft);
105 load_pixmap(name, "focus-bottomleft.png", &theme_config.focus_bottomleft,
106 &theme_config.px_focus_bottomleft);
107 load_pixmap(name, "focus-topright.png", &theme_config.focus_topright,
108 &theme_config.px_focus_topright);
109 load_pixmap(name, "focus-bottomright.png", &theme_config.focus_bottomright,
110 &theme_config.px_focus_bottomright);
112 load_pixmap(name, "unfocus-topleft.png", &theme_config.unfocus_topleft,
113 &theme_config.px_unfocus_topleft);
114 load_pixmap(name, "unfocus-bottomleft.png",
115 &theme_config.unfocus_bottomleft,
116 &theme_config.px_unfocus_bottomleft);
117 load_pixmap(name, "unfocus-topright.png", &theme_config.unfocus_topright,
118 &theme_config.px_unfocus_topright);
119 load_pixmap(name, "unfocus-bottomright.png",
120 &theme_config.unfocus_bottomright,
121 &theme_config.px_unfocus_bottomright);
126 void load_pixmap(const gchar * theme_name, const gchar * base_name,
127 GdkPixbuf ** gp, Pixmap * p)
129 gchar * s = g_build_filename(g_get_home_dir(), ".themes", theme_name,
130 "openbox-3", base_name, NULL);
131 ob_debug("Load file %s.\n", s);
132 *gp = gdk_pixbuf_new_from_file(s, NULL);
133 //GdkPixbuff * mask = NULL;
134 gdk_pixbuf_xlib_render_pixmap_and_mask(*gp, p, NULL, 128);
138 static gchar *create_class_name(const gchar *rname)
140 gchar *rclass = g_strdup(rname);
145 p = strchr(p+1, '.');
155 static gboolean read_int(XrmDatabase db, const gchar *rname, gint *value)
157 gboolean ret = FALSE;
158 gchar *rclass = create_class_name(rname);
159 gchar *rettype, *end;
162 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && retvalue.addr
164 *value = (gint)strtol(retvalue.addr, &end, 10);
165 if (end != retvalue.addr)
173 static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)
175 gboolean ret = FALSE;
176 gchar *rclass = create_class_name(rname);
180 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && retvalue.addr
182 *value = retvalue.addr;
190 static gboolean read_color(XrmDatabase db, const RrInstance *inst,
191 const gchar *rname, RrColor **value)
193 gboolean ret = FALSE;
194 gchar *rclass = create_class_name(rname);
198 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && retvalue.addr
200 RrColor *c = RrColorParse(inst, retvalue.addr);
211 static gboolean read_mask(const RrInstance *inst, const gchar *path,
212 ObFrameThemeConfig *theme, const gchar *maskname, RrPixmapMask **value)
214 gboolean ret = FALSE;
216 gint hx, hy; /* ignored */
220 s = g_build_filename(path, maskname, NULL);
221 if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) {
223 *value = RrPixmapMaskNew(inst, w, h, (gchar*)b);
231 static void parse_appearance(gchar *tex, RrSurfaceColorType *grad,
232 RrReliefType *relief, RrBevelType *bevel, gboolean *interlaced,
233 gboolean *border, gboolean allow_trans)
237 /* convert to all lowercase */
238 for (t = tex; *t != '\0'; ++t)
239 *t = g_ascii_tolower(*t);
241 if (allow_trans && strstr(tex, "parentrelative") != NULL) {
242 *grad = RR_SURFACE_PARENTREL;
245 if (strstr(tex, "gradient") != NULL) {
246 if (strstr(tex, "crossdiagonal") != NULL)
247 *grad = RR_SURFACE_CROSS_DIAGONAL;
248 else if (strstr(tex, "pyramid") != NULL)
249 *grad = RR_SURFACE_PYRAMID;
250 else if (strstr(tex, "mirrorhorizontal") != NULL)
251 *grad = RR_SURFACE_MIRROR_HORIZONTAL;
252 else if (strstr(tex, "horizontal") != NULL)
253 *grad = RR_SURFACE_HORIZONTAL;
254 else if (strstr(tex, "splitvertical") != NULL)
255 *grad = RR_SURFACE_SPLIT_VERTICAL;
256 else if (strstr(tex, "vertical") != NULL)
257 *grad = RR_SURFACE_VERTICAL;
259 *grad = RR_SURFACE_DIAGONAL;
262 *grad = RR_SURFACE_SOLID;
266 if (strstr(tex, "sunken") != NULL)
267 *relief = RR_RELIEF_SUNKEN;
268 else if (strstr(tex, "flat") != NULL)
269 *relief = RR_RELIEF_FLAT;
270 else if (strstr(tex, "raised") != NULL)
271 *relief = RR_RELIEF_RAISED;
273 *relief = (*grad == RR_SURFACE_PARENTREL) ? RR_RELIEF_FLAT
277 if (*relief == RR_RELIEF_FLAT) {
278 if (strstr(tex, "border") != NULL)
282 if (strstr(tex, "bevel2") != NULL)
288 if (strstr(tex, "interlaced") != NULL)
294 static gboolean read_appearance(XrmDatabase db, const RrInstance *inst,
295 const gchar *rname, RrAppearance *value, gboolean allow_trans)
297 gboolean ret = FALSE;
298 gchar *rclass = create_class_name(rname);
299 gchar *cname, *ctoname, *bcname, *icname, *hname, *sname;
300 gchar *csplitname, *ctosplitname;
305 cname = g_strconcat(rname, ".color", NULL);
306 ctoname = g_strconcat(rname, ".colorTo", NULL);
307 bcname = g_strconcat(rname, ".border.color", NULL);
308 icname = g_strconcat(rname, ".interlace.color", NULL);
309 hname = g_strconcat(rname, ".highlight", NULL);
310 sname = g_strconcat(rname, ".shadow", NULL);
311 csplitname = g_strconcat(rname, ".color.splitTo", NULL);
312 ctosplitname = g_strconcat(rname, ".colorTo.splitTo", NULL);
314 if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && retvalue.addr
316 parse_appearance(retvalue.addr, &value->surface.grad,
317 &value->surface.relief, &value->surface.bevel,
318 &value->surface.interlaced, &value->surface.border, allow_trans);
319 if (!read_color(db, inst, cname, &value->surface.primary))
320 value->surface.primary = RrColorNew(inst, 0, 0, 0);
321 if (!read_color(db, inst, ctoname, &value->surface.secondary))
322 value->surface.secondary = RrColorNew(inst, 0, 0, 0);
323 if (value->surface.border)
324 if (!read_color(db, inst, bcname, &value->surface.border_color))
325 value->surface.border_color = RrColorNew(inst, 0, 0, 0);
326 if (value->surface.interlaced)
327 if (!read_color(db, inst, icname, &value->surface.interlace_color))
328 value->surface.interlace_color = RrColorNew(inst, 0, 0, 0);
329 if (read_int(db, hname, &i) && i >= 0)
330 value->surface.bevel_light_adjust = i;
331 if (read_int(db, sname, &i) && i >= 0 && i <= 256)
332 value->surface.bevel_dark_adjust = i;
334 if (value->surface.grad == RR_SURFACE_SPLIT_VERTICAL) {
337 if (!read_color(db, inst, csplitname, &value->surface.split_primary)) {
338 r = value->surface.primary->r;
340 g = value->surface.primary->g;
342 b = value->surface.primary->b;
350 value->surface.split_primary = RrColorNew(inst, r, g, b);
353 if (!read_color(db, inst, ctosplitname,
354 &value->surface.split_secondary)) {
355 r = value->surface.secondary->r;
357 g = value->surface.secondary->g;
359 b = value->surface.secondary->b;
367 value->surface.split_secondary = RrColorNew(inst, r, g, b);
374 g_free(ctosplitname);
386 static int parse_inline_number(const char *p)
394 for (; isdigit(*p); ++p)
395 res = res * 10 + *p - '0';
400 static void set_default_appearance(RrAppearance *a)
402 a->surface.grad = RR_SURFACE_SOLID;
403 a->surface.relief = RR_RELIEF_FLAT;
404 a->surface.bevel = RR_BEVEL_1;
405 a->surface.interlaced = FALSE;
406 a->surface.border = FALSE;
407 a->surface.primary = RrColorNew(a->inst, 0, 0, 0);
408 a->surface.secondary = RrColorNew(a->inst, 0, 0, 0);
411 /* Reads the output from gimp's C-Source file format into valid RGBA data for
413 static RrPixel32* read_c_image(gint width, gint height, const guint8 *data)
418 p = im = g_memdup(data, width * height * sizeof(RrPixel32));
420 for (i = 0; i < width * height; ++i) {
421 guchar a = ((*p >> 24) & 0xff);
422 guchar b = ((*p >> 16) & 0xff);
423 guchar g = ((*p >> 8) & 0xff);
424 guchar r = ((*p >> 0) & 0xff);
426 *p = ((r << RrDefaultRedOffset) + (g << RrDefaultGreenOffset) + (b
427 << RrDefaultBlueOffset) + (a << RrDefaultAlphaOffset));