/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
theme.c for the Openbox window manager
+ Copyright (c) 2006 Mikael Magnusson
Copyright (c) 2003 Ben Jansens
This program is free software; you can redistribute it and/or modify
#include <stdlib.h>
#include <string.h>
-static XrmDatabase loaddb(RrTheme *theme, char *name);
-static gboolean read_int(XrmDatabase db, char *rname, int *value);
-static gboolean read_string(XrmDatabase db, char *rname, char **value);
+static XrmDatabase loaddb(RrTheme *theme, gchar *name);
+static gboolean read_bool(XrmDatabase db, gchar *rname, gboolean *value);
+static gboolean read_int(XrmDatabase db, gchar *rname, gint *value);
+static gboolean read_string(XrmDatabase db, gchar *rname, gchar **value);
static gboolean read_color(XrmDatabase db, const RrInstance *inst,
gchar *rname, RrColor **value);
static gboolean read_mask(const RrInstance *inst,
static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
static void set_default_appearance(RrAppearance *a);
-RrTheme* RrThemeNew(const RrInstance *inst, gchar *name)
+RrTheme* RrThemeNew(const RrInstance *inst, gchar *name,
+ RrFont *active_window_font, RrFont *inactive_window_font,
+ RrFont *menu_title_font, RrFont *menu_item_font)
{
XrmDatabase db = NULL;
RrJustify winjust, mtitlejust;
+ gboolean b;
gchar *str;
- gchar *font_str;
RrTheme *theme;
+ gint offset;
+ gint tint;
theme = g_new0(RrTheme, 1);
theme->a_clear = RrAppearanceNew(inst, 0);
theme->a_clear_tex = RrAppearanceNew(inst, 1);
- theme->app_hilite_bg = RrAppearanceNew(inst, 0);
- theme->app_unhilite_bg = RrAppearanceNew(inst, 0);
- theme->app_hilite_label = RrAppearanceNew(inst, 1);
- theme->app_unhilite_label = RrAppearanceNew(inst, 1);
-
if (name) {
db = loaddb(theme, name);
if (db == NULL) {
}
/* load the font stuff */
- if (!read_string(db, "window.active.label.text.font", &font_str))
- font_str = "arial,sans:bold:pixelsize=10:shadow=y:shadowtint=50";
-
- if (!(theme->win_font_focused = RrFontOpen(inst, font_str))) {
- RrThemeFree(theme);
- return NULL;
- }
- theme->win_font_height = RrFontHeight(theme->win_font_focused);
-
- if (!read_string(db, "window.inactive.label.text.font", &font_str))
- /* font_str will already be set to the last one */;
-
- if (!(theme->win_font_unfocused = RrFontOpen(inst, font_str))) {
- RrThemeFree(theme);
- return NULL;
- }
- theme->win_font_height = MAX(theme->win_font_height,
- RrFontHeight(theme->win_font_unfocused));
+ if (active_window_font) {
+ theme->win_font_focused = active_window_font;
+ RrFontRef(active_window_font);
+ } else
+ theme->win_font_focused = RrFontOpenDefault(inst);
+
+ if (inactive_window_font) {
+ theme->win_font_unfocused = inactive_window_font;
+ RrFontRef(inactive_window_font);
+ } else
+ theme->win_font_unfocused = RrFontOpenDefault(inst);
winjust = RR_JUSTIFY_LEFT;
if (read_string(db, "window.label.text.justify", &str)) {
winjust = RR_JUSTIFY_CENTER;
}
- if (!read_string(db, "menu.title.text.font", &font_str))
- font_str = "arial,sans:bold:pixelsize=12:shadow=y";
-
- if (!(theme->menu_title_font = RrFontOpen(inst, font_str))) {
- RrThemeFree(theme);
- return NULL;
- }
- theme->menu_title_font_height = RrFontHeight(theme->menu_title_font);
+ if (menu_title_font) {
+ theme->menu_title_font = menu_title_font;
+ RrFontRef(menu_title_font);
+ } else
+ theme->menu_title_font = RrFontOpenDefault(inst);
mtitlejust = RR_JUSTIFY_LEFT;
if (read_string(db, "menu.title.text.justify", &str)) {
mtitlejust = RR_JUSTIFY_CENTER;
}
- if (!read_string(db, "menu.items.font", &font_str))
- font_str = "arial,sans:bold:pixelsize=11:shadow=y";
-
- if (!(theme->menu_font = RrFontOpen(inst, font_str))) {
- RrThemeFree(theme);
- return NULL;
- }
- theme->menu_font_height = RrFontHeight(theme->menu_font);
+ if (menu_item_font) {
+ theme->menu_font = menu_item_font;
+ RrFontRef(menu_item_font);
+ } else
+ theme->menu_font = RrFontOpenDefault(inst);
/* load direct dimensions */
if (!read_int(db, "menu.overlap", &theme->menu_overlap) ||
} else {
{
guchar data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
- theme->max_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->max_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
{
guchar data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
- theme->max_toggled_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->max_toggled_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
theme->max_pressed_mask = RrPixmapMaskCopy(theme->max_mask);
theme->max_disabled_mask = RrPixmapMaskCopy(theme->max_mask);
} else {
{
guchar data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
- theme->iconify_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->iconify_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
theme->iconify_pressed_mask = RrPixmapMaskCopy(theme->iconify_mask);
theme->iconify_disabled_mask = RrPixmapMaskCopy(theme->iconify_mask);
} else {
{
guchar data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
- theme->desk_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->desk_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
{
guchar data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
theme->desk_toggled_mask = RrPixmapMaskNew(inst, 7, 7,
- (char*)data);
+ (gchar*)data);
}
theme->desk_pressed_mask = RrPixmapMaskCopy(theme->desk_mask);
theme->desk_disabled_mask = RrPixmapMaskCopy(theme->desk_mask);
} else {
{
guchar data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
- theme->shade_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->shade_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
{
guchar data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
theme->shade_toggled_mask = RrPixmapMaskNew(inst, 7, 7,
- (char*)data);
+ (gchar*)data);
}
theme->shade_pressed_mask = RrPixmapMaskCopy(theme->shade_mask);
theme->shade_disabled_mask = RrPixmapMaskCopy(theme->shade_mask);
} else {
{
guchar data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
- theme->close_mask = RrPixmapMaskNew(inst, 7, 7, (char*)data);
+ theme->close_mask = RrPixmapMaskNew(inst, 7, 7, (gchar*)data);
}
theme->close_pressed_mask = RrPixmapMaskCopy(theme->close_mask);
theme->close_disabled_mask = RrPixmapMaskCopy(theme->close_mask);
if (!read_mask(inst, "bullet.xbm", theme, &theme->menu_bullet_mask)) {
guchar data[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01 };
- theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (char*)data);
+ theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
}
/* read the decoration textures */
set_default_appearance(theme->a_menu_selected);
/* read the appearances for rendering non-decorations */
- if (!read_appearance(db, inst,
- "window.active.title.bg", theme->app_hilite_bg,
- FALSE))
- set_default_appearance(theme->app_hilite_bg);
- if (!read_appearance(db, inst,
- "window.active.label.bg", theme->app_hilite_label,
- TRUE))
- set_default_appearance(theme->app_hilite_label);
+ theme->app_hilite_bg = RrAppearanceCopy(theme->a_focused_title);
+ theme->app_hilite_label = RrAppearanceCopy(theme->a_focused_label);
if (theme->a_focused_label->surface.grad != RR_SURFACE_PARENTREL)
theme->app_hilite_fg = RrAppearanceCopy(theme->a_focused_label);
else
theme->app_hilite_fg = RrAppearanceCopy(theme->a_focused_title);
- if (!read_appearance(db, inst,
- "window.inactive.title.bg", theme->app_unhilite_bg,
- FALSE))
- set_default_appearance(theme->app_unhilite_bg);
- if (!read_appearance(db, inst,
- "window.inactive.label.bg", theme->app_unhilite_label,
- TRUE))
- set_default_appearance(theme->app_unhilite_label);
+ theme->app_unhilite_bg = RrAppearanceCopy(theme->a_unfocused_title);
+ theme->app_unhilite_label = RrAppearanceCopy(theme->a_unfocused_label);
if (theme->a_unfocused_label->surface.grad != RR_SURFACE_PARENTREL)
theme->app_unhilite_fg = RrAppearanceCopy(theme->a_unfocused_label);
else
/* read buttons textures */
if (!read_appearance(db, inst,
"window.active.button.disabled.bg",
- theme->a_disabled_focused_max,
+ theme->a_disabled_focused_max,
TRUE))
set_default_appearance(theme->a_disabled_focused_max);
if (!read_appearance(db, inst,
"window.inactive.button.disabled.bg",
- theme->a_disabled_unfocused_max,
+ theme->a_disabled_unfocused_max,
TRUE))
set_default_appearance(theme->a_disabled_unfocused_max);
if (!read_appearance(db, inst,
"window.active.button.pressed.bg",
- theme->a_focused_pressed_max,
+ theme->a_focused_pressed_max,
TRUE))
set_default_appearance(theme->a_focused_pressed_max);
if (!read_appearance(db, inst,
theme->app_hilite_label->texture[0].data.text.color =
theme->title_focused_color;
+ if (read_bool(db, "window.active.label.text.shadow", &b) && b) {
+ if (!read_int(db, "window.active.label.text.shadow.offset", &offset))
+ offset = 1;
+
+ if (!read_int(db, "window.active.label.text.shadow.tint", &tint))
+ tint = 50;
+ tint = (tint > 100 ? 100 : (tint < -100 ? -100 : tint));
+ } else {
+ offset = 0;
+ tint = 50;
+ }
+ theme->a_focused_label->texture[0].data.text.shadow_offset =
+ theme->app_hilite_label->texture[0].data.text.shadow_offset = offset;
+ theme->a_focused_label->texture[0].data.text.shadow_tint =
+ theme->app_hilite_label->texture[0].data.text.shadow_tint = tint;
+
theme->a_unfocused_label->texture[0].type =
theme->app_unhilite_label->texture[0].type = RR_TEXTURE_TEXT;
theme->a_unfocused_label->texture[0].data.text.justify = winjust;
theme->app_unhilite_label->texture[0].data.text.color =
theme->title_unfocused_color;
+ if (read_bool(db, "window.inactive.label.text.shadow", &b) && b) {
+ if (!read_int(db, "window.inactive.label.text.shadow.offset", &offset))
+ offset = 1;
+
+ if (!read_int(db, "window.inactive.label.text.shadow.tint", &tint))
+ tint = 50;
+ tint = (tint > 100 ? 100 : (tint < -100 ? -100 : tint));
+ } else {
+ offset = 0;
+ tint = 50;
+ }
+ theme->a_unfocused_label->texture[0].data.text.shadow_offset =
+ theme->app_unhilite_label->texture[0].data.text.shadow_offset =
+ offset;
+ theme->a_unfocused_label->texture[0].data.text.shadow_tint =
+ theme->app_unhilite_label->texture[0].data.text.shadow_tint = tint;
+
theme->a_menu_title->texture[0].type = RR_TEXTURE_TEXT;
theme->a_menu_title->texture[0].data.text.justify = mtitlejust;
theme->a_menu_title->texture[0].data.text.font = theme->menu_title_font;
theme->a_menu_title->texture[0].data.text.color = theme->menu_title_color;
+ if (read_bool(db, "menu.title.text.shadow", &b) && b) {
+ if (!read_int(db, "menu.title.text.shadow.offset", &offset))
+ offset = 1;
+
+ if (!read_int(db, "menu.title.text.shadow.tint", &tint))
+ tint = 50;
+ tint = (tint > 100 ? 100 : (tint < -100 ? -100 : tint));
+ } else {
+ offset = 0;
+ tint = 50;
+ }
+ theme->a_menu_title->texture[0].data.text.shadow_offset = offset;
+ theme->a_menu_title->texture[0].data.text.shadow_tint = tint;
+
theme->a_menu_text_normal->texture[0].type =
theme->a_menu_text_disabled->texture[0].type =
theme->a_menu_text_selected->texture[0].type = RR_TEXTURE_TEXT;
theme->a_menu_text_selected->texture[0].data.text.color =
theme->menu_selected_color;
+ if (read_bool(db, "menu.items.text.shadow", &b) && b) {
+ if (!read_int(db, "menu.items.text.shadow.offset", &offset))
+ offset = 1;
+
+ if (!read_int(db, "menu.items.text.shadow.tint", &tint))
+ tint = 50;
+ tint = (tint > 100 ? 100 : (tint < -100 ? -100 : tint));
+ } else {
+ offset = 0;
+ tint = 50;
+ }
+ theme->a_menu_text_normal->texture[0].data.text.shadow_offset =
+ theme->a_menu_text_disabled->texture[0].data.text.shadow_offset =
+ theme->a_menu_text_selected->texture[0].data.text.shadow_offset =
+ offset;
+ theme->a_menu_text_normal->texture[0].data.text.shadow_tint =
+ theme->a_menu_text_disabled->texture[0].data.text.shadow_tint =
+ theme->a_menu_text_selected->texture[0].data.text.shadow_tint = tint;
+
theme->a_disabled_focused_max->texture[0].type =
theme->a_disabled_unfocused_max->texture[0].type =
theme->a_hover_focused_max->texture[0].type =
XrmDestroyDatabase(db);
+ /* set the font heights */
+ theme->win_font_height = RrFontHeight
+ (theme->win_font_focused,
+ theme->a_focused_label->texture[0].data.text.shadow_offset);
+ theme->win_font_height =
+ MAX(theme->win_font_height,
+ RrFontHeight
+ (theme->win_font_focused,
+ theme->a_unfocused_label->texture[0].data.text.shadow_offset));
+ theme->menu_title_font_height = RrFontHeight
+ (theme->menu_title_font,
+ theme->a_menu_title->texture[0].data.text.shadow_offset);
+ theme->menu_font_height = RrFontHeight
+ (theme->menu_font,
+ theme->a_menu_text_normal->texture[0].data.text.shadow_offset);
+
+ /* calculate some last extents */
{
gint ft, fb, fl, fr, ut, ub, ul, ur;
theme->padding * 2;
}
theme->button_size = theme->label_height - 2;
- theme->grip_width = theme->title_height * 1.5;
+ theme->grip_width = 25;
return theme;
}
}
}
-static XrmDatabase loaddb(RrTheme *theme, char *name)
+static XrmDatabase loaddb(RrTheme *theme, gchar *name)
{
GSList *it;
XrmDatabase db = NULL;
return db;
}
-static char *create_class_name(char *rname)
+static gchar *create_class_name(gchar *rname)
{
- char *rclass = g_strdup(rname);
- char *p = rclass;
+ gchar *rclass = g_strdup(rname);
+ gchar *p = rclass;
while (TRUE) {
*p = toupper(*p);
return rclass;
}
-static gboolean read_int(XrmDatabase db, char *rname, int *value)
+static gboolean read_bool(XrmDatabase db, gchar *rname, gint *value)
{
gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype, *end;
+ gchar *rclass = create_class_name(rname);
+ gchar *rettype;
XrmValue retvalue;
if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
retvalue.addr != NULL) {
- *value = (int)strtol(retvalue.addr, &end, 10);
+ if (!g_ascii_strcasecmp(retvalue.addr, "true")) {
+ *value = TRUE;
+ ret = TRUE;
+ } else if (!g_ascii_strcasecmp(retvalue.addr, "false")) {
+ *value = FALSE;
+ ret = TRUE;
+ }
+ }
+
+ g_free(rclass);
+ return ret;
+}
+
+static gboolean read_int(XrmDatabase db, gchar *rname, gint *value)
+{
+ gboolean ret = FALSE;
+ gchar *rclass = create_class_name(rname);
+ gchar *rettype, *end;
+ XrmValue retvalue;
+
+ if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+ retvalue.addr != NULL) {
+ *value = (gint)strtol(retvalue.addr, &end, 10);
if (end != retvalue.addr)
ret = TRUE;
}
return ret;
}
-static gboolean read_string(XrmDatabase db, char *rname, char **value)
+static gboolean read_string(XrmDatabase db, gchar *rname, gchar **value)
{
gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype;
+ gchar *rclass = create_class_name(rname);
+ gchar *rettype;
XrmValue retvalue;
if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
gchar *rname, RrColor **value)
{
gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *rettype;
+ gchar *rclass = create_class_name(rname);
+ gchar *rettype;
XrmValue retvalue;
if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
RrPixmapMask **value)
{
gboolean ret = FALSE;
- char *s;
- int hx, hy; /* ignored */
- unsigned int w, h;
- unsigned char *b;
+ gchar *s;
+ gint hx, hy; /* ignored */
+ guint w, h;
+ guchar *b;
s = g_build_filename(theme->path, maskname, NULL);
if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) {
ret = TRUE;
- *value = RrPixmapMaskNew(inst, w, h, (char*)b);
+ *value = RrPixmapMaskNew(inst, w, h, (gchar*)b);
XFree(b);
}
g_free(s);
gboolean *interlaced, gboolean *border,
gboolean allow_trans)
{
- char *t;
+ gchar *t;
/* convert to all lowercase */
for (t = tex; *t != '\0'; ++t)
*grad = RR_SURFACE_CROSS_DIAGONAL;
else if (strstr(tex, "pyramid") != NULL)
*grad = RR_SURFACE_PYRAMID;
+ else if (strstr(tex, "mirrorhorizontal") != NULL)
+ *grad = RR_SURFACE_MIRROR_HORIZONTAL;
else if (strstr(tex, "horizontal") != NULL)
*grad = RR_SURFACE_HORIZONTAL;
+ else if (strstr(tex, "splitvertical") != NULL)
+ *grad = RR_SURFACE_SPLIT_VERTICAL;
else if (strstr(tex, "vertical") != NULL)
*grad = RR_SURFACE_VERTICAL;
else
*relief = RR_RELIEF_FLAT;
else
*relief = RR_RELIEF_RAISED;
-
+
*border = FALSE;
if (*relief == RR_RELIEF_FLAT) {
if (strstr(tex, "border") != NULL)
gboolean allow_trans)
{
gboolean ret = FALSE;
- char *rclass = create_class_name(rname);
- char *cname, *ctoname, *bcname, *icname;
- char *rettype;
+ gchar *rclass = create_class_name(rname);
+ gchar *cname, *ctoname, *bcname, *icname;
+ gchar *rettype;
XrmValue retvalue;
cname = g_strconcat(rname, ".color", NULL);