]> Dogcows Code - chaz/openbox/commitdiff
move the openbox engine into librender and the kernel. the theme is loaded and stored...
authorDana Jansens <danakj@orodu.net>
Sun, 13 Apr 2003 07:18:28 +0000 (07:18 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 13 Apr 2003 07:18:28 +0000 (07:18 +0000)
43 files changed:
Makefile.in
build/Makefile.engines [deleted file]
build/Makefile.engines.openbox [deleted file]
build/Makefile.kernel
build/Makefile.render
build/Makefile.themes.openbox [deleted file]
cwmcc/prop.c
cwmcc/root_props.c
cwmcc/root_props.h
engines/.cvsignore [deleted file]
engines/engineinterface.h [deleted file]
engines/openbox/.cvsignore [deleted file]
engines/openbox/obengine.c [deleted file]
engines/openbox/obengine.h [deleted file]
engines/openbox/obrender.c [deleted file]
engines/openbox/obrender.h [deleted file]
engines/openbox/obtheme.c [deleted file]
engines/openbox/obtheme.h [deleted file]
obcl/Makefile [moved from engines/openbox/Makefile with 71% similarity]
openbox/.cvsignore
openbox/action.c
openbox/client.c
openbox/config.h
openbox/engine.c [deleted file]
openbox/engine.h [deleted file]
openbox/event.c
openbox/focus.c
openbox/frame.c
openbox/frame.h
openbox/framerender.c [new file with mode: 0644]
openbox/framerender.h [new file with mode: 0644]
openbox/openbox.c
openbox/parse.l
openbox/parse.y
openbox/screen.c
plugins/keyboard/keyboard.c
plugins/mouse/mouse.c
render/.cvsignore
render/font.h
render/mask.h
render/render.h
render/theme.c [new file with mode: 0644]
render/theme.h [new file with mode: 0644]

index 97c293eb756ed494e0bf70974789a73c1a8b24e1..24e7fcd92e735fac6fc913415f05d13a57b6a257 100644 (file)
@@ -1,6 +1,6 @@
 include build/Makefile.incl
 
-targets = render cwmcc obcl kernel plugins engines themes data
+targets = render cwmcc obcl kernel plugins themes data
 
 all: libtool
        @for i in $(targets); do \
diff --git a/build/Makefile.engines b/build/Makefile.engines
deleted file mode 100644 (file)
index cc1cd84..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-include build/Makefile.incl
-
-all clean distclean:
-       @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.engines.openbox $@
-
-install:
-       @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.engines.openbox $@
-       $(LIBTOOL) --mode=finish $(DESTDIR)$(enginedir)
-
-uninstall:
-       @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.engines.openbox $@
-       -rmdir $(DESTDIR)$(enginedir)
-
-.PHONY: all clean distclean install uninstall
diff --git a/build/Makefile.engines.openbox b/build/Makefile.engines.openbox
deleted file mode 100644 (file)
index 3830dd2..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-include build/Makefile.incl
-
-dir = engines/openbox
-theme = operation
-
-CPPFLAGS += $(GLIB_CFLAGS) $(XFT_CFLAGS) -DG_LOG_DOMAIN=\"Engine-Openbox\" \
-            -DDEFAULT_THEME=\"$(theme)\" -DTHEMEDIR=\"$(themedir)/openbox\"
-LDFLAGS += -module -avoid-version
-
-target = openbox.la
-sources = obengine.c obtheme.c obrender.c
-
-srcdir := $(srcdir)/$(dir)
-target := $(addprefix $(dir)/,$(target))
-objects := $(addprefix $(dir)/,$(sources:.c=.lo))
-sources := $(addprefix $(srcdir)/,$(sources))
-deps := $(addprefix $(depdir)/,$(objects:.lo=.d))
-depdir := $(depdir)/$(dir)
-
-all: $(target)
-
-$(target): $(objects)
-       $(LINK) -rpath $(enginedir) -o $@ $^ $(LDFLAGS)
-
-$(dir)/%.lo: $(srcdir)/%.c $(depdir)/%.d
-       $(LTCOMPILE) -c -o $@ $<
-
-$(depdir)/%.d: $(srcdir)/%.c
-       @echo Building dependancies for $<
-       $(INSTALL) -d $(depdir)
-       @$(DEPCOMPILE) -w -MM -MF $@ -MQ $(<:.c=.lo) $<
-
-install:
-       $(INSTALL) -d $(DESTDIR)$(enginedir)/
-       $(LIBTOOL) --mode=install $(INSTALL) $(target) \
-               $(DESTDIR)$(enginedir)/$(notdir $(target))
-
-uninstall:
-       $(LTRM) $(DESTDIR)$(enginedir)/$(notdir $(target))
-
-clean:
-       $(LTCLEAN) $(target) $(objects)
-       $(RM) $(srcdir)/*\~
-
--include $(deps)
-
-.PHONY: all install uninstall clean distclean
index a58798e244a4b6e80f21b53fd395817f87b55e01..e0ccfa264a26cd0dbfb53f2bb7d247f50476b325 100644 (file)
@@ -9,8 +9,8 @@ LIBS += $(GLIB_LIBS) $(GMODULE_LIBS) $(XFT_LIBS) $(X_LIBS) $(XINERAMA_LIBS) \
 LDFLAGS += -Lrender -export-dynamic
 
 target = openbox3
-sources = action.c client.c config.c dispatch.c engine.c event.c group.c \
-          extensions.c focus.c frame.c grab.c menu.c openbox.c \
+sources = action.c client.c config.c dispatch.c event.c group.c \
+          extensions.c focus.c frame.c grab.c menu.c openbox.c framerender.c \
           parse.c plugin.c prop.c screen.c stacking.c timer.c xerror.c \
           parse.lex.c parse.tab.c
 
@@ -41,7 +41,7 @@ $(dir)/%.lo: $(srcdir)/%.c $(depdir)/%.d
 
 $(depdir)/%.d: $(srcdir)/%.c
        @echo Building dependancies for $<
-       $(INSTALL) -d $(depdir)
+       @$(INSTALL) -d $(depdir)
        @$(CC) $(CPPFLAGS) $(CFLAGS) -w -MM -MF $@ -MQ $(<:.c=.lo) $<
 
 install:
index 178ba9715868be819593c97e5b552519bd6b9ffe..e47afa2a58e80616e63d55f6b33dc6422d7484e7 100644 (file)
@@ -1,11 +1,13 @@
 include build/Makefile.incl
 
 dir = render
+theme = operation
 
-CPPFLAGS += $(GLIB_CFLAGS) $(XFT_CFLAGS) -DG_LOG_DOMAIN=\"Render\"
+CPPFLAGS += $(GLIB_CFLAGS) $(XFT_CFLAGS) -DG_LOG_DOMAIN=\"Render\" \
+            -DDEFAULT_THEME=\"$(theme)\" -DTHEMEDIR=\"$(themedir)\"
 
 target = libobrender.la
-sources = color.c font.c gradient.c image.c mask.c render.c test.c
+sources = color.c font.c gradient.c image.c mask.c render.c theme.c
 
 srcdir := $(srcdir)/$(dir)
 target := $(addprefix $(dir)/, $(target))
diff --git a/build/Makefile.themes.openbox b/build/Makefile.themes.openbox
deleted file mode 100644 (file)
index 71294b1..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-include build/Makefile.incl
-
-dir = themes/openbox
-
-files = artwiz bbs bluebox cthulhain deep ebox fieron fieron2 flux \
-        frobozz frobust mbdtex miklos nyz nyzclone ob20 operation \
-        outcomes paper purplehaaze shade steelblue steelblue2 \
-        the_orange trisb twice warp-xp
-
-srcdir := $(srcdir)/$(dir)
-dir := $(DESTDIR)$(themedir)/$(notdir $(dir))
-sources := $(addprefix $(srcdir)/,$(files))
-
-fieron_buttons_dir := $(dir)/fieron_buttons
-fieron_buttons_srcdir := $(srcdir)/fieron_buttons
-fieron_buttons := close.xbm icon.xbm max.xbm stick.xbm
-fieron_buttons_sources := $(addprefix $(fieron_buttons_srcdir)/,$(fieron_buttons))
-
-fieron2_buttons_dir:=$(dir)/fieron2_buttons
-fieron2_buttons_srcdir:=$(srcdir)/fieron2_buttons
-fieron2_buttons:=close.xbm icon.xbm max.xbm stick.xbm
-fieron2_buttons_sources := $(addprefix $(fieron2_buttons_srcdir)/,$(fieron2_buttons))
-
-ebox_buttons_dir:=$(dir)/ebox_buttons
-ebox_buttons_srcdir:=$(srcdir)/ebox_buttons
-ebox_buttons:=close.xbm icon.xbm max.xbm
-ebox_buttons_sources := $(addprefix $(ebox_buttons_srcdir)/,$(ebox_buttons))
-
-all:
-
-install:
-       $(INSTALL) -d $(dir)
-       for i in $(sources); do \
-               $(INSTALL) -m 644 $$i $(dir); \
-       done
-
-       $(INSTALL) -d $(fieron_buttons_dir)
-       for i in $(fieron_buttons_sources); do \
-               $(INSTALL) $$i $(fieron_buttons_dir); \
-       done
-       $(INSTALL) -d $(fieron2_buttons_dir)
-       for i in $(fieron2_buttons_sources); do \
-               $(INSTALL) $$i $(fieron2_buttons_dir); \
-       done
-       $(INSTALL) -d $(ebox_buttons_dir)
-       for i in $(ebox_buttons_sources); do \
-               $(INSTALL) $$i $(ebox_buttons_dir); \
-       done
-
-uninstall:
-       for i in $(ebox_buttons); do \
-               $(RM) $(ebox_buttons_dir)/$$i; \
-       done
-       -rmdir $(ebox_buttons_dir)
-       for i in $(fieron2_buttons); do \
-               $(RM) $(fieron2_buttons_dir)/$$i; \
-       done
-       -rmdir $(fieron2_buttons_dir)
-       for i in $(fieron_buttons); do \
-               $(RM) $(fieron_buttons_dir)/$$i; \
-       done
-       -rmdir $(fieron_buttons_dir)
-       for i in $(files); do \
-               $(RM) $(dir)/$$i; \
-       done
-       -rmdir $(dir)
-
-clean:
-
-distclean:
-
-.PHONY: all clean distclean install uninstall
index b855c909106d3f6ff4d487088ba1fb5c44b1c9d4..6e9e08126c976d4b72f7ab7725a969a566ef0478 100644 (file)
@@ -84,9 +84,7 @@ static gboolean get_all(Window win, Atom prop, Atom type, int size,
                             &ret_items, &bytes_left, &xdata);
     if (res == Success) {
        if (ret_size == size && ret_items > 0) {
-           *data = g_malloc(ret_items * (size / 8) + sizeof(guchar*));
-            g_memmove(*data, xdata, ret_items * (size / 8));
-            data[ret_items * (size / 8)] = NULL;
+           *data = g_memdup(xdata, ret_items * (size / 8));
            *num = ret_items;
            ret = TRUE;
        }
index 52b2b531ce6cc8e05cf113f5226ab950b76b975d..3ba243c86de13bf9860735df0841bfc11730b13f 100644 (file)
@@ -5,36 +5,34 @@
 
 #include <string.h>
 
-void cwmcc_root_get_supported(Window win, Atom **atoms)
+void cwmcc_root_get_supported(Window win, Atom **atoms, gulong *num)
 {
-    gulong num;
-
     if (!cwmcc_prop_get_array32(win, CWMCC_ATOM(root, net_supported),
-                                CWMCC_ATOM(type, atom), atoms, &num)) {
+                                CWMCC_ATOM(type, atom), atoms, num)) {
         g_warning("Failed to read NET_SUPPORTED from 0x%lx", win);
         *atoms = NULL;
+        *num = 0;
     }
 }
 
-void cwmcc_root_get_client_list(Window win, Window **windows)
+void cwmcc_root_get_client_list(Window win, Window **windows, gulong *num)
 {
-    gulong num;
-
     if (!cwmcc_prop_get_array32(win, CWMCC_ATOM(root, net_client_list),
-                                CWMCC_ATOM(type, window), windows, &num)) {
+                                CWMCC_ATOM(type, window), windows, num)) {
         g_warning("Failed to read NET_CLIENT_LIST from 0x%lx", win);
         *windows = NULL;
+        *num = 0;
     }
 }
 
-void cwmcc_root_get_client_list_stacking(Window win, Window **windows)
+void cwmcc_root_get_client_list_stacking(Window win, Window **windows,
+                                         gulong *num)
 {
-    gulong num;
-
     if (!cwmcc_prop_get_array32(win,CWMCC_ATOM(root, net_client_list_stacking),
-                                CWMCC_ATOM(type, window), windows, &num)) {
+                                CWMCC_ATOM(type, window), windows, num)) {
         g_warning("Failed to read NET_CLIENT_LIST_STACKING from 0x%lx", win);
         *windows = NULL;
+        *num = 0;
     }
 }
 
index 13b06010b36273f4847f94286bf2699b53d267c7..7690287b02cfc50ef8af000e564b9149fc439034 100644 (file)
@@ -4,11 +4,12 @@
 #include <X11/Xlib.h>
 #include <glib.h>
 
-void cwmcc_root_get_supported(Window win, Atom **atoms);
+void cwmcc_root_get_supported(Window win, Atom **atoms, gulong *num);
 
-void cwmcc_root_get_client_list(Window win, Window **windows);
+void cwmcc_root_get_client_list(Window win, Window **windows, gulong *num);
 
-void cwmcc_root_get_client_list_stacking(Window win, Window **windows);
+void cwmcc_root_get_client_list_stacking(Window win, Window **windows,
+                                         gulong *num);
 
 void cwmcc_root_get_number_of_desktops(Window win, gulong *desktops);
 
diff --git a/engines/.cvsignore b/engines/.cvsignore
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/engines/engineinterface.h b/engines/engineinterface.h
deleted file mode 100644 (file)
index 1dbc9c7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef __engineinterface_h
-#define __engineinterface_h
-
-#include "kernel/frame.h"
-#include "kernel/geom.h"
-#include <X11/Xlib.h>
-#include <glib.h>
-
-/* startup */
-typedef gboolean EngineStartup();
-
-/* shutdown */
-typedef void EngineShutdown();
-
-/* frame_new */
-typedef Frame *EngineFrameNew();
-
-/* frame_grab_client */
-typedef void EngineFrameGrabClient(Frame *self, Client *client);
-/* frame_release_client */
-typedef void EngineFrameReleaseClient(Frame *self, Client *client);
-
-/* frame_adjust_area */
-/*! Update the frame's size/position to match the client */
-typedef void EngineFrameAdjustArea(Frame *self, gboolean moved,
-                                   gboolean resized);
-/* frame_adjust_shape */
-/*! Shape the frame window to the client window */
-typedef void EngineFrameAdjustShape(Frame *self);
-/* frame_adjust_state */
-/*! Update the frame to match the client's new state (for things like toggle
-  buttons, focus, and the title) XXX break this up */
-typedef void EngineFrameAdjustState(Frame *self);
-/* frame_adjust_focus */
-/*! Update the frame to match the client's focused state */
-typedef void EngineFrameAdjustFocus(Frame *self);
-/* frame_adjust_title */
-/*! Update the frame to display the client's current title */
-typedef void EngineFrameAdjustTitle(Frame *self);
-/* frame_adjust_icon */
-/*! Update the frame to display the client's current icon */
-typedef void EngineFrameAdjustIcon(Frame *self);
-
-/* frame_show */
-/*! Shows the frame */
-typedef void EngineFrameShow(Frame *self);
-/*! Hides the frame */
-typedef void EngineFrameHide(Frame *self);
-
-/* get_context */
-typedef Context EngineGetContext(Client *client, Window win);
-
-typedef void EngineRenderLabel(Window win, Size *sz, char *text,
-                               gboolean hilight, gboolean toplevel);
-
-typedef void EngineSizeLabel(char *text, gboolean hilight, gboolean toplevel,
-                             Size *s);
-
-#endif
diff --git a/engines/openbox/.cvsignore b/engines/openbox/.cvsignore
deleted file mode 100644 (file)
index a784068..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-openbox.la
-obengine.lo
-obtheme.lo
-obrender.lo
-.libs
diff --git a/engines/openbox/obengine.c b/engines/openbox/obengine.c
deleted file mode 100644 (file)
index 75396c8..0000000
+++ /dev/null
@@ -1,873 +0,0 @@
-#include "obtheme.h"
-#include "obrender.h"
-#include "obengine.h"
-#include "kernel/openbox.h"
-#include "kernel/extensions.h"
-#include "kernel/dispatch.h"
-#include "kernel/config.h"
-
-#ifdef HAVE_SYS_STAT_H
-#  include <sys/stat.h>
-#  include <sys/types.h>
-#endif
-#include <X11/Xlib.h>
-#include <glib.h>
-
-#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
-#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
-                         ButtonPressMask | ButtonReleaseMask)
-#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
-                           ButtonMotionMask | ExposureMask)
-
-/* style settings - geometry */
-int ob_s_bevel;
-int ob_s_handle_height;
-int ob_s_bwidth;
-int ob_s_cbwidth;
-/* style settings - colors */
-color_rgb *ob_s_b_color;
-color_rgb *ob_s_cb_focused_color;
-color_rgb *ob_s_cb_unfocused_color;
-color_rgb *ob_s_title_focused_color;
-color_rgb *ob_s_title_unfocused_color;
-color_rgb *ob_s_titlebut_focused_color;
-color_rgb *ob_s_titlebut_unfocused_color;
-/* style settings - fonts */
-int ob_s_winfont_height;
-ObFont *ob_s_winfont;
-/* style settings - masks */
-pixmap_mask *ob_s_max_set_mask;
-pixmap_mask *ob_s_max_unset_mask;
-pixmap_mask *ob_s_iconify_mask;
-pixmap_mask *ob_s_desk_set_mask;
-pixmap_mask *ob_s_desk_unset_mask;
-pixmap_mask *ob_s_shade_set_mask;
-pixmap_mask *ob_s_shade_unset_mask;
-pixmap_mask *ob_s_close_mask;
-
-/* global appearances */
-Appearance *ob_a_focused_unpressed_max;
-Appearance *ob_a_focused_pressed_max;
-Appearance *ob_a_focused_pressed_set_max;
-Appearance *ob_a_unfocused_unpressed_max;
-Appearance *ob_a_unfocused_pressed_max;
-Appearance *ob_a_unfocused_pressed_set_max;
-Appearance *ob_a_focused_unpressed_close;
-Appearance *ob_a_focused_pressed_close;
-Appearance *ob_a_unfocused_unpressed_close;
-Appearance *ob_a_unfocused_pressed_close;
-Appearance *ob_a_focused_unpressed_desk;
-Appearance *ob_a_focused_pressed_desk;
-Appearance *ob_a_focused_pressed_set_desk;
-Appearance *ob_a_unfocused_unpressed_desk;
-Appearance *ob_a_unfocused_pressed_desk;
-Appearance *ob_a_unfocused_pressed_set_desk;
-Appearance *ob_a_focused_unpressed_shade;
-Appearance *ob_a_focused_pressed_shade;
-Appearance *ob_a_focused_pressed_set_shade;
-Appearance *ob_a_unfocused_unpressed_shade;
-Appearance *ob_a_unfocused_pressed_shade;
-Appearance *ob_a_unfocused_pressed_set_shade;
-Appearance *ob_a_focused_unpressed_iconify;
-Appearance *ob_a_focused_pressed_iconify;
-Appearance *ob_a_unfocused_unpressed_iconify;
-Appearance *ob_a_unfocused_pressed_iconify;
-Appearance *ob_a_focused_grip;
-Appearance *ob_a_unfocused_grip;
-Appearance *ob_a_focused_title;
-Appearance *ob_a_unfocused_title;
-Appearance *ob_a_focused_label;
-Appearance *ob_a_unfocused_label;
-Appearance *ob_a_icon; /* always parentrelative, so no focused/unfocused */
-Appearance *ob_a_focused_handle;
-Appearance *ob_a_unfocused_handle;
-
-Appearance *ob_app_hilite_label;
-Appearance *ob_app_unhilite_label;
-
-static void layout_title(ObFrame *self);
-static void mouse_event(const ObEvent *e, ObFrame *self);
-
-gboolean startup()
-{
-    char *path;
-
-    /* create the ~/.openbox/themes/openbox dir */
-    path = g_build_filename(g_get_home_dir(), ".openbox", "themes", "openbox",
-                            NULL);
-    mkdir(path, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP |
-                 S_IROTH | S_IWOTH | S_IXOTH));
-    g_free(path);
-
-    ob_s_b_color = ob_s_cb_unfocused_color = ob_s_cb_focused_color = 
-        ob_s_title_unfocused_color = ob_s_title_focused_color = 
-        ob_s_titlebut_unfocused_color = ob_s_titlebut_focused_color = NULL;
-    ob_s_winfont = NULL;
-    ob_s_max_set_mask = ob_s_max_unset_mask = NULL;
-    ob_s_desk_set_mask = ob_s_desk_unset_mask = NULL;
-    ob_s_shade_set_mask = ob_s_shade_unset_mask = NULL;
-    ob_s_iconify_mask = ob_s_close_mask = NULL;
-
-    ob_a_focused_unpressed_max = appearance_new(Surface_Planar, 1);
-    ob_a_focused_pressed_max = appearance_new(Surface_Planar, 1);
-    ob_a_focused_pressed_set_max = appearance_new(Surface_Planar, 1);
-    ob_a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1);
-    ob_a_unfocused_pressed_max = appearance_new(Surface_Planar, 1);
-    ob_a_unfocused_pressed_set_max = appearance_new(Surface_Planar, 1);
-    ob_a_focused_unpressed_close = NULL;
-    ob_a_focused_pressed_close = NULL;
-    ob_a_unfocused_unpressed_close = NULL;
-    ob_a_unfocused_pressed_close = NULL;
-    ob_a_focused_unpressed_desk = NULL;
-    ob_a_focused_pressed_desk = NULL;
-    ob_a_focused_pressed_set_desk = NULL;
-    ob_a_unfocused_unpressed_desk = NULL;
-    ob_a_unfocused_pressed_desk = NULL;
-    ob_a_unfocused_pressed_set_desk = NULL;
-    ob_a_focused_unpressed_shade = NULL;
-    ob_a_focused_pressed_shade = NULL;
-    ob_a_focused_pressed_set_shade = NULL;
-    ob_a_unfocused_unpressed_shade = NULL;
-    ob_a_unfocused_pressed_shade = NULL;
-    ob_a_unfocused_pressed_set_shade = NULL;
-    ob_a_focused_unpressed_iconify = NULL;
-    ob_a_focused_pressed_iconify = NULL;
-    ob_a_unfocused_unpressed_iconify = NULL;
-    ob_a_unfocused_pressed_iconify = NULL;
-    ob_a_focused_grip = appearance_new(Surface_Planar, 0);
-    ob_a_unfocused_grip = appearance_new(Surface_Planar, 0);
-    ob_a_focused_title = appearance_new(Surface_Planar, 0);
-    ob_a_unfocused_title = appearance_new(Surface_Planar, 0);
-    ob_a_focused_label = appearance_new(Surface_Planar, 1);
-    ob_a_unfocused_label = appearance_new(Surface_Planar, 1);
-    ob_a_icon = appearance_new(Surface_Planar, 1);
-    ob_a_focused_handle = appearance_new(Surface_Planar, 0);
-    ob_a_unfocused_handle = appearance_new(Surface_Planar, 0);
-    ob_app_hilite_label = appearance_new(Surface_Planar, 1);
-    ob_app_unhilite_label = appearance_new(Surface_Planar, 1);
-
-    if (obtheme_load()) {
-        RECT_SET(ob_a_focused_pressed_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_set_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_unpressed_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_set_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_desk->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_set_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_unpressed_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_set_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_shade->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_iconify->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_unpressed_iconify->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_iconify->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_iconify->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_iconify->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_set_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_unpressed_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_set_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_max->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_pressed_close->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_focused_unpressed_close->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_pressed_close->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-        RECT_SET(ob_a_unfocused_unpressed_close->area, 0, 0,
-                 BUTTON_SIZE, BUTTON_SIZE);
-
-        RECT_SET(ob_a_focused_grip->area, 0, 0,
-                 GRIP_WIDTH, ob_s_handle_height);
-        RECT_SET(ob_a_unfocused_grip->area, 0, 0,
-                 GRIP_WIDTH, ob_s_handle_height);
-        return TRUE;
-    } else
-        return FALSE;
-}
-
-void shutdown()
-{
-    if (ob_s_b_color != NULL) color_free(ob_s_b_color);
-    if (ob_s_cb_unfocused_color != NULL) color_free(ob_s_cb_unfocused_color);
-    if (ob_s_cb_focused_color != NULL) color_free(ob_s_cb_focused_color);
-    if (ob_s_title_unfocused_color != NULL) color_free(ob_s_title_unfocused_color);
-    if (ob_s_title_focused_color != NULL) color_free(ob_s_title_focused_color);
-    if (ob_s_titlebut_unfocused_color != NULL)
-        color_free(ob_s_titlebut_unfocused_color);
-    if (ob_s_titlebut_focused_color != NULL)
-        color_free(ob_s_titlebut_focused_color);
-
-    if (ob_s_max_set_mask != NULL)
-        pixmap_mask_free(ob_s_max_set_mask);
-    if (ob_s_max_unset_mask != NULL)
-        pixmap_mask_free(ob_s_max_unset_mask);
-    if (ob_s_desk_set_mask != NULL)
-        pixmap_mask_free(ob_s_desk_set_mask);
-    if (ob_s_desk_unset_mask != NULL)
-        pixmap_mask_free(ob_s_desk_unset_mask);
-    if (ob_s_shade_set_mask != NULL)
-        pixmap_mask_free(ob_s_shade_set_mask);
-    if (ob_s_shade_unset_mask != NULL)
-        pixmap_mask_free(ob_s_shade_unset_mask);
-    if (ob_s_iconify_mask != NULL)
-        pixmap_mask_free(ob_s_iconify_mask);
-    if (ob_s_close_mask != NULL)
-        pixmap_mask_free(ob_s_close_mask);
-
-    if (ob_s_winfont != NULL) font_close(ob_s_winfont);
-
-    appearance_free(ob_a_focused_unpressed_max);
-    appearance_free(ob_a_focused_pressed_max);
-    appearance_free(ob_a_focused_pressed_set_max);
-    appearance_free(ob_a_unfocused_unpressed_max);
-    appearance_free(ob_a_unfocused_pressed_max);
-    appearance_free(ob_a_unfocused_pressed_set_max);
-    if (ob_a_focused_unpressed_close != NULL)
-       appearance_free(ob_a_focused_unpressed_close);
-    if (ob_a_focused_pressed_close != NULL)
-       appearance_free(ob_a_focused_pressed_close);
-    if (ob_a_unfocused_unpressed_close != NULL)
-       appearance_free(ob_a_unfocused_unpressed_close);
-    if (ob_a_unfocused_pressed_close != NULL)
-       appearance_free(ob_a_unfocused_pressed_close);
-    if (ob_a_focused_unpressed_desk != NULL)
-       appearance_free(ob_a_focused_unpressed_desk);
-    if (ob_a_focused_pressed_desk != NULL)
-       appearance_free(ob_a_focused_pressed_desk);
-    if (ob_a_unfocused_unpressed_desk != NULL)
-       appearance_free(ob_a_unfocused_unpressed_desk);
-    if (ob_a_unfocused_pressed_desk != NULL)
-       appearance_free(ob_a_unfocused_pressed_desk);
-    if (ob_a_focused_unpressed_shade != NULL)
-       appearance_free(ob_a_focused_unpressed_shade);
-    if (ob_a_focused_pressed_shade != NULL)
-       appearance_free(ob_a_focused_pressed_shade);
-    if (ob_a_unfocused_unpressed_shade != NULL)
-       appearance_free(ob_a_unfocused_unpressed_shade);
-    if (ob_a_unfocused_pressed_shade != NULL)
-       appearance_free(ob_a_unfocused_pressed_shade);
-    if (ob_a_focused_unpressed_iconify != NULL)
-       appearance_free(ob_a_focused_unpressed_iconify);
-    if (ob_a_focused_pressed_iconify != NULL)
-       appearance_free(ob_a_focused_pressed_iconify);
-    if (ob_a_unfocused_unpressed_iconify != NULL)
-       appearance_free(ob_a_unfocused_unpressed_iconify);
-    if (ob_a_unfocused_pressed_iconify != NULL)
-       appearance_free(ob_a_unfocused_pressed_iconify);
-    appearance_free(ob_a_focused_grip);
-    appearance_free(ob_a_unfocused_grip);
-    appearance_free(ob_a_focused_title);
-    appearance_free(ob_a_unfocused_title);
-    appearance_free(ob_a_focused_label);
-    appearance_free(ob_a_unfocused_label);
-    appearance_free(ob_a_icon);
-    appearance_free(ob_a_focused_handle);
-    appearance_free(ob_a_unfocused_handle);
-    appearance_free(ob_app_hilite_label);
-    appearance_free(ob_app_unhilite_label);
-}
-
-static Window createWindow(Window parent, unsigned long mask,
-                          XSetWindowAttributes *attrib)
-{
-    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
-                        render_depth, InputOutput, render_visual,
-                        mask, attrib);
-                       
-}
-
-Frame *frame_new()
-{
-    XSetWindowAttributes attrib;
-    unsigned long mask;
-    ObFrame *self;
-
-    self = g_new(ObFrame, 1);
-
-    self->frame.visible = FALSE;
-
-    /* create all of the decor windows */
-    mask = CWOverrideRedirect | CWEventMask;
-    attrib.event_mask = FRAME_EVENTMASK;
-    attrib.override_redirect = TRUE;
-    self->frame.window = createWindow(ob_root, mask, &attrib);
-
-    mask = 0;
-    self->frame.plate = createWindow(self->frame.window, mask, &attrib);
-
-    mask = CWEventMask;
-    attrib.event_mask = ELEMENT_EVENTMASK;
-    self->title = createWindow(self->frame.window, mask, &attrib);
-    self->label = createWindow(self->title, mask, &attrib);
-    self->max = createWindow(self->title, mask, &attrib);
-    self->close = createWindow(self->title, mask, &attrib);
-    self->desk = createWindow(self->title, mask, &attrib);
-    self->shade = createWindow(self->title, mask, &attrib);
-    self->icon = createWindow(self->title, mask, &attrib);
-    self->iconify = createWindow(self->title, mask, &attrib);
-    self->handle = createWindow(self->frame.window, mask, &attrib);
-    mask |= CWCursor;
-    attrib.cursor = ob_cursors.ll_angle;
-    self->lgrip = createWindow(self->handle, mask, &attrib);
-    attrib.cursor = ob_cursors.lr_angle;
-    self->rgrip = createWindow(self->handle, mask, &attrib);
-
-    /* the other stuff is shown based on decor settings */
-    XMapWindow(ob_display, self->frame.plate);
-    XMapWindow(ob_display, self->lgrip);
-    XMapWindow(ob_display, self->rgrip);
-    XMapWindow(ob_display, self->label);
-
-    /* set colors/appearance/sizes for stuff that doesn't change */
-    XSetWindowBorder(ob_display, self->frame.window, ob_s_b_color->pixel);
-    XSetWindowBorder(ob_display, self->label, ob_s_b_color->pixel);
-    XSetWindowBorder(ob_display, self->rgrip, ob_s_b_color->pixel);
-    XSetWindowBorder(ob_display, self->lgrip, ob_s_b_color->pixel);
-
-    XResizeWindow(ob_display, self->max, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->iconify, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->icon, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->close, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->desk, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->shade, BUTTON_SIZE, BUTTON_SIZE);
-    XResizeWindow(ob_display, self->lgrip, GRIP_WIDTH, ob_s_handle_height);
-    XResizeWindow(ob_display, self->rgrip, GRIP_WIDTH, ob_s_handle_height);
-
-    /* set up the dynamic appearances */
-    self->a_unfocused_title = appearance_copy(ob_a_unfocused_title);
-    self->a_focused_title = appearance_copy(ob_a_focused_title);
-    self->a_unfocused_label = appearance_copy(ob_a_unfocused_label);
-    self->a_focused_label = appearance_copy(ob_a_focused_label);
-    self->a_unfocused_handle = appearance_copy(ob_a_unfocused_handle);
-    self->a_focused_handle = appearance_copy(ob_a_focused_handle);
-    self->a_icon = appearance_copy(ob_a_icon);
-
-    self->max_press = self->close_press = self->desk_press = 
-       self->iconify_press = self->shade_press = FALSE;
-
-    dispatch_register(Event_X_ButtonPress | Event_X_ButtonRelease,
-                      (EventHandler)mouse_event, self);
-
-    return (Frame*)self;
-}
-
-static void frame_free(ObFrame *self)
-{
-    appearance_free(self->a_unfocused_title); 
-    appearance_free(self->a_focused_title);
-    appearance_free(self->a_unfocused_label);
-    appearance_free(self->a_focused_label);
-    appearance_free(self->a_unfocused_handle);
-    appearance_free(self->a_focused_handle);
-    appearance_free(self->a_icon);
-
-    XDestroyWindow(ob_display, self->frame.window);
-
-    dispatch_register(0, (EventHandler)mouse_event, self);
-
-    g_free(self);
-}
-
-void frame_show(ObFrame *self)
-{
-    if (!self->frame.visible) {
-       self->frame.visible = TRUE;
-       XMapWindow(ob_display, self->frame.window);
-    }
-}
-
-void frame_hide(ObFrame *self)
-{
-    if (self->frame.visible) {
-       self->frame.visible = FALSE;
-       self->frame.client->ignore_unmaps++;
-       XUnmapWindow(ob_display, self->frame.window);
-    }
-}
-
-void frame_adjust_shape(ObFrame *self)
-{
-#ifdef SHAPE
-    int num;
-    XRectangle xrect[2];
-
-    if (!self->frame.client->shaped) {
-       /* clear the shape on the frame window */
-       XShapeCombineMask(ob_display, self->frame.window, ShapeBounding,
-                         self->innersize.left,
-                         self->innersize.top,
-                         None, ShapeSet);
-    } else {
-       /* make the frame's shape match the clients */
-       XShapeCombineShape(ob_display, self->frame.window, ShapeBounding,
-                          self->innersize.left,
-                          self->innersize.top,
-                          self->frame.client->window,
-                          ShapeBounding, ShapeSet);
-
-       num = 0;
-       if (self->frame.client->decorations & Decor_Titlebar) {
-           xrect[0].x = -ob_s_bevel;
-           xrect[0].y = -ob_s_bevel;
-           xrect[0].width = self->width + self->bwidth * 2;
-           xrect[0].height = TITLE_HEIGHT +
-               self->bwidth * 2;
-           ++num;
-       }
-
-       if (self->frame.client->decorations & Decor_Handle) {
-           xrect[1].x = -ob_s_bevel;
-           xrect[1].y = HANDLE_Y(self);
-           xrect[1].width = self->width + self->bwidth * 2;
-           xrect[1].height = ob_s_handle_height +
-               self->bwidth * 2;
-           ++num;
-       }
-
-       XShapeCombineRectangles(ob_display, self->frame.window,
-                               ShapeBounding, 0, 0, xrect, num,
-                               ShapeUnion, Unsorted);
-    }
-#endif
-}
-
-void frame_adjust_area(ObFrame *self, gboolean moved, gboolean resized)
-{
-    if (resized) {
-        if (self->frame.client->decorations & Decor_Border) {
-            self->bwidth = ob_s_bwidth;
-            self->cbwidth = ob_s_cbwidth;
-        } else {
-            self->bwidth = self->cbwidth = 0;
-        }
-        STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
-                  self->cbwidth, self->cbwidth);
-        self->width = self->frame.client->area.width + self->cbwidth * 2;
-        g_assert(self->width > 0);
-
-        /* set border widths */
-        XSetWindowBorderWidth(ob_display, self->frame.plate,  self->cbwidth);
-        XSetWindowBorderWidth(ob_display, self->frame.window, self->bwidth);
-        XSetWindowBorderWidth(ob_display, self->title,  self->bwidth);
-        XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
-        XSetWindowBorderWidth(ob_display, self->lgrip,  self->bwidth);
-        XSetWindowBorderWidth(ob_display, self->rgrip,  self->bwidth);
-  
-        /* position/size and map/unmap all the windows */
-
-        /* they all default off, they're turned on in layout_title */
-        self->icon_x = -1;
-        self->desk_x = -1;
-        self->shade_x = -1;
-        self->iconify_x = -1;
-        self->label_x = -1;
-        self->max_x = -1;
-        self->close_x = -1;
-
-        if (self->frame.client->decorations & Decor_Titlebar) {
-            XMoveResizeWindow(ob_display, self->title,
-                              -self->bwidth, -self->bwidth,
-                              self->width, TITLE_HEIGHT);
-            self->innersize.top += TITLE_HEIGHT + self->bwidth;
-            XMapWindow(ob_display, self->title);
-
-            RECT_SET(self->a_focused_title->area, 0, 0,
-                     self->width, TITLE_HEIGHT);
-            RECT_SET(self->a_unfocused_title->area, 0, 0,
-                     self->width, TITLE_HEIGHT);
-
-            /* layout the title bar elements */
-            layout_title(self);
-        } else
-            XUnmapWindow(ob_display, self->title);
-
-        if (self->frame.client->decorations & Decor_Handle) {
-            XMoveResizeWindow(ob_display, self->handle,
-                              -self->bwidth, HANDLE_Y(self),
-                              self->width, ob_s_handle_height);
-            XMoveWindow(ob_display, self->lgrip,
-                        -self->bwidth, -self->bwidth);
-            XMoveWindow(ob_display, self->rgrip,
-                        -self->bwidth + self->width -
-                        GRIP_WIDTH, -self->bwidth);
-            self->innersize.bottom += ob_s_handle_height +
-                self->bwidth;
-            XMapWindow(ob_display, self->handle);
-
-            if (ob_a_focused_grip->surface.data.planar.grad ==
-                Background_ParentRelative)
-                RECT_SET(self->a_focused_handle->area, 0, 0,
-                         self->width, ob_s_handle_height);
-            else
-                RECT_SET(self->a_focused_handle->area,
-                         GRIP_WIDTH + self->bwidth, 0,
-                         self->width - (GRIP_WIDTH + self->bwidth) * 2,
-                         ob_s_handle_height);
-            if (ob_a_unfocused_grip->surface.data.planar.grad ==
-                Background_ParentRelative)
-                RECT_SET(self->a_unfocused_handle->area, 0, 0,
-                         self->width, ob_s_handle_height);
-            else
-                RECT_SET(self->a_unfocused_handle->area,
-                         GRIP_WIDTH + self->bwidth, 0,
-                         self->width - (GRIP_WIDTH + self->bwidth) * 2,
-                         ob_s_handle_height);
-
-        } else
-            XUnmapWindow(ob_display, self->handle);
-    }
-
-    if (resized) {
-        /* move and resize the plate */
-        XMoveResizeWindow(ob_display, self->frame.plate,
-                          self->innersize.left - self->cbwidth,
-                          self->innersize.top - self->cbwidth,
-                          self->frame.client->area.width,
-                          self->frame.client->area.height);
-        /* when the client has StaticGravity, it likes to move around. */
-        XMoveWindow(ob_display, self->frame.client->window, 0, 0);
-    }
-
-    if (resized) {
-        STRUT_SET(self->frame.size,
-                  self->innersize.left + self->bwidth,
-                  self->innersize.top + self->bwidth,
-                  self->innersize.right + self->bwidth,
-                  self->innersize.bottom + self->bwidth);
-    }
-
-    /* shading can change without being moved or resized */
-    RECT_SET_SIZE(self->frame.area,
-                 self->frame.client->area.width +
-                 self->frame.size.left + self->frame.size.right,
-                 (self->frame.client->shaded ? TITLE_HEIGHT + self->bwidth*2:
-                   self->frame.client->area.height +
-                   self->frame.size.top + self->frame.size.bottom));
-
-    if (moved) {
-        /* find the new coordinates, done after setting the frame.size, for
-           frame_client_gravity. */
-        self->frame.area.x = self->frame.client->area.x;
-        self->frame.area.y = self->frame.client->area.y;
-        frame_client_gravity((Frame*)self,
-                             &self->frame.area.x, &self->frame.area.y);
-    }
-
-    /* move and resize the top level frame.
-       shading can change without being moved or resized */
-    XMoveResizeWindow(ob_display, self->frame.window,
-                      self->frame.area.x, self->frame.area.y,
-                      self->width,
-                      self->frame.area.height - self->bwidth * 2);
-
-    if (resized) {
-        obrender_frame(self);
-
-        frame_adjust_shape(self);
-    }
-}
-
-void frame_adjust_state(ObFrame *self)
-{
-    obrender_frame(self);
-}
-
-void frame_adjust_focus(ObFrame *self)
-{
-    obrender_frame(self);
-}
-
-void frame_adjust_title(ObFrame *self)
-{
-    obrender_frame(self);
-}
-
-void frame_adjust_icon(ObFrame *self)
-{
-    obrender_frame(self);
-}
-
-void frame_grab_client(ObFrame *self, Client *client)
-{
-    self->frame.client = client;
-
-    /* reparent the client to the frame */
-    XReparentWindow(ob_display, client->window, self->frame.plate, 0, 0);
-    /*
-      When reparenting the client window, it is usually not mapped yet, since
-      this occurs from a MapRequest. However, in the case where Openbox is
-      starting up, the window is already mapped, so we'll see unmap events for
-      it. There are 2 unmap events generated that we see, one with the 'event'
-      member set the root window, and one set to the client, but both get
-      handled and need to be ignored.
-    */
-    if (ob_state == State_Starting)
-       client->ignore_unmaps += 2;
-
-    /* select the event mask on the client's parent (to receive config/map
-       req's) the ButtonPress is to catch clicks on the client border */
-    XSelectInput(ob_display, self->frame.plate, PLATE_EVENTMASK);
-
-    /* map the client so it maps when the frame does */
-    XMapWindow(ob_display, client->window);
-
-    frame_adjust_area(self, TRUE, TRUE);
-
-    /* set all the windows for the frame in the client_map */
-    g_hash_table_insert(client_map, &self->frame.window, client);
-    g_hash_table_insert(client_map, &self->frame.plate, client);
-    g_hash_table_insert(client_map, &self->title, client);
-    g_hash_table_insert(client_map, &self->label, client);
-    g_hash_table_insert(client_map, &self->max, client);
-    g_hash_table_insert(client_map, &self->close, client);
-    g_hash_table_insert(client_map, &self->desk, client);
-    g_hash_table_insert(client_map, &self->shade, client);
-    g_hash_table_insert(client_map, &self->icon, client);
-    g_hash_table_insert(client_map, &self->iconify, client);
-    g_hash_table_insert(client_map, &self->handle, client);
-    g_hash_table_insert(client_map, &self->lgrip, client);
-    g_hash_table_insert(client_map, &self->rgrip, client);
-}
-
-void frame_release_client(ObFrame *self, Client *client)
-{
-    XEvent ev;
-
-    g_assert(self->frame.client == client);
-
-    /* check if the app has already reparented its window away */
-    if (XCheckTypedWindowEvent(ob_display, client->window,
-                              ReparentNotify, &ev)) {
-       XPutBackEvent(ob_display, &ev);
-       /* re-map the window since the unmanaging process unmaps it */
-       XMapWindow(ob_display, client->window);
-    } else {
-       /* according to the ICCCM - if the client doesn't reparent itself,
-          then we will reparent the window to root for them */
-       XReparentWindow(ob_display, client->window, ob_root,
-                       client->area.x,
-                       client->area.y);
-    }
-
-    /* remove all the windows for the frame from the client_map */
-    g_hash_table_remove(client_map, &self->frame.window);
-    g_hash_table_remove(client_map, &self->frame.plate);
-    g_hash_table_remove(client_map, &self->title);
-    g_hash_table_remove(client_map, &self->label);
-    g_hash_table_remove(client_map, &self->max);
-    g_hash_table_remove(client_map, &self->close);
-    g_hash_table_remove(client_map, &self->desk);
-    g_hash_table_remove(client_map, &self->shade);
-    g_hash_table_remove(client_map, &self->icon);
-    g_hash_table_remove(client_map, &self->iconify);
-    g_hash_table_remove(client_map, &self->handle);
-    g_hash_table_remove(client_map, &self->lgrip);
-    g_hash_table_remove(client_map, &self->rgrip);
-
-    frame_free(self);
-}
-
-static void layout_title(ObFrame *self)
-{
-    char *lc;
-    int x;
-    gboolean n, d, i, l, m, c, s;
-
-    n = d = i = l = m = c = s = FALSE;
-
-    /* figure out whats being shown, and the width of the label */
-    self->label_width = self->width - (ob_s_bevel + 1) * 2;
-    for (lc = config_engine_layout; *lc != '\0'; ++lc) {
-       switch (*lc) {
-       case 'N':
-           if (!(self->frame.client->decorations & Decor_Icon)) break;
-            if (n) { *lc = ' '; break; } /* rm duplicates */
-           n = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'D':
-           if (!(self->frame.client->decorations & Decor_AllDesktops)) break;
-            if (d) { *lc = ' '; break; } /* rm duplicates */
-           d = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'S':
-           if (!(self->frame.client->decorations & Decor_Shade)) break;
-            if (s) { *lc = ' '; break; } /* rm duplicates */
-           s = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'I':
-           if (!(self->frame.client->decorations & Decor_Iconify)) break;
-            if (i) { *lc = ' '; break; } /* rm duplicates */
-           i = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'L':
-            if (l) { *lc = ' '; break; } /* rm duplicates */
-           l = TRUE;
-           break;
-       case 'M':
-           if (!(self->frame.client->decorations & Decor_Maximize)) break;
-            if (m) { *lc = ' '; break; } /* rm duplicates */
-           m = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'C':
-           if (!(self->frame.client->decorations & Decor_Close)) break;
-            if (c) { *lc = ' '; break; } /* rm duplicates */
-           c = TRUE;
-           self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       }
-    }
-    if (self->label_width < 1) self->label_width = 1;
-
-    XResizeWindow(ob_display, self->label, self->label_width,
-                  LABEL_HEIGHT);
-  
-    if (!n) XUnmapWindow(ob_display, self->icon);
-    if (!d) XUnmapWindow(ob_display, self->desk);
-    if (!s) XUnmapWindow(ob_display, self->shade);
-    if (!i) XUnmapWindow(ob_display, self->iconify);
-    if (!l) XUnmapWindow(ob_display, self->label);
-    if (!m) XUnmapWindow(ob_display, self->max);
-    if (!c) XUnmapWindow(ob_display, self->close);
-
-    x = ob_s_bevel + 1;
-    for (lc = config_engine_layout; *lc != '\0'; ++lc) {
-       switch (*lc) {
-       case 'N':
-           if (!n) break;
-           self->icon_x = x;
-            RECT_SET(self->a_icon->area, 0, 0, BUTTON_SIZE, BUTTON_SIZE);
-           XMapWindow(ob_display, self->icon);
-           XMoveWindow(ob_display, self->icon, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'D':
-           if (!d) break;
-           self->desk_x = x;
-           XMapWindow(ob_display, self->desk);
-           XMoveWindow(ob_display, self->desk, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'S':
-           if (!s) break;
-           self->shade_x = x;
-           XMapWindow(ob_display, self->shade);
-           XMoveWindow(ob_display, self->shade, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'I':
-           if (!i) break;
-           self->iconify_x = x;
-           XMapWindow(ob_display, self->iconify);
-           XMoveWindow(ob_display, self->iconify, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'L':
-           if (!l) break;
-           self->label_x = x;
-           XMapWindow(ob_display, self->label);
-           XMoveWindow(ob_display, self->label, x, ob_s_bevel);
-           x += self->label_width + ob_s_bevel + 1;
-           break;
-       case 'M':
-           if (!m) break;
-           self->max_x = x;
-           XMapWindow(ob_display, self->max);
-           XMoveWindow(ob_display, self->max, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       case 'C':
-           if (!c) break;
-           self->close_x = x;
-           XMapWindow(ob_display, self->close);
-           XMoveWindow(ob_display, self->close, x, ob_s_bevel + 1);
-           x += BUTTON_SIZE + ob_s_bevel + 1;
-           break;
-       }
-    }
-
-    RECT_SET(self->a_focused_label->area, 0, 0,
-             self->label_width, LABEL_HEIGHT);
-    RECT_SET(self->a_unfocused_label->area, 0, 0,
-             self->label_width, LABEL_HEIGHT);
-}
-
-static void mouse_event(const ObEvent *e, ObFrame *self)
-{
-    Window win;
-    gboolean press = e->type == Event_X_ButtonPress;
-
-    win = e->data.x.e->xbutton.window;
-    if (win == self->max) {
-        self->max_press = press;
-        obrender_frame(self);
-    } else if (win == self->close) {
-        self->close_press = press;
-        obrender_frame(self);
-    } else if (win == self->iconify) {
-        self->iconify_press = press;
-        obrender_frame(self);
-    } else if (win == self->desk) { 
-        self->desk_press = press;
-        obrender_frame(self);
-    } else if (win == self->shade) { 
-        self->shade_press = press;
-        obrender_frame(self);
-    }
-}
-
-Context get_context(Client *client, Window win)
-{
-    ObFrame *self;
-
-    if (win == ob_root) return Context_Root;
-    if (client == NULL) return Context_None;
-    if (win == client->window) return Context_Client;
-
-    self = (ObFrame*) client->frame;
-    if (win == self->frame.window) return Context_Frame;
-    if (win == self->frame.plate)  return Context_Client;
-    if (win == self->title)  return Context_Titlebar;
-    if (win == self->label)  return Context_Titlebar;
-    if (win == self->handle) return Context_Handle;
-    if (win == self->lgrip)  return Context_BLCorner;
-    if (win == self->rgrip)  return Context_BRCorner;
-    if (win == self->max)  return Context_Maximize;
-    if (win == self->iconify)  return Context_Iconify;
-    if (win == self->close)  return Context_Close;
-    if (win == self->icon)  return Context_Icon;
-    if (win == self->desk)  return Context_AllDesktops;
-    if (win == self->shade)  return Context_Shade;
-
-    return Context_None;
-}
diff --git a/engines/openbox/obengine.h b/engines/openbox/obengine.h
deleted file mode 100644 (file)
index b4cd7d4..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef __engine_openbox_h
-#define __engine_openbox_h
-
-#include "../../kernel/frame.h"
-#include "../../render/render.h"
-#include "../../render/color.h"
-#include "../../render/font.h"
-#include "../../render/mask.h"
-
-#define LABEL_HEIGHT    (ob_s_winfont_height + 2)
-#define TITLE_HEIGHT    (LABEL_HEIGHT + ob_s_bevel * 2)
-#define HANDLE_Y(f)     (f->innersize.top + f->frame.client->area.height + \
-                        f->cbwidth)
-#define BUTTON_SIZE     (LABEL_HEIGHT - 2)
-#define GRIP_WIDTH      (BUTTON_SIZE * 2)
-
-extern int ob_s_bevel;
-extern int ob_s_handle_height;
-extern int ob_s_bwidth;
-extern int ob_s_cbwidth;
-
-extern color_rgb *ob_s_b_color;
-extern color_rgb *ob_s_cb_focused_color;
-extern color_rgb *ob_s_cb_unfocused_color;
-extern color_rgb *ob_s_title_focused_color;
-extern color_rgb *ob_s_title_unfocused_color;
-extern color_rgb *ob_s_titlebut_focused_color;
-extern color_rgb *ob_s_titlebut_unfocused_color;
-
-extern int ob_s_winfont_height;
-extern ObFont *ob_s_winfont;
-
-extern pixmap_mask *ob_s_max_set_mask;
-extern pixmap_mask *ob_s_max_unset_mask;
-extern pixmap_mask *ob_s_iconify_mask;
-extern pixmap_mask *ob_s_desk_set_mask;
-extern pixmap_mask *ob_s_desk_unset_mask;
-extern pixmap_mask *ob_s_shade_set_mask;
-extern pixmap_mask *ob_s_shade_unset_mask;
-extern pixmap_mask *ob_s_close_mask;
-
-extern Appearance *ob_a_focused_unpressed_max;
-extern Appearance *ob_a_focused_pressed_max;
-extern Appearance *ob_a_focused_pressed_set_max;
-extern Appearance *ob_a_unfocused_unpressed_max;
-extern Appearance *ob_a_unfocused_pressed_max;
-extern Appearance *ob_a_unfocused_pressed_set_max;
-extern Appearance *ob_a_focused_unpressed_close;
-extern Appearance *ob_a_focused_pressed_close;
-extern Appearance *ob_a_unfocused_unpressed_close;
-extern Appearance *ob_a_unfocused_pressed_close;
-extern Appearance *ob_a_focused_unpressed_desk;
-extern Appearance *ob_a_focused_pressed_desk;
-extern Appearance *ob_a_focused_pressed_set_desk;
-extern Appearance *ob_a_unfocused_unpressed_desk;
-extern Appearance *ob_a_unfocused_pressed_desk;
-extern Appearance *ob_a_unfocused_pressed_set_desk;
-extern Appearance *ob_a_focused_unpressed_shade;
-extern Appearance *ob_a_focused_pressed_shade;
-extern Appearance *ob_a_focused_pressed_set_shade;
-extern Appearance *ob_a_unfocused_unpressed_shade;
-extern Appearance *ob_a_unfocused_pressed_shade;
-extern Appearance *ob_a_unfocused_pressed_set_shade;
-extern Appearance *ob_a_focused_unpressed_iconify;
-extern Appearance *ob_a_focused_pressed_iconify;
-extern Appearance *ob_a_unfocused_unpressed_iconify;
-extern Appearance *ob_a_unfocused_pressed_iconify;
-extern Appearance *ob_a_focused_grip;
-extern Appearance *ob_a_unfocused_grip;
-extern Appearance *ob_a_focused_title;
-extern Appearance *ob_a_unfocused_title;
-extern Appearance *ob_a_focused_label;
-extern Appearance *ob_a_unfocused_label;
-extern Appearance *ob_a_icon;
-extern Appearance *ob_a_focused_handle;
-extern Appearance *ob_a_unfocused_handle;
-
-extern Appearance *ob_app_hilite_label;
-extern Appearance *ob_app_unhilite_label;
-
-typedef struct ObFrame {
-    Frame frame;
-
-    Window title;
-    Window label;
-    Window max;
-    Window close;
-    Window desk;
-    Window shade;
-    Window icon;
-    Window iconify;
-    Window handle;
-    Window lgrip;
-    Window rgrip;
-
-    Appearance *a_unfocused_title;
-    Appearance *a_focused_title;
-    Appearance *a_unfocused_label;
-    Appearance *a_focused_label;
-    Appearance *a_icon;
-    Appearance *a_unfocused_handle;
-    Appearance *a_focused_handle;
-
-    Strut  innersize;
-
-    GSList *clients;
-
-    int width; /* title and handle */
-    int label_width;
-    int icon_x;        /* x-position of the window icon button */
-    int label_x;       /* x-position of the window title */
-    int iconify_x;     /* x-position of the window iconify button */
-    int desk_x;         /* x-position of the window all-desktops button */
-    int shade_x;         /* x-position of the window shade button */
-    int max_x;         /* x-position of the window maximize button */
-    int close_x;       /* x-position of the window close button */
-    int bwidth;        /* border width */
-    int cbwidth;       /* client border width */
-
-    gboolean max_press;
-    gboolean close_press;
-    gboolean desk_press;
-    gboolean shade_press;
-    gboolean iconify_press;
-} ObFrame;
-
-#endif
diff --git a/engines/openbox/obrender.c b/engines/openbox/obrender.c
deleted file mode 100644 (file)
index 0027208..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-#include "obengine.h"
-#include "../../kernel/openbox.h"
-#include "../../kernel/screen.h"
-
-static void obrender_label(ObFrame *self, Appearance *a);
-static void obrender_max(ObFrame *self, Appearance *a);
-static void obrender_icon(ObFrame *self, Appearance *a);
-static void obrender_iconify(ObFrame *self, Appearance *a);
-static void obrender_desk(ObFrame *self, Appearance *a);
-static void obrender_shade(ObFrame *self, Appearance *a);
-static void obrender_close(ObFrame *self, Appearance *a);
-
-void obrender_frame(ObFrame *self)
-{
-    if (client_focused(self->frame.client)) {
-        XSetWindowBorder(ob_display, self->frame.plate,
-                         ob_s_cb_focused_color->pixel);
-    } else {
-        XSetWindowBorder(ob_display, self->frame.plate,
-                         ob_s_cb_unfocused_color->pixel);
-    }
-
-    if (self->frame.client->decorations & Decor_Titlebar) {
-        Appearance *t, *l, *m, *n, *i, *d, *s, *c;
-
-        t = (client_focused(self->frame.client) ?
-             self->a_focused_title : self->a_unfocused_title);
-        l = (client_focused(self->frame.client) ?
-             self->a_focused_label : self->a_unfocused_label);
-        m = (client_focused(self->frame.client) ?
-             (self->frame.client->max_vert || self->frame.client->max_horz ?
-              ob_a_focused_pressed_set_max :
-              (self->max_press ?
-               ob_a_focused_pressed_max : ob_a_focused_unpressed_max)) :
-             (self->frame.client->max_vert || self->frame.client->max_horz ?
-              ob_a_unfocused_pressed_set_max :
-              (self->max_press ?
-               ob_a_unfocused_pressed_max : ob_a_unfocused_unpressed_max)));
-        n = self->a_icon;
-        i = (client_focused(self->frame.client) ?
-             (self->iconify_press ?
-              ob_a_focused_pressed_iconify : ob_a_focused_unpressed_iconify) :
-             (self->iconify_press ?
-              ob_a_unfocused_pressed_iconify :
-              ob_a_unfocused_unpressed_iconify));
-        d = (client_focused(self->frame.client) ?
-             (self->frame.client->desktop == DESKTOP_ALL ?
-              ob_a_focused_pressed_set_desk :
-              (self->desk_press ?
-               ob_a_focused_pressed_desk : ob_a_focused_unpressed_desk)) :
-             (self->frame.client->desktop == DESKTOP_ALL ?
-              ob_a_unfocused_pressed_set_desk :
-              (self->desk_press ?
-               ob_a_unfocused_pressed_desk : ob_a_unfocused_unpressed_desk)));
-        s = (client_focused(self->frame.client) ?
-             (self->frame.client->shaded ?
-              ob_a_focused_pressed_set_shade :
-              (self->shade_press ?
-               ob_a_focused_pressed_shade : ob_a_focused_unpressed_shade)) :
-             (self->frame.client->shaded ?
-              ob_a_unfocused_pressed_set_shade :
-              (self->shade_press ?
-               ob_a_unfocused_pressed_shade :ob_a_unfocused_unpressed_shade)));
-        c = (client_focused(self->frame.client) ?
-             (self->close_press ?
-              ob_a_focused_pressed_close : ob_a_focused_unpressed_close) :
-             (self->close_press ?
-              ob_a_unfocused_pressed_close : ob_a_unfocused_unpressed_close));
-
-        paint(self->title, t);
-
-        /* set parents for any parent relative guys */
-        l->surface.data.planar.parent = t;
-        l->surface.data.planar.parentx = self->label_x;
-        l->surface.data.planar.parenty = ob_s_bevel;
-
-        m->surface.data.planar.parent = t;
-        m->surface.data.planar.parentx = self->max_x;
-        m->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        n->surface.data.planar.parent = t;
-        n->surface.data.planar.parentx = self->icon_x;
-        n->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        i->surface.data.planar.parent = t;
-        i->surface.data.planar.parentx = self->iconify_x;
-        i->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        d->surface.data.planar.parent = t;
-        d->surface.data.planar.parentx = self->desk_x;
-        d->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        s->surface.data.planar.parent = t;
-        s->surface.data.planar.parentx = self->shade_x;
-        s->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        c->surface.data.planar.parent = t;
-        c->surface.data.planar.parentx = self->close_x;
-        c->surface.data.planar.parenty = ob_s_bevel + 1;
-
-        obrender_label(self, l);
-        obrender_max(self, m);
-        obrender_icon(self, n);
-        obrender_iconify(self, i);
-        obrender_desk(self, d);
-        obrender_shade(self, s);
-        obrender_close(self, c);
-    }
-
-    if (self->frame.client->decorations & Decor_Handle) {
-        Appearance *h, *g;
-
-        h = (client_focused(self->frame.client) ?
-             self->a_focused_handle : self->a_unfocused_handle);
-        g = (client_focused(self->frame.client) ?
-             ob_a_focused_grip : ob_a_unfocused_grip);
-
-        if (g->surface.data.planar.grad == Background_ParentRelative) {
-            g->surface.data.planar.parent = h;
-            paint(self->handle, h);
-        } else
-            paint(self->handle, h);
-
-        g->surface.data.planar.parentx = 0;
-        g->surface.data.planar.parenty = 0;
-
-        paint(self->lgrip, g);
-
-        g->surface.data.planar.parentx = self->width - GRIP_WIDTH;
-        g->surface.data.planar.parenty = 0;
-
-        paint(self->rgrip, g);
-    }
-}
-
-static void obrender_label(ObFrame *self, Appearance *a)
-{
-    if (self->label_x < 0) return;
-
-
-    /* set the texture's text! */
-    a->texture[0].data.text.string = self->frame.client->title;
-    RECT_SET(a->texture[0].position, 0, 0, self->label_width, LABEL_HEIGHT);
-
-    paint(self->label, a);
-}
-
-static void obrender_icon(ObFrame *self, Appearance *a)
-{
-    if (self->icon_x < 0) return;
-
-    if (self->frame.client->nicons) {
-        Icon *icon = client_icon(self->frame.client, BUTTON_SIZE, BUTTON_SIZE);
-        a->texture[0].type = RGBA;
-        a->texture[0].data.rgba.width = icon->width;
-        a->texture[0].data.rgba.height = icon->height;
-        a->texture[0].data.rgba.data = icon->data;
-        RECT_SET(self->a_icon->texture[0].position, 0, 0,
-                 BUTTON_SIZE,BUTTON_SIZE);
-    } else
-        a->texture[0].type = NoTexture;
-
-    paint(self->icon, a);
-}
-
-static void obrender_max(ObFrame *self, Appearance *a)
-{
-    if (self->max_x < 0) return;
-
-    RECT_SET(a->texture[0].position, 0, 0, BUTTON_SIZE,BUTTON_SIZE);
-    paint(self->max, a);
-}
-
-static void obrender_iconify(ObFrame *self, Appearance *a)
-{
-    if (self->iconify_x < 0) return;
-
-    RECT_SET(a->texture[0].position, 0, 0, BUTTON_SIZE,BUTTON_SIZE);
-    paint(self->iconify, a);
-}
-
-static void obrender_desk(ObFrame *self, Appearance *a)
-{
-    if (self->desk_x < 0) return;
-
-    RECT_SET(a->texture[0].position, 0, 0, BUTTON_SIZE,BUTTON_SIZE);
-    paint(self->desk, a);
-}
-
-static void obrender_shade(ObFrame *self, Appearance *a)
-{
-    if (self->shade_x < 0) return;
-
-    RECT_SET(a->texture[0].position, 0, 0, BUTTON_SIZE,BUTTON_SIZE);
-    paint(self->shade, a);
-}
-
-static void obrender_close(ObFrame *self, Appearance *a)
-{
-    if (self->close_x < 0) return;
-
-    RECT_SET(a->texture[0].position, 0, 0, BUTTON_SIZE,BUTTON_SIZE);
-    paint(self->close, a);
-}
-
-void render_label(Window win, Size *sz, char *text,
-                  gboolean hilight, gboolean toplevel)
-{
-    Appearance *a;
-
-    a = hilight ? ob_app_hilite_label : ob_app_unhilite_label;
-    a->texture[0].data.text.string = text;
-    RECT_SET(a->area, 0, 0, sz->width, sz->height);
-    a->texture[0].position = a->area;
-
-    if (toplevel) {
-        XSetWindowBorderWidth(ob_display, win, ob_s_bwidth);
-        XSetWindowBorder(ob_display, win, ob_s_b_color->pixel);
-    }
-
-    paint(win, a);
-}
-
-void size_label(char *text, gboolean hilight, gboolean toplevel, Size *s)
-{
-    Appearance *a;
-
-    a = hilight ? ob_app_hilite_label : ob_app_unhilite_label;
-    a->texture[0].data.text.string = text;
-
-    appearance_minsize(a, s);
-    s->width += ob_s_bevel * 2;
-    s->height += ob_s_bevel * 2;
-}
diff --git a/engines/openbox/obrender.h b/engines/openbox/obrender.h
deleted file mode 100644 (file)
index 8845c92..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __engines_openbox_render_h
-#define __engines_openbox_render_h
-
-#include "obengine.h"
-
-void obrender_frame(ObFrame *self);
-
-#endif
diff --git a/engines/openbox/obtheme.c b/engines/openbox/obtheme.c
deleted file mode 100644 (file)
index 533559f..0000000
+++ /dev/null
@@ -1,624 +0,0 @@
-#include "obengine.h"
-#include "kernel/openbox.h"
-#include "kernel/config.h"
-
-#include <glib.h>
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-#ifdef HAVE_CTYPE_H
-#  include <ctype.h>
-#endif
-#ifdef HAVE_STRING_H
-#  include <string.h>
-#endif
-
-static XrmDatabase loaddb(char *theme)
-{
-    XrmDatabase db;
-
-    db = XrmGetFileDatabase(theme);
-    if (db == NULL) {
-       char *s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
-                                  "openbox", theme, NULL);
-       db = XrmGetFileDatabase(s);
-       g_free(s);
-    }
-    if (db == NULL) {
-       char *s = g_build_filename(THEMEDIR, theme, NULL);
-       db = XrmGetFileDatabase(s);
-       g_free(s);
-    }
-    return db;
-}
-
-static char *create_class_name(char *rname)
-{
-    char *rclass = g_strdup(rname);
-    char *p = rclass;
-
-    while (TRUE) {
-       *p = toupper(*p);
-       p = strchr(p+1, '.');
-       if (p == NULL) break;
-       ++p;
-       if (*p == '\0') break;
-    }
-    return rclass;
-}
-
-static gboolean read_int(XrmDatabase db, char *rname, int *value)
-{
-    gboolean ret = FALSE;
-    char *rclass = create_class_name(rname);
-    char *rettype, *end;
-    XrmValue retvalue;
-  
-    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
-       retvalue.addr != NULL) {
-       *value = (int)strtol(retvalue.addr, &end, 10);
-       if (end != retvalue.addr)
-           ret = TRUE;
-    }
-
-    g_free(rclass);
-    return ret;
-}
-
-static gboolean read_string(XrmDatabase db, char *rname, char **value)
-{
-    gboolean ret = FALSE;
-    char *rclass = create_class_name(rname);
-    char *rettype;
-    XrmValue retvalue;
-  
-    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
-       retvalue.addr != NULL) {
-       *value = g_strdup(retvalue.addr);
-       ret = TRUE;
-    }
-
-    g_free(rclass);
-    return ret;
-}
-
-static gboolean read_color(XrmDatabase db, char *rname, color_rgb **value)
-{
-    gboolean ret = FALSE;
-    char *rclass = create_class_name(rname);
-    char *rettype;
-    XrmValue retvalue;
-  
-    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
-       retvalue.addr != NULL) {
-       color_rgb *c = color_parse(retvalue.addr);
-       if (c != NULL) {
-           *value = c;
-           ret = TRUE;
-       }
-    }
-
-    g_free(rclass);
-    return ret;
-}
-
-static gboolean read_mask(XrmDatabase db, char *rname, pixmap_mask **value)
-{
-    gboolean ret = FALSE;
-    char *rclass = create_class_name(rname);
-    char *rettype;
-    char *s;
-    char *button_dir;
-    XrmValue retvalue;
-    int hx, hy; /* ignored */
-    unsigned int w, h;
-    unsigned char *b;
-  
-    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
-        retvalue.addr != NULL) {
-
-       button_dir = g_strdup_printf("%s_buttons", config_engine_theme);
-
-        s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
-                             "openbox", button_dir, retvalue.addr, NULL);
-
-        if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
-            ret = TRUE;
-        else {
-            g_free(s);
-            s = g_build_filename(THEMEDIR, button_dir, retvalue.addr, NULL);
-       
-            if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) 
-                ret = TRUE;
-            else {
-                char *themename;
-
-                g_free(s);
-                themename = g_path_get_basename(config_engine_theme);
-                s = g_strdup_printf("%s/%s_buttons/%s", config_engine_theme,
-                                    themename, retvalue.addr);
-                g_free(themename);
-                if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) ==
-                    BitmapSuccess) 
-                    ret = TRUE;
-                else
-                    g_message("Unable to find bitmap '%s'", retvalue.addr);
-            }
-        }
-
-        if (ret) {
-            *value = pixmap_mask_new(w, h, (char*)b);
-            XFree(b);
-        }
-      
-        g_free(s);
-        g_free(button_dir);
-    }
-
-    g_free(rclass);
-    return ret;
-}
-
-static void parse_appearance(char *tex, SurfaceColorType *grad,
-                             ReliefType *relief, BevelType *bevel,
-                             gboolean *interlaced, gboolean *border)
-{
-    char *t;
-
-    /* convert to all lowercase */
-    for (t = tex; *t != '\0'; ++t)
-       *t = g_ascii_tolower(*t);
-
-    if (strstr(tex, "parentrelative") != NULL) {
-       *grad = Background_ParentRelative;
-    } else {
-       if (strstr(tex, "gradient") != NULL) {
-           if (strstr(tex, "crossdiagonal") != NULL)
-               *grad = Background_CrossDiagonal;
-           else if (strstr(tex, "rectangle") != NULL)
-               *grad = Background_Rectangle;
-           else if (strstr(tex, "pyramid") != NULL)
-               *grad = Background_Pyramid;
-           else if (strstr(tex, "pipecross") != NULL)
-               *grad = Background_PipeCross;
-           else if (strstr(tex, "elliptic") != NULL)
-               *grad = Background_Elliptic;
-           else if (strstr(tex, "horizontal") != NULL)
-               *grad = Background_Horizontal;
-           else if (strstr(tex, "vertical") != NULL)
-               *grad = Background_Vertical;
-           else
-               *grad = Background_Diagonal;
-       } else {
-           *grad = Background_Solid;
-       }
-
-       if (strstr(tex, "sunken") != NULL)
-           *relief = Sunken;
-       else if (strstr(tex, "flat") != NULL)
-           *relief = Flat;
-       else
-           *relief = Raised;
-       
-       *border = FALSE;
-       if (*relief == Flat) {
-           if (strstr(tex, "border") != NULL)
-               *border = TRUE;
-       } else {
-           if (strstr(tex, "bevel2") != NULL)
-               *bevel = Bevel2;
-           else
-               *bevel = Bevel1;
-       }
-
-       if (strstr(tex, "interlaced") != NULL)
-           *interlaced = TRUE;
-       else
-           *interlaced = FALSE;
-    }
-}
-
-
-static gboolean read_appearance(XrmDatabase db, char *rname, Appearance *value)
-{
-    gboolean ret = FALSE;
-    char *rclass = create_class_name(rname), *cname, *ctoname, *bcname;
-    char *rettype;
-    XrmValue retvalue;
-
-    cname = g_strconcat(rname, ".color", NULL);
-    ctoname = g_strconcat(rname, ".colorTo", NULL);
-    bcname = g_strconcat(rname, ".borderColor", NULL);
-
-    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
-       retvalue.addr != NULL) {
-       parse_appearance(retvalue.addr,
-                        &value->surface.data.planar.grad,
-                        &value->surface.data.planar.relief,
-                        &value->surface.data.planar.bevel,
-                        &value->surface.data.planar.interlaced,
-                        &value->surface.data.planar.border);
-       if (!read_color(db, cname, &value->surface.data.planar.primary))
-           value->surface.data.planar.primary = color_new(0, 0, 0);
-       if (!read_color(db, ctoname, &value->surface.data.planar.secondary))
-           value->surface.data.planar.secondary = color_new(0, 0, 0);
-       if (value->surface.data.planar.border)
-           if (!read_color(db, bcname,
-                           &value->surface.data.planar.border_color))
-               value->surface.data.planar.border_color = color_new(0, 0, 0);
-       ret = TRUE;
-    }
-
-    g_free(bcname);
-    g_free(ctoname);
-    g_free(cname);
-    g_free(rclass);
-    return ret;
-}
-
-static void set_default_appearance(Appearance *a)
-{
-    a->surface.data.planar.grad = Background_Solid;
-    a->surface.data.planar.relief = Flat;
-    a->surface.data.planar.bevel = Bevel1;
-    a->surface.data.planar.interlaced = FALSE;
-    a->surface.data.planar.border = FALSE;
-    a->surface.data.planar.primary = color_new(0, 0, 0);
-    a->surface.data.planar.secondary = color_new(0, 0, 0);
-}
-
-gboolean obtheme_load()
-{
-    XrmDatabase db = NULL;
-    Justify winjust;
-    char *winjuststr;
-
-    if (config_engine_theme) {
-       db = loaddb(config_engine_theme);
-        if (db == NULL) {
-           g_warning("Failed to load the theme '%s'", config_engine_theme);
-           g_message("Falling back to the default: '%s'", DEFAULT_THEME);
-       }
-    }
-    if (db == NULL) {
-       db = loaddb(DEFAULT_THEME);
-       if (db == NULL) {
-           g_warning("Failed to load the theme '%s'.", DEFAULT_THEME);
-           return FALSE;
-       }
-        /* set it to what was loaded */
-        g_free(config_engine_theme);
-        config_engine_theme = g_strdup(DEFAULT_THEME);
-    }
-
-    /* load the font, not from the theme file tho, its in the config */
-
-    ob_s_winfont = font_open(config_engine_font);
-    ob_s_winfont_height = font_height(ob_s_winfont, config_engine_shadow,
-                                      config_engine_shadow_offset);
-
-    winjust = Justify_Left;
-    if (read_string(db, "window.justify", &winjuststr)) {
-        if (!g_ascii_strcasecmp(winjuststr, "right"))
-            winjust = Justify_Right;
-        else if (!g_ascii_strcasecmp(winjuststr, "center"))
-            winjust = Justify_Center;
-        g_free(winjuststr);
-    }
-
-    if (!read_int(db, "handleWidth", &ob_s_handle_height) ||
-       ob_s_handle_height < 0 || ob_s_handle_height > 100)
-        ob_s_handle_height = 6;
-    if (!read_int(db, "bevelWidth", &ob_s_bevel) ||
-       ob_s_bevel <= 0 || ob_s_bevel > 100) ob_s_bevel = 3;
-    if (!read_int(db, "borderWidth", &ob_s_bwidth) ||
-       ob_s_bwidth < 0 || ob_s_bwidth > 100) ob_s_bwidth = 1;
-    if (!read_int(db, "frameWidth", &ob_s_cbwidth) ||
-       ob_s_cbwidth < 0 || ob_s_cbwidth > 100) ob_s_cbwidth = ob_s_bevel;
-
-    if (!read_color(db, "borderColor", &ob_s_b_color))
-       ob_s_b_color = color_new(0, 0, 0);
-    if (!read_color(db, "window.frame.focusColor", &ob_s_cb_focused_color))
-       ob_s_cb_focused_color = color_new(0xff, 0xff, 0xff);
-    if (!read_color(db, "window.frame.unfocusColor", &ob_s_cb_unfocused_color))
-       ob_s_cb_unfocused_color = color_new(0xff, 0xff, 0xff);
-    if (!read_color(db, "window.label.focus.textColor",
-                    &ob_s_title_focused_color))
-       ob_s_title_focused_color = color_new(0x0, 0x0, 0x0);
-    if (!read_color(db, "window.label.unfocus.textColor",
-                    &ob_s_title_unfocused_color))
-       ob_s_title_unfocused_color = color_new(0xff, 0xff, 0xff);
-    if (!read_color(db, "window.button.focus.picColor",
-                    &ob_s_titlebut_focused_color))
-       ob_s_titlebut_focused_color = color_new(0, 0, 0);
-    if (!read_color(db, "window.button.unfocus.picColor",
-                    &ob_s_titlebut_unfocused_color))
-       ob_s_titlebut_unfocused_color = color_new(0xff, 0xff, 0xff);
-
-    if (read_mask(db, "window.button.max.mask", &ob_s_max_unset_mask)) {
-        if (!read_mask(db, "window.button.max.toggled.mask",
-                       &ob_s_max_set_mask)) {
-            ob_s_max_set_mask = pixmap_mask_copy(ob_s_max_unset_mask);
-        }
-    } else {
-        {
-            char data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
-            ob_s_max_unset_mask = pixmap_mask_new(7, 7, data);
-        }
-        {
-            char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
-            ob_s_max_set_mask = pixmap_mask_new(7, 7, data);
-        }
-    }
-
-    if (!read_mask(db, "window.button.icon.mask",
-                   &ob_s_iconify_mask)) {
-        char data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
-        ob_s_iconify_mask = pixmap_mask_new(7, 7, data);
-    }
-
-    if (read_mask(db, "window.button.stick.mask",
-                   &ob_s_desk_unset_mask)) {
-        if (!read_mask(db, "window.button.stick.toggled.mask",
-                       &ob_s_desk_set_mask)) {
-            ob_s_desk_set_mask =
-                pixmap_mask_copy(ob_s_desk_unset_mask);
-        }
-    } else {
-        {
-            char data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
-            ob_s_desk_unset_mask = pixmap_mask_new(7, 7, data);
-        }
-        {
-            char data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
-            ob_s_desk_set_mask = pixmap_mask_new(7, 7, data);
-        }
-    }
-
-    if (read_mask(db, "window.button.shade.mask",
-                   &ob_s_shade_unset_mask)) {
-        if (!read_mask(db, "window.button.shade.toggled.mask",
-                       &ob_s_shade_set_mask)) {
-            ob_s_shade_set_mask =
-                pixmap_mask_copy(ob_s_shade_unset_mask);
-        }
-    } else {
-        {
-            char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
-            ob_s_shade_unset_mask = pixmap_mask_new(7, 7, data);
-        }
-        {
-            char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
-            ob_s_shade_set_mask = pixmap_mask_new(7, 7, data);
-        }
-    }
-
-    if (!read_mask(db, "window.button.close.mask",
-                   &ob_s_close_mask)) {
-        char data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
-        ob_s_close_mask = pixmap_mask_new(7, 7, data);
-    }        
-
-    /* read the decoration textures */
-    if (!read_appearance(db, "window.title.focus", ob_a_focused_title))
-       set_default_appearance(ob_a_focused_title);
-    if (!read_appearance(db, "window.title.unfocus", ob_a_unfocused_title))
-       set_default_appearance(ob_a_unfocused_title);
-    if (!read_appearance(db, "window.label.focus", ob_a_focused_label))
-       set_default_appearance(ob_a_focused_label);
-    if (!read_appearance(db, "window.label.unfocus", ob_a_unfocused_label))
-       set_default_appearance(ob_a_unfocused_label);
-    if (!read_appearance(db, "window.handle.focus", ob_a_focused_handle))
-       set_default_appearance(ob_a_focused_handle);
-    if (!read_appearance(db, "window.handle.unfocus", ob_a_unfocused_handle))
-       set_default_appearance(ob_a_unfocused_handle);
-    if (!read_appearance(db, "window.grip.focus", ob_a_focused_grip))
-       set_default_appearance(ob_a_focused_grip);
-    if (!read_appearance(db, "window.grip.unfocus", ob_a_unfocused_grip))
-       set_default_appearance(ob_a_unfocused_grip);
-
-    /* read the appearances for rendering non-decorations. these cannot be
-       parent-relative */
-    if (ob_a_focused_label->surface.data.planar.grad !=
-        Background_ParentRelative) {
-        if (!read_appearance(db, "window.label.focus", ob_app_hilite_label))
-            set_default_appearance(ob_app_hilite_label);
-    } else {
-        if (!read_appearance(db, "window.title.focus", ob_app_hilite_label))
-            set_default_appearance(ob_app_hilite_label);
-    }
-    if (ob_a_unfocused_label->surface.data.planar.grad !=
-        Background_ParentRelative) {
-        if (!read_appearance(db, "window.label.unfocus",ob_app_unhilite_label))
-            set_default_appearance(ob_app_unhilite_label);
-    } else {
-        if (!read_appearance(db, "window.title.unfocus",ob_app_unhilite_label))
-            set_default_appearance(ob_app_unhilite_label);
-    }
-
-    /* read buttons textures */
-    if (!read_appearance(db, "window.button.pressed.focus",
-                        ob_a_focused_pressed_max))
-       if (!read_appearance(db, "window.button.pressed",
-                             ob_a_focused_pressed_max))
-           set_default_appearance(ob_a_focused_pressed_max);
-    if (!read_appearance(db, "window.button.pressed.unfocus",
-                        ob_a_unfocused_pressed_max))
-       if (!read_appearance(db, "window.button.pressed",
-                            ob_a_unfocused_pressed_max))
-           set_default_appearance(ob_a_unfocused_pressed_max);
-    if (!read_appearance(db, "window.button.focus",
-                        ob_a_focused_unpressed_max))
-       set_default_appearance(ob_a_focused_unpressed_max);
-    if (!read_appearance(db, "window.button.unfocus",
-                        ob_a_unfocused_unpressed_max))
-       set_default_appearance(ob_a_unfocused_unpressed_max);
-
-    ob_a_unfocused_unpressed_close =
-        appearance_copy(ob_a_unfocused_unpressed_max);
-    ob_a_unfocused_pressed_close = appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_focused_unpressed_close = appearance_copy(ob_a_focused_unpressed_max);
-    ob_a_focused_pressed_close = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_unfocused_unpressed_desk =
-        appearance_copy(ob_a_unfocused_unpressed_max);
-    ob_a_unfocused_pressed_desk = appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_unfocused_pressed_set_desk =
-        appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_focused_unpressed_desk = appearance_copy(ob_a_focused_unpressed_max);
-    ob_a_focused_pressed_desk = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_focused_pressed_set_desk = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_unfocused_unpressed_shade =
-        appearance_copy(ob_a_unfocused_unpressed_max);
-    ob_a_unfocused_pressed_shade = appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_unfocused_pressed_set_shade =
-        appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_focused_unpressed_shade = appearance_copy(ob_a_focused_unpressed_max);
-    ob_a_focused_pressed_shade = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_focused_pressed_set_shade = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_unfocused_unpressed_iconify =
-        appearance_copy(ob_a_unfocused_unpressed_max);
-    ob_a_unfocused_pressed_iconify =
-        appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_focused_unpressed_iconify =
-        appearance_copy(ob_a_focused_unpressed_max);
-    ob_a_focused_pressed_iconify = appearance_copy(ob_a_focused_pressed_max);
-    ob_a_unfocused_pressed_set_max =
-        appearance_copy(ob_a_unfocused_pressed_max);
-    ob_a_focused_pressed_set_max = appearance_copy(ob_a_focused_pressed_max);
-
-    ob_a_icon->surface.data.planar.grad = Background_ParentRelative;
-
-    /* set up the textures */
-    ob_a_focused_label->texture[0].type = Text;
-    ob_a_focused_label->texture[0].data.text.justify = winjust;
-    ob_a_focused_label->texture[0].data.text.font = ob_s_winfont;
-    ob_a_focused_label->texture[0].data.text.shadow = config_engine_shadow;
-    ob_a_focused_label->texture[0].data.text.offset =
-        config_engine_shadow_offset;
-    ob_a_focused_label->texture[0].data.text.tint = config_engine_shadow_tint;
-    ob_a_focused_label->texture[0].data.text.color = ob_s_title_focused_color;
-    ob_app_hilite_label->texture[0].type = Text;
-    ob_app_hilite_label->texture[0].data.text.justify = winjust;
-    ob_app_hilite_label->texture[0].data.text.font = ob_s_winfont;
-    ob_app_hilite_label->texture[0].data.text.shadow = config_engine_shadow;
-    ob_app_hilite_label->texture[0].data.text.offset =
-        config_engine_shadow_offset;
-    ob_app_hilite_label->texture[0].data.text.tint = config_engine_shadow_tint;
-    ob_app_hilite_label->texture[0].data.text.color = ob_s_title_focused_color;
-
-    ob_a_unfocused_label->texture[0].type = Text;
-    ob_a_unfocused_label->texture[0].data.text.justify = winjust;
-    ob_a_unfocused_label->texture[0].data.text.font = ob_s_winfont;
-    ob_a_unfocused_label->texture[0].data.text.shadow = config_engine_shadow;
-    ob_a_unfocused_label->texture[0].data.text.offset =
-        config_engine_shadow_offset;
-    ob_a_unfocused_label->texture[0].data.text.tint =config_engine_shadow_tint;
-    ob_a_unfocused_label->texture[0].data.text.color =
-        ob_s_title_unfocused_color;
-    ob_app_unhilite_label->texture[0].type = Text;
-    ob_app_unhilite_label->texture[0].data.text.justify = winjust;
-    ob_app_unhilite_label->texture[0].data.text.font = ob_s_winfont;
-    ob_app_unhilite_label->texture[0].data.text.shadow = config_engine_shadow;
-    ob_app_unhilite_label->texture[0].data.text.offset =
-        config_engine_shadow_offset;
-    ob_app_unhilite_label->texture[0].data.text.tint =
-        config_engine_shadow_tint;
-    ob_app_unhilite_label->texture[0].data.text.color =
-        ob_s_title_unfocused_color;
-
-    ob_a_focused_unpressed_max->texture[0].type = 
-        ob_a_focused_pressed_max->texture[0].type = 
-        ob_a_focused_pressed_set_max->texture[0].type =  
-        ob_a_unfocused_unpressed_max->texture[0].type = 
-        ob_a_unfocused_pressed_max->texture[0].type = 
-        ob_a_unfocused_pressed_set_max->texture[0].type = 
-        ob_a_focused_unpressed_close->texture[0].type = 
-        ob_a_focused_pressed_close->texture[0].type = 
-        ob_a_unfocused_unpressed_close->texture[0].type = 
-        ob_a_unfocused_pressed_close->texture[0].type = 
-        ob_a_focused_unpressed_desk->texture[0].type = 
-        ob_a_focused_pressed_desk->texture[0].type = 
-        ob_a_focused_pressed_set_desk->texture[0].type = 
-        ob_a_unfocused_unpressed_desk->texture[0].type = 
-        ob_a_unfocused_pressed_desk->texture[0].type = 
-        ob_a_unfocused_pressed_set_desk->texture[0].type = 
-        ob_a_focused_unpressed_shade->texture[0].type = 
-        ob_a_focused_pressed_shade->texture[0].type = 
-        ob_a_focused_pressed_set_shade->texture[0].type = 
-        ob_a_unfocused_unpressed_shade->texture[0].type = 
-        ob_a_unfocused_pressed_shade->texture[0].type = 
-        ob_a_unfocused_pressed_set_shade->texture[0].type = 
-        ob_a_focused_unpressed_iconify->texture[0].type = 
-        ob_a_focused_pressed_iconify->texture[0].type = 
-        ob_a_unfocused_unpressed_iconify->texture[0].type = 
-        ob_a_unfocused_pressed_iconify->texture[0].type = Bitmask;
-    ob_a_focused_unpressed_max->texture[0].data.mask.mask = 
-        ob_a_unfocused_unpressed_max->texture[0].data.mask.mask = 
-        ob_a_focused_pressed_max->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_max->texture[0].data.mask.mask =
-        ob_s_max_unset_mask;
-    ob_a_focused_pressed_set_max->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_set_max->texture[0].data.mask.mask =
-        ob_s_max_set_mask;
-    ob_a_focused_pressed_close->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_close->texture[0].data.mask.mask =
-        ob_a_focused_unpressed_close->texture[0].data.mask.mask = 
-        ob_a_unfocused_unpressed_close->texture[0].data.mask.mask =
-        ob_s_close_mask;
-    ob_a_focused_unpressed_desk->texture[0].data.mask.mask = 
-        ob_a_unfocused_unpressed_desk->texture[0].data.mask.mask = 
-        ob_a_focused_pressed_desk->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_desk->texture[0].data.mask.mask =
-        ob_s_desk_unset_mask;
-    ob_a_focused_pressed_set_desk->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_set_desk->texture[0].data.mask.mask =
-        ob_s_desk_set_mask;
-    ob_a_focused_unpressed_shade->texture[0].data.mask.mask = 
-        ob_a_unfocused_unpressed_shade->texture[0].data.mask.mask = 
-        ob_a_focused_pressed_shade->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_shade->texture[0].data.mask.mask =
-        ob_s_shade_unset_mask;
-    ob_a_focused_pressed_set_shade->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_set_shade->texture[0].data.mask.mask =
-        ob_s_shade_set_mask;
-    ob_a_focused_unpressed_iconify->texture[0].data.mask.mask = 
-        ob_a_unfocused_unpressed_iconify->texture[0].data.mask.mask = 
-        ob_a_focused_pressed_iconify->texture[0].data.mask.mask = 
-        ob_a_unfocused_pressed_iconify->texture[0].data.mask.mask =
-        ob_s_iconify_mask;
-    ob_a_focused_unpressed_max->texture[0].data.mask.color = 
-        ob_a_focused_pressed_max->texture[0].data.mask.color = 
-        ob_a_focused_pressed_set_max->texture[0].data.mask.color = 
-        ob_a_focused_unpressed_close->texture[0].data.mask.color = 
-        ob_a_focused_pressed_close->texture[0].data.mask.color = 
-        ob_a_focused_unpressed_desk->texture[0].data.mask.color = 
-        ob_a_focused_pressed_desk->texture[0].data.mask.color = 
-        ob_a_focused_pressed_set_desk->texture[0].data.mask.color = 
-        ob_a_focused_unpressed_shade->texture[0].data.mask.color = 
-        ob_a_focused_pressed_shade->texture[0].data.mask.color = 
-        ob_a_focused_pressed_set_shade->texture[0].data.mask.color = 
-        ob_a_focused_unpressed_iconify->texture[0].data.mask.color = 
-        ob_a_focused_pressed_iconify->texture[0].data.mask.color =
-        ob_s_titlebut_focused_color;
-    ob_a_unfocused_unpressed_max->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_max->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_set_max->texture[0].data.mask.color = 
-        ob_a_unfocused_unpressed_close->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_close->texture[0].data.mask.color = 
-        ob_a_unfocused_unpressed_desk->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_desk->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_set_desk->texture[0].data.mask.color = 
-        ob_a_unfocused_unpressed_shade->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_shade->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_set_shade->texture[0].data.mask.color = 
-        ob_a_unfocused_unpressed_iconify->texture[0].data.mask.color = 
-        ob_a_unfocused_pressed_iconify->texture[0].data.mask.color =
-        ob_s_titlebut_unfocused_color;
-
-    XrmDestroyDatabase(db);
-    return TRUE;
-}
-
-
diff --git a/engines/openbox/obtheme.h b/engines/openbox/obtheme.h
deleted file mode 100644 (file)
index 11dae6c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __engine_theme_h
-#define __engine_theme_h
-
-#include <glib.h>
-
-gboolean obtheme_load();
-
-#endif
similarity index 71%
rename from engines/openbox/Makefile
rename to obcl/Makefile
index 2ed05a6ea774bbd43177300917485a7aae552f02..56263a4a0e1b275485edb60383ea423d149c754e 100644 (file)
@@ -1,4 +1,4 @@
 all clean distclean install uninstall:
-       $(MAKE) -$(MAKEFLAGS) -C ../.. $@
+       $(MAKE) -$(MAKEFLAGS) -C .. $@
 
 .PHONY: all clean distclean install uninstall
index 5060e1919e55752ae65e133e8381240841f2a06b..b4b3cfc35c272493632b6cc52df8917449991e7e 100644 (file)
@@ -4,3 +4,25 @@ parse.tab.c
 parse.tab.h
 .libs
 parse.lex.c
+action.lo
+client.lo
+config.lo
+dispatch.lo
+event.lo
+extensions.lo
+focus.lo
+frame.lo
+framerender.lo
+grab.lo
+group.lo
+menu.lo
+openbox.lo
+parse.lex.lo
+parse.lo
+parse.tab.lo
+plugin.lo
+prop.lo
+screen.lo
+stacking.lo
+timer.lo
+xerror.lo
index a9c7737af1a3c9d8e668adeb481a9d3f468906a8..683e205f098f5170b7f918c46dded265df99f7f0 100644 (file)
@@ -2,12 +2,11 @@
 #include "focus.h"
 #include "stacking.h"
 #include "frame.h"
+#include "framerender.h"
 #include "screen.h"
 #include "action.h"
 #include "dispatch.h"
 #include "openbox.h"
-#include "engine.h"
-#include "render/render.h"
 
 #include <glib.h>
 
@@ -649,10 +648,10 @@ static void popup_coords(char *format, int a, int b, gboolean hide)
         char *text;
 
         text = g_strdup_printf(format, a, b);
-        engine_size_label(text, TRUE, TRUE, &s);
+        framerender_size_popup_label(text, &s);
         XMoveResizeWindow(ob_display, coords,
                           10, 10, s.width, s.height);
-        engine_render_label(coords, &s, text, TRUE, TRUE);
+        framerender_popup_label(coords, &s, text);
         g_free(text);
 
         XMapWindow(ob_display, coords);
@@ -733,12 +732,12 @@ static void popup_cycle(Client *c, gboolean hide)
 
         a = screen_area(c->desktop);
 
-        engine_size_label(c->title, TRUE, TRUE, &s);
+        framerender_size_popup_label(c->title, &s);
         XMoveResizeWindow(ob_display, coords,
                           a->x + (a->width - s.width) / 2,
                           a->y + (a->height - s.height) / 2,
                           s.width, s.height);
-        engine_render_label(coords, &s, c->title, TRUE, TRUE);
+        framerender_popup_label(coords, &s, c->title);
 
         XMapWindow(ob_display, coords);
     }
index e1c391eac4fc60190ccea550824b40d84365f580..f4dd727b9dc33490d660d29f8b928b70ce349b23 100644 (file)
@@ -3,7 +3,6 @@
 #include "prop.h"
 #include "extensions.h"
 #include "frame.h"
-#include "engine.h"
 #include "event.h"
 #include "grab.h"
 #include "focus.h"
@@ -206,9 +205,9 @@ void client_manage(Window window)
     XChangeSaveSet(ob_display, window, SetModeInsert);
 
     /* create the decoration frame for the client window */
-    self->frame = engine_frame_new();
+    self->frame = frame_new();
 
-    engine_frame_grab_client(self->frame, self);
+    frame_grab_client(self->frame, self);
 
     client_apply_startup_state(self);
 
@@ -290,7 +289,7 @@ void client_unmanage(Client *self)
     /* we dont want events no more */
     XSelectInput(ob_display, self->window, NoEventMask);
 
-    engine_frame_hide(self->frame);
+    frame_hide(self->frame);
 
     client_list = g_list_remove(client_list, self);
     stacking_list = g_list_remove(stacking_list, self);
@@ -347,7 +346,7 @@ void client_unmanage(Client *self)
     client_toggle_border(self, TRUE);
 
     /* reparent the window out of the frame, and free the frame */
-    engine_frame_release_client(self->frame, self);
+    frame_release_client(self->frame, self);
     self->frame = NULL;
      
     if (ob_state != State_Exiting) {
@@ -933,7 +932,7 @@ void client_setup_decor_and_functions(Client *self)
     if (self->frame) {
        /* change the decors on the frame, and with more/less decorations,
            we may also need to be repositioned */
-       engine_frame_adjust_area(self->frame, TRUE, TRUE);
+       frame_adjust_area(self->frame, TRUE, TRUE);
        /* with new decor, the window's maximized size may change */
        client_remaximize(self);
     }
@@ -1051,7 +1050,7 @@ void client_update_wmhints(Client *self)
                    self->pixmap_icon_mask = None;
 
                if (self->frame)
-                   engine_frame_adjust_icon(self->frame);
+                   frame_adjust_icon(self->frame);
            }
        }
 
@@ -1100,7 +1099,7 @@ void client_update_title(Client *self)
     self->title = data;
 
     if (self->frame)
-       engine_frame_adjust_title(self->frame);
+       frame_adjust_title(self->frame);
 }
 
 void client_update_icon_title(Client *self)
@@ -1224,7 +1223,7 @@ void client_update_icons(Client *self)
     }
 
     if (self->frame)
-       engine_frame_adjust_icon(self->frame);
+       frame_adjust_icon(self->frame);
 }
 
 void client_update_kwm_icon(Client *self)
@@ -1239,7 +1238,7 @@ void client_update_kwm_icon(Client *self)
        self->pixmap_icon = self->pixmap_icon_mask = None;
     }
     if (self->frame)
-       engine_frame_adjust_icon(self->frame);
+       frame_adjust_icon(self->frame);
 }
 
 static void client_change_state(Client *self)
@@ -1278,7 +1277,7 @@ static void client_change_state(Client *self)
     client_calc_layer(self);
 
     if (self->frame)
-       engine_frame_adjust_state(self->frame);
+       frame_adjust_state(self->frame);
 }
 
 static Client *search_focus_tree(Client *node, Client *skip)
@@ -1349,9 +1348,9 @@ static void client_showhide(Client *self)
 {
 
     if (client_should_show(self))
-        engine_frame_show(self->frame);
+        frame_show(self->frame);
     else
-        engine_frame_hide(self->frame);
+        frame_hide(self->frame);
 }
 
 gboolean client_normal(Client *self) {
@@ -1524,7 +1523,7 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h,
     /* move/resize the frame to match the request */
     if (self->frame) {
         if (moved || resized)
-            engine_frame_adjust_area(self->frame, moved, resized);
+            frame_adjust_area(self->frame, moved, resized);
 
         if (!user || final) {
             XEvent event;
@@ -1790,7 +1789,7 @@ void client_shade(Client *self, gboolean shade)
     self->shaded = shade;
     client_change_state(self);
     /* resize the frame to just the titlebar */
-    engine_frame_adjust_area(self->frame, FALSE, FALSE);
+    frame_adjust_area(self->frame, FALSE, FALSE);
 }
 
 void client_close(Client *self)
@@ -1839,7 +1838,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
     self->desktop = target;
     PROP_SET32(self->window, net_wm_desktop, cardinal, target);
     /* the frame can display the current desktop state */
-    engine_frame_adjust_state(self->frame);
+    frame_adjust_state(self->frame);
     /* 'move' the window to the new desktop */
     if (!donthide)
         client_showhide(self);
index 0dceb9208539768b950b2e2746fc02b4feb2c231..b69f74a18bf7a5f554064ee419ce9425751d791a 100644 (file)
@@ -12,21 +12,6 @@ extern gboolean config_focus_last;
 /*! Focus the last focused window as a fallback when switching desktops */
 extern gboolean config_focus_last_on_desktop;
 
-/*! The engine to load */
-extern char *config_engine_name;
-/*! The theme to load */
-extern char *config_engine_theme;
-/*! The titlebar layout */
-extern char *config_engine_layout;
-/*! The titlebar font */
-extern char *config_engine_font;
-/*! The titlebar font's shadow */
-extern gboolean config_engine_shadow;
-/*! The titlebar font's shadow offset */
-extern int config_engine_shadow_offset;
-/*! The titlebar font's shadow transparency */
-extern int config_engine_shadow_tint;
-
 /*! The number of desktops */
 extern int config_desktops_num;
 /*! Names for the desktops */
diff --git a/openbox/engine.c b/openbox/engine.c
deleted file mode 100644 (file)
index 53e10de..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#include "engine.h"
-#include "config.h"
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-EngineFrameNew *engine_frame_new;
-EngineFrameGrabClient *engine_frame_grab_client;
-EngineFrameReleaseClient *engine_frame_release_client;
-EngineFrameAdjustArea *engine_frame_adjust_area;
-EngineFrameAdjustShape *engine_frame_adjust_shape;
-EngineFrameAdjustState *engine_frame_adjust_state;
-EngineFrameAdjustFocus *engine_frame_adjust_focus;
-EngineFrameAdjustTitle *engine_frame_adjust_title;
-EngineFrameAdjustIcon *engine_frame_adjust_icon;
-EngineFrameShow *engine_frame_show;
-EngineFrameHide *engine_frame_hide;
-EngineGetContext *engine_get_context;
-EngineRenderLabel *engine_render_label;
-EngineSizeLabel *engine_size_label;
-
-static GModule *module = NULL;
-static EngineStartup *estartup = NULL;
-static EngineShutdown *eshutdown = NULL;
-
-#define LOADSYM(name, var) \
-    if (!g_module_symbol(module, #name, (gpointer*)&var)) { \
-        g_warning("Failed to load symbol %s from engine", #name); \
-        return FALSE; \
-    }
-
-static gboolean load(char *name)
-{
-    char *path;
-
-    g_assert(module == NULL);
-
-    path = g_build_filename(g_get_home_dir(), ".openbox", "engines", name,
-                            NULL);
-    module = g_module_open(path, 0);
-    g_free(path);
-
-    if (module == NULL) {
-        path = g_build_filename(ENGINEDIR, name, NULL);
-        module = g_module_open(path, 0);
-        g_free(path);
-    }
-
-    if (module == NULL) {
-        g_warning(g_module_error());
-       return FALSE;
-    }
-
-    /* load the engine's symbols */
-    LOADSYM(startup, estartup);
-    LOADSYM(shutdown, eshutdown);
-    LOADSYM(frame_new, engine_frame_new);
-    LOADSYM(frame_grab_client, engine_frame_grab_client);
-    LOADSYM(frame_release_client, engine_frame_release_client);
-    LOADSYM(frame_adjust_area, engine_frame_adjust_area);
-    LOADSYM(frame_adjust_shape, engine_frame_adjust_shape);
-    LOADSYM(frame_adjust_state, engine_frame_adjust_state);
-    LOADSYM(frame_adjust_focus, engine_frame_adjust_focus);
-    LOADSYM(frame_adjust_title, engine_frame_adjust_title);
-    LOADSYM(frame_adjust_icon, engine_frame_adjust_icon);
-    LOADSYM(frame_show, engine_frame_show);
-    LOADSYM(frame_hide, engine_frame_hide);
-    LOADSYM(get_context, engine_get_context);
-    LOADSYM(render_label, engine_render_label);
-    LOADSYM(size_label, engine_size_label);
-
-    if (!estartup())
-       return FALSE;
-
-    return TRUE;
-}
-
-void engine_startup()
-{
-    module = NULL;
-}
-
-void engine_load()
-{
-    if (load(config_engine_name))
-        return;
-    g_warning("Failed to load the engine '%s'", config_engine_name);
-    g_message("Falling back to the default: '%s'", DEFAULT_ENGINE);
-    if (module != NULL) {
-       g_module_close(module);
-        module = NULL;
-    }
-    if (!load(DEFAULT_ENGINE)) {
-       g_critical("Failed to load the engine '%s'. Aborting", DEFAULT_ENGINE);
-       exit(1);
-    }
-}
-
-void engine_shutdown()
-{
-    if (module != NULL) {
-       eshutdown();
-       g_module_close(module);
-    }
-}
diff --git a/openbox/engine.h b/openbox/engine.h
deleted file mode 100644 (file)
index e2c314a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __engine_h
-#define __engine_h
-
-#include "../engines/engineinterface.h"
-
-void engine_startup();
-void engine_load();
-void engine_shutdown();
-
-extern EngineFrameNew *engine_frame_new;
-
-extern EngineFrameGrabClient *engine_frame_grab_client;
-extern EngineFrameReleaseClient *engine_frame_release_client;
-
-extern EngineFrameAdjustArea *engine_frame_adjust_area;
-extern EngineFrameAdjustShape *engine_frame_adjust_shape;
-extern EngineFrameAdjustState *engine_frame_adjust_state;
-extern EngineFrameAdjustFocus *engine_frame_adjust_focus;
-extern EngineFrameAdjustTitle *engine_frame_adjust_title;
-extern EngineFrameAdjustIcon *engine_frame_adjust_icon;
-
-extern EngineFrameShow *engine_frame_show;
-extern EngineFrameHide *engine_frame_hide;
-
-extern EngineGetContext *engine_get_context;
-
-extern EngineRenderLabel *engine_render_label;
-extern EngineSizeLabel *engine_size_label;
-
-#endif
index 9d31e6bcdf42206b9aed6975fcc76898488e2f73..4d449f78856bd929c5e60bae05c580b07de894ae 100644 (file)
@@ -5,12 +5,11 @@
 #include "config.h"
 #include "screen.h"
 #include "frame.h"
-#include "engine.h"
+#include "framerender.h"
 #include "focus.h"
 #include "stacking.h"
 #include "extensions.h"
 #include "timer.h"
-#include "engine.h"
 #include "dispatch.h"
 
 #include <X11/Xlib.h>
@@ -368,6 +367,34 @@ static void event_handle_client(Client *client, XEvent *e)
     int i=0;
      
     switch (e->type) {
+    case ButtonPress:
+    case ButtonRelease:
+        switch (frame_context(client->frame, e->xbutton.window)) {
+        case Context_Maximize:
+            client->frame->max_press = (e->type == ButtonPress);
+            framerender_frame(client->frame);
+            break;
+        case Context_Close:
+            client->frame->close_press = (e->type == ButtonPress);
+            framerender_frame(client->frame);
+            break;
+        case Context_Iconify:
+            client->frame->iconify_press = (e->type == ButtonPress);
+            framerender_frame(client->frame);
+            break;
+        case Context_AllDesktops:
+            client->frame->desk_press = (e->type == ButtonPress);
+            framerender_frame(client->frame);
+            break; 
+        case Context_Shade:
+            client->frame->shade_press = (e->type == ButtonPress);
+            framerender_frame(client->frame);
+            break;
+        default:
+            /* nothing changes with clicks for any other contexts */
+            break;
+        }
+        break;
     case FocusIn:
         focus_set_client(client);
     case FocusOut:
@@ -377,7 +404,7 @@ static void event_handle_client(Client *client, XEvent *e)
 #endif
         /* focus state can affect the stacking layer */
         client_calc_layer(client);
-        engine_frame_adjust_focus(client->frame);
+        frame_adjust_focus(client->frame);
        break;
     case EnterNotify:
         if (client_normal(client)) {
@@ -639,7 +666,7 @@ static void event_handle_client(Client *client, XEvent *e)
 #ifdef SHAPE
         if (extensions_shape && e->type == extensions_shape_event_basep) {
             client->shaped = ((XShapeEvent*)e)->shaped;
-            engine_frame_adjust_shape(client->frame);
+            frame_adjust_shape(client->frame);
         }
 #endif
     }
index 7542fae66577bccd1184ad510f3fc285d0ce688b..c189bc9e5c262dfa435a60ebea83395e990353ab 100644 (file)
@@ -9,7 +9,6 @@
 #include "dispatch.h"
 #include "focus.h"
 #include "parse.h"
-#include "engine.h"
 
 #include <X11/Xlib.h>
 #include <glib.h>
index 2064f304445ef6749621a7b88df023615a897c2d..765c4b59bca0e1473ad993872ebb7d897af117f7 100644 (file)
@@ -1,4 +1,615 @@
 #include "frame.h"
+#include "openbox.h"
+#include "extensions.h"
+#include "framerender.h"
+#include "render/theme.h"
+
+#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
+#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+                         ButtonPressMask | ButtonReleaseMask)
+#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
+                           ButtonMotionMask | ExposureMask)
+
+static void layout_title(Frame *self);
+
+void frame_startup()
+{
+    RECT_SET(theme_a_focused_pressed_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_set_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_unpressed_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_set_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_desk->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_set_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_unpressed_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_set_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_shade->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_iconify->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_unpressed_iconify->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_iconify->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_set_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_unpressed_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_set_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_max->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_pressed_close->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_focused_unpressed_close->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_pressed_close->area, 0, 0,
+             theme_button_size, theme_button_size);
+    RECT_SET(theme_a_unfocused_unpressed_close->area, 0, 0,
+             theme_button_size, theme_button_size);
+
+    RECT_SET(theme_a_focused_grip->area, 0, 0,
+             theme_grip_width, theme_handle_height);
+    RECT_SET(theme_a_unfocused_grip->area, 0, 0,
+             theme_grip_width, theme_handle_height);
+}
+
+void frame_shutdown()
+{
+}
+
+static Window createWindow(Window parent, unsigned long mask,
+                          XSetWindowAttributes *attrib)
+{
+    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
+                        render_depth, InputOutput, render_visual,
+                        mask, attrib);
+                       
+}
+
+Frame *frame_new()
+{
+    XSetWindowAttributes attrib;
+    unsigned long mask;
+    Frame *self;
+
+    self = g_new(Frame, 1);
+
+    self->visible = FALSE;
+
+    /* create all of the decor windows */
+    mask = CWOverrideRedirect | CWEventMask;
+    attrib.event_mask = FRAME_EVENTMASK;
+    attrib.override_redirect = TRUE;
+    self->window = createWindow(ob_root, mask, &attrib);
+
+    mask = 0;
+    self->plate = createWindow(self->window, mask, &attrib);
+
+    mask = CWEventMask;
+    attrib.event_mask = ELEMENT_EVENTMASK;
+    self->title = createWindow(self->window, mask, &attrib);
+    self->label = createWindow(self->title, mask, &attrib);
+    self->max = createWindow(self->title, mask, &attrib);
+    self->close = createWindow(self->title, mask, &attrib);
+    self->desk = createWindow(self->title, mask, &attrib);
+    self->shade = createWindow(self->title, mask, &attrib);
+    self->icon = createWindow(self->title, mask, &attrib);
+    self->iconify = createWindow(self->title, mask, &attrib);
+    self->handle = createWindow(self->window, mask, &attrib);
+    mask |= CWCursor;
+    attrib.cursor = ob_cursors.ll_angle;
+    self->lgrip = createWindow(self->handle, mask, &attrib);
+    attrib.cursor = ob_cursors.lr_angle;
+    self->rgrip = createWindow(self->handle, mask, &attrib);
+
+    /* the other stuff is shown based on decor settings */
+    XMapWindow(ob_display, self->plate);
+    XMapWindow(ob_display, self->lgrip);
+    XMapWindow(ob_display, self->rgrip);
+    XMapWindow(ob_display, self->label);
+
+    /* set colors/appearance/sizes for stuff that doesn't change */
+    XSetWindowBorder(ob_display, self->window, theme_b_color->pixel);
+    XSetWindowBorder(ob_display, self->label, theme_b_color->pixel);
+    XSetWindowBorder(ob_display, self->rgrip, theme_b_color->pixel);
+    XSetWindowBorder(ob_display, self->lgrip, theme_b_color->pixel);
+
+    XResizeWindow(ob_display, self->max, theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->iconify,
+                  theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->icon,
+                  theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->close,
+                  theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->desk,
+                  theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->shade,
+                  theme_button_size, theme_button_size);
+    XResizeWindow(ob_display, self->lgrip,
+                  theme_grip_width, theme_handle_height);
+    XResizeWindow(ob_display, self->rgrip,
+                  theme_grip_width, theme_handle_height);
+
+    /* set up the dynamic appearances */
+    self->a_unfocused_title = appearance_copy(theme_a_unfocused_title);
+    self->a_focused_title = appearance_copy(theme_a_focused_title);
+    self->a_unfocused_label = appearance_copy(theme_a_unfocused_label);
+    self->a_focused_label = appearance_copy(theme_a_focused_label);
+    self->a_unfocused_handle = appearance_copy(theme_a_unfocused_handle);
+    self->a_focused_handle = appearance_copy(theme_a_focused_handle);
+    self->a_icon = appearance_copy(theme_a_icon);
+
+    self->max_press = self->close_press = self->desk_press = 
+       self->iconify_press = self->shade_press = FALSE;
+
+    return (Frame*)self;
+}
+
+static void frame_free(Frame *self)
+{
+    appearance_free(self->a_unfocused_title); 
+    appearance_free(self->a_focused_title);
+    appearance_free(self->a_unfocused_label);
+    appearance_free(self->a_focused_label);
+    appearance_free(self->a_unfocused_handle);
+    appearance_free(self->a_focused_handle);
+    appearance_free(self->a_icon);
+
+    XDestroyWindow(ob_display, self->window);
+
+    g_free(self);
+}
+
+void frame_show(Frame *self)
+{
+    if (!self->visible) {
+       self->visible = TRUE;
+       XMapWindow(ob_display, self->window);
+    }
+}
+
+void frame_hide(Frame *self)
+{
+    if (self->visible) {
+       self->visible = FALSE;
+       self->client->ignore_unmaps++;
+       XUnmapWindow(ob_display, self->window);
+    }
+}
+
+void frame_adjust_shape(Frame *self)
+{
+#ifdef SHAPE
+    int num;
+    XRectangle xrect[2];
+
+    if (!self->client->shaped) {
+       /* clear the shape on the frame window */
+       XShapeCombineMask(ob_display, self->window, ShapeBounding,
+                         self->innersize.left,
+                         self->innersize.top,
+                         None, ShapeSet);
+    } else {
+       /* make the frame's shape match the clients */
+       XShapeCombineShape(ob_display, self->window, ShapeBounding,
+                          self->innersize.left,
+                          self->innersize.top,
+                          self->client->window,
+                          ShapeBounding, ShapeSet);
+
+       num = 0;
+       if (self->client->decorations & Decor_Titlebar) {
+           xrect[0].x = -theme_bevel;
+           xrect[0].y = -theme_bevel;
+           xrect[0].width = self->width + self->bwidth * 2;
+           xrect[0].height = theme_title_height +
+               self->bwidth * 2;
+           ++num;
+       }
+
+       if (self->client->decorations & Decor_Handle) {
+           xrect[1].x = -theme_bevel;
+           xrect[1].y = FRAME_HANDLE_Y(self);
+           xrect[1].width = self->width + self->bwidth * 2;
+           xrect[1].height = theme_handle_height +
+               self->bwidth * 2;
+           ++num;
+       }
+
+       XShapeCombineRectangles(ob_display, self->window,
+                               ShapeBounding, 0, 0, xrect, num,
+                               ShapeUnion, Unsorted);
+    }
+#endif
+}
+
+void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
+{
+    if (resized) {
+        if (self->client->decorations & Decor_Border) {
+            self->bwidth = theme_bwidth;
+            self->cbwidth = theme_cbwidth;
+        } else {
+            self->bwidth = self->cbwidth = 0;
+        }
+        STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
+                  self->cbwidth, self->cbwidth);
+        self->width = self->client->area.width + self->cbwidth * 2;
+        g_assert(self->width > 0);
+
+        /* set border widths */
+        XSetWindowBorderWidth(ob_display, self->plate,  self->cbwidth);
+        XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
+        XSetWindowBorderWidth(ob_display, self->title,  self->bwidth);
+        XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
+        XSetWindowBorderWidth(ob_display, self->lgrip,  self->bwidth);
+        XSetWindowBorderWidth(ob_display, self->rgrip,  self->bwidth);
+  
+        /* position/size and map/unmap all the windows */
+
+        /* they all default off, they're turned on in layout_title */
+        self->icon_x = -1;
+        self->desk_x = -1;
+        self->shade_x = -1;
+        self->iconify_x = -1;
+        self->label_x = -1;
+        self->max_x = -1;
+        self->close_x = -1;
+
+        if (self->client->decorations & Decor_Titlebar) {
+            XMoveResizeWindow(ob_display, self->title,
+                              -self->bwidth, -self->bwidth,
+                              self->width, theme_title_height);
+            self->innersize.top += theme_title_height + self->bwidth;
+            XMapWindow(ob_display, self->title);
+
+            RECT_SET(self->a_focused_title->area, 0, 0,
+                     self->width, theme_title_height);
+            RECT_SET(self->a_unfocused_title->area, 0, 0,
+                     self->width, theme_title_height);
+
+            /* layout the title bar elements */
+            layout_title(self);
+        } else
+            XUnmapWindow(ob_display, self->title);
+
+        if (self->client->decorations & Decor_Handle) {
+            XMoveResizeWindow(ob_display, self->handle,
+                              -self->bwidth, FRAME_HANDLE_Y(self),
+                              self->width, theme_handle_height);
+            XMoveWindow(ob_display, self->lgrip,
+                        -self->bwidth, -self->bwidth);
+            XMoveWindow(ob_display, self->rgrip,
+                        -self->bwidth + self->width -
+                        theme_grip_width, -self->bwidth);
+            self->innersize.bottom += theme_handle_height +
+                self->bwidth;
+            XMapWindow(ob_display, self->handle);
+
+            if (theme_a_focused_grip->surface.data.planar.grad ==
+                Background_ParentRelative)
+                RECT_SET(self->a_focused_handle->area, 0, 0,
+                         self->width, theme_handle_height);
+            else
+                RECT_SET(self->a_focused_handle->area,
+                         theme_grip_width + self->bwidth, 0,
+                         self->width - (theme_grip_width + self->bwidth) * 2,
+                         theme_handle_height);
+            if (theme_a_unfocused_grip->surface.data.planar.grad ==
+                Background_ParentRelative)
+                RECT_SET(self->a_unfocused_handle->area, 0, 0,
+                         self->width, theme_handle_height);
+            else
+                RECT_SET(self->a_unfocused_handle->area,
+                         theme_grip_width + self->bwidth, 0,
+                         self->width - (theme_grip_width + self->bwidth) * 2,
+                         theme_handle_height);
+
+        } else
+            XUnmapWindow(ob_display, self->handle);
+    }
+
+    if (resized) {
+        /* move and resize the plate */
+        XMoveResizeWindow(ob_display, self->plate,
+                          self->innersize.left - self->cbwidth,
+                          self->innersize.top - self->cbwidth,
+                          self->client->area.width,
+                          self->client->area.height);
+        /* when the client has StaticGravity, it likes to move around. */
+        XMoveWindow(ob_display, self->client->window, 0, 0);
+    }
+
+    if (resized) {
+        STRUT_SET(self->size,
+                  self->innersize.left + self->bwidth,
+                  self->innersize.top + self->bwidth,
+                  self->innersize.right + self->bwidth,
+                  self->innersize.bottom + self->bwidth);
+    }
+
+    /* shading can change without being moved or resized */
+    RECT_SET_SIZE(self->area,
+                 self->client->area.width +
+                 self->size.left + self->size.right,
+                 (self->client->shaded ? theme_title_height + self->bwidth*2:
+                   self->client->area.height +
+                   self->size.top + self->size.bottom));
+
+    if (moved) {
+        /* find the new coordinates, done after setting the frame.size, for
+           frame_client_gravity. */
+        self->area.x = self->client->area.x;
+        self->area.y = self->client->area.y;
+        frame_client_gravity((Frame*)self,
+                             &self->area.x, &self->area.y);
+    }
+
+    /* move and resize the top level frame.
+       shading can change without being moved or resized */
+    XMoveResizeWindow(ob_display, self->window,
+                      self->area.x, self->area.y,
+                      self->width,
+                      self->area.height - self->bwidth * 2);
+
+    if (resized) {
+        framerender_frame(self);
+
+        frame_adjust_shape(self);
+    }
+}
+
+void frame_adjust_state(Frame *self)
+{
+    framerender_frame(self);
+}
+
+void frame_adjust_focus(Frame *self)
+{
+    framerender_frame(self);
+}
+
+void frame_adjust_title(Frame *self)
+{
+    framerender_frame(self);
+}
+
+void frame_adjust_icon(Frame *self)
+{
+    framerender_frame(self);
+}
+
+void frame_grab_client(Frame *self, Client *client)
+{
+    self->client = client;
+
+    /* reparent the client to the frame */
+    XReparentWindow(ob_display, client->window, self->plate, 0, 0);
+    /*
+      When reparenting the client window, it is usually not mapped yet, since
+      this occurs from a MapRequest. However, in the case where Openbox is
+      starting up, the window is already mapped, so we'll see unmap events for
+      it. There are 2 unmap events generated that we see, one with the 'event'
+      member set the root window, and one set to the client, but both get
+      handled and need to be ignored.
+    */
+    if (ob_state == State_Starting)
+       client->ignore_unmaps += 2;
+
+    /* select the event mask on the client's parent (to receive config/map
+       req's) the ButtonPress is to catch clicks on the client border */
+    XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
+
+    /* map the client so it maps when the frame does */
+    XMapWindow(ob_display, client->window);
+
+    frame_adjust_area(self, TRUE, TRUE);
+
+    /* set all the windows for the frame in the client_map */
+    g_hash_table_insert(client_map, &self->window, client);
+    g_hash_table_insert(client_map, &self->plate, client);
+    g_hash_table_insert(client_map, &self->title, client);
+    g_hash_table_insert(client_map, &self->label, client);
+    g_hash_table_insert(client_map, &self->max, client);
+    g_hash_table_insert(client_map, &self->close, client);
+    g_hash_table_insert(client_map, &self->desk, client);
+    g_hash_table_insert(client_map, &self->shade, client);
+    g_hash_table_insert(client_map, &self->icon, client);
+    g_hash_table_insert(client_map, &self->iconify, client);
+    g_hash_table_insert(client_map, &self->handle, client);
+    g_hash_table_insert(client_map, &self->lgrip, client);
+    g_hash_table_insert(client_map, &self->rgrip, client);
+}
+
+void frame_release_client(Frame *self, Client *client)
+{
+    XEvent ev;
+
+    g_assert(self->client == client);
+
+    /* check if the app has already reparented its window away */
+    if (XCheckTypedWindowEvent(ob_display, client->window,
+                              ReparentNotify, &ev)) {
+       XPutBackEvent(ob_display, &ev);
+       /* re-map the window since the unmanaging process unmaps it */
+       XMapWindow(ob_display, client->window);
+    } else {
+       /* according to the ICCCM - if the client doesn't reparent itself,
+          then we will reparent the window to root for them */
+       XReparentWindow(ob_display, client->window, ob_root,
+                       client->area.x,
+                       client->area.y);
+    }
+
+    /* remove all the windows for the frame from the client_map */
+    g_hash_table_remove(client_map, &self->window);
+    g_hash_table_remove(client_map, &self->plate);
+    g_hash_table_remove(client_map, &self->title);
+    g_hash_table_remove(client_map, &self->label);
+    g_hash_table_remove(client_map, &self->max);
+    g_hash_table_remove(client_map, &self->close);
+    g_hash_table_remove(client_map, &self->desk);
+    g_hash_table_remove(client_map, &self->shade);
+    g_hash_table_remove(client_map, &self->icon);
+    g_hash_table_remove(client_map, &self->iconify);
+    g_hash_table_remove(client_map, &self->handle);
+    g_hash_table_remove(client_map, &self->lgrip);
+    g_hash_table_remove(client_map, &self->rgrip);
+
+    frame_free(self);
+}
+
+static void layout_title(Frame *self)
+{
+    char *lc;
+    int x;
+    gboolean n, d, i, l, m, c, s;
+
+    n = d = i = l = m = c = s = FALSE;
+
+    /* figure out whats being shown, and the width of the label */
+    self->label_width = self->width - (theme_bevel + 1) * 2;
+    for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+       switch (*lc) {
+       case 'N':
+           if (!(self->client->decorations & Decor_Icon)) break;
+            if (n) { *lc = ' '; break; } /* rm duplicates */
+           n = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       case 'D':
+           if (!(self->client->decorations & Decor_AllDesktops)) break;
+            if (d) { *lc = ' '; break; } /* rm duplicates */
+           d = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       case 'S':
+           if (!(self->client->decorations & Decor_Shade)) break;
+            if (s) { *lc = ' '; break; } /* rm duplicates */
+           s = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       case 'I':
+           if (!(self->client->decorations & Decor_Iconify)) break;
+            if (i) { *lc = ' '; break; } /* rm duplicates */
+           i = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       case 'L':
+            if (l) { *lc = ' '; break; } /* rm duplicates */
+           l = TRUE;
+           break;
+       case 'M':
+           if (!(self->client->decorations & Decor_Maximize)) break;
+            if (m) { *lc = ' '; break; } /* rm duplicates */
+           m = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       case 'C':
+           if (!(self->client->decorations & Decor_Close)) break;
+            if (c) { *lc = ' '; break; } /* rm duplicates */
+           c = TRUE;
+           self->label_width -= theme_button_size + theme_bevel + 1;
+           break;
+       }
+    }
+    if (self->label_width < 1) self->label_width = 1;
+
+    XResizeWindow(ob_display, self->label, self->label_width,
+                  theme_label_height);
+  
+    if (!n) XUnmapWindow(ob_display, self->icon);
+    if (!d) XUnmapWindow(ob_display, self->desk);
+    if (!s) XUnmapWindow(ob_display, self->shade);
+    if (!i) XUnmapWindow(ob_display, self->iconify);
+    if (!l) XUnmapWindow(ob_display, self->label);
+    if (!m) XUnmapWindow(ob_display, self->max);
+    if (!c) XUnmapWindow(ob_display, self->close);
+
+    x = theme_bevel + 1;
+    for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+       switch (*lc) {
+       case 'N':
+           if (!n) break;
+           self->icon_x = x;
+            RECT_SET(self->a_icon->area, 0, 0,
+                     theme_button_size, theme_button_size);
+           XMapWindow(ob_display, self->icon);
+           XMoveWindow(ob_display, self->icon, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       case 'D':
+           if (!d) break;
+           self->desk_x = x;
+           XMapWindow(ob_display, self->desk);
+           XMoveWindow(ob_display, self->desk, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       case 'S':
+           if (!s) break;
+           self->shade_x = x;
+           XMapWindow(ob_display, self->shade);
+           XMoveWindow(ob_display, self->shade, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       case 'I':
+           if (!i) break;
+           self->iconify_x = x;
+           XMapWindow(ob_display, self->iconify);
+           XMoveWindow(ob_display, self->iconify, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       case 'L':
+           if (!l) break;
+           self->label_x = x;
+           XMapWindow(ob_display, self->label);
+           XMoveWindow(ob_display, self->label, x, theme_bevel);
+           x += self->label_width + theme_bevel + 1;
+           break;
+       case 'M':
+           if (!m) break;
+           self->max_x = x;
+           XMapWindow(ob_display, self->max);
+           XMoveWindow(ob_display, self->max, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       case 'C':
+           if (!c) break;
+           self->close_x = x;
+           XMapWindow(ob_display, self->close);
+           XMoveWindow(ob_display, self->close, x, theme_bevel + 1);
+           x += theme_button_size + theme_bevel + 1;
+           break;
+       }
+    }
+
+    RECT_SET(self->a_focused_label->area, 0, 0,
+             self->label_width, theme_label_height);
+    RECT_SET(self->a_unfocused_label->area, 0, 0,
+             self->label_width, theme_label_height);
+}
 
 Context frame_context_from_string(char *name)
 {
@@ -35,6 +646,29 @@ Context frame_context_from_string(char *name)
     return Context_None;
 }
 
+Context frame_context(Frame *self, Window win)
+{
+    if (win == ob_root) return Context_Root;
+    if (self == NULL) return Context_None;
+    if (win == self->client->window) return Context_Client;
+
+    if (win == self->window) return Context_Frame;
+    if (win == self->plate)  return Context_Client;
+    if (win == self->title)  return Context_Titlebar;
+    if (win == self->label)  return Context_Titlebar;
+    if (win == self->handle) return Context_Handle;
+    if (win == self->lgrip)  return Context_BLCorner;
+    if (win == self->rgrip)  return Context_BRCorner;
+    if (win == self->max)    return Context_Maximize;
+    if (win == self->iconify)return Context_Iconify;
+    if (win == self->close)  return Context_Close;
+    if (win == self->icon)   return Context_Icon;
+    if (win == self->desk)   return Context_AllDesktops;
+    if (win == self->shade)  return Context_Shade;
+
+    return Context_None;
+}
+
 void frame_client_gravity(Frame *self, int *x, int *y)
 {
     /* horizontal */
index fb492d8cf59f46da9b9633a3f929b24392cddc53..c36e783312b865d71293d1b3859f68cab5271b5b 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "geom.h"
 #include "client.h"
+#include "render/render.h"
 
 typedef enum {
     Context_None,
@@ -24,7 +25,8 @@ typedef enum {
     NUM_CONTEXTS
 } Context;
 
-Context frame_context_from_string(char *name);
+#define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
+                          f->cbwidth)
 
 typedef struct Frame {
     Client *client;
@@ -35,8 +37,69 @@ typedef struct Frame {
     Strut  size;
     Rect   area;
     gboolean visible;
+
+    Window title;
+    Window label;
+    Window max;
+    Window close;
+    Window desk;
+    Window shade;
+    Window icon;
+    Window iconify;
+    Window handle;
+    Window lgrip;
+    Window rgrip;
+
+    Appearance *a_unfocused_title;
+    Appearance *a_focused_title;
+    Appearance *a_unfocused_label;
+    Appearance *a_focused_label;
+    Appearance *a_icon;
+    Appearance *a_unfocused_handle;
+    Appearance *a_focused_handle;
+
+    Strut  innersize;
+
+    GSList *clients;
+
+    int width;         /* title and handle */
+    int label_width;
+    int icon_x;        /* x-position of the window icon button */
+    int label_x;       /* x-position of the window title */
+    int iconify_x;     /* x-position of the window iconify button */
+    int desk_x;        /* x-position of the window all-desktops button */
+    int shade_x;       /* x-position of the window shade button */
+    int max_x;         /* x-position of the window maximize button */
+    int close_x;       /* x-position of the window close button */
+    int bwidth;        /* border width */
+    int cbwidth;       /* client border width */
+
+    gboolean max_press;
+    gboolean close_press;
+    gboolean desk_press;
+    gboolean shade_press;
+    gboolean iconify_press;
 } Frame;
 
+void frame_startup();
+void frame_shutdown();
+
+Frame *frame_new();
+void frame_show(Frame *self);
+void frame_hide(Frame *self);
+void frame_adjust_shape(Frame *self);
+void frame_adjust_area(Frame *self, gboolean moved, gboolean resized);
+void frame_adjust_state(Frame *self);
+void frame_adjust_focus(Frame *self);
+void frame_adjust_title(Frame *self);
+void frame_adjust_icon(Frame *self);
+void frame_grab_client(Frame *self, Client *client);
+void frame_release_client(Frame *self, Client *client);
+
+Context frame_context_from_string(char *name);
+
+Context frame_context(Frame *self, Window win);
+
 /*! Applies gravity to the client's position to find where the frame should
   be positioned.
   @return The proper coordinates for the frame, based on the client.
diff --git a/openbox/framerender.c b/openbox/framerender.c
new file mode 100644 (file)
index 0000000..44a6b78
--- /dev/null
@@ -0,0 +1,248 @@
+#include "frame.h"
+#include "openbox.h"
+#include "screen.h"
+#include "framerender.h"
+#include "render/theme.h"
+
+static void framerender_label(Frame *self, Appearance *a);
+static void framerender_icon(Frame *self, Appearance *a);
+static void framerender_max(Frame *self, Appearance *a);
+static void framerender_iconify(Frame *self, Appearance *a);
+static void framerender_desk(Frame *self, Appearance *a);
+static void framerender_shade(Frame *self, Appearance *a);
+static void framerender_close(Frame *self, Appearance *a);
+
+void framerender_frame(Frame *self)
+{
+    if (client_focused(self->client)) {
+        XSetWindowBorder(ob_display, self->plate,
+                         theme_cb_focused_color->pixel);
+    } else {
+        XSetWindowBorder(ob_display, self->plate,
+                         theme_cb_unfocused_color->pixel);
+    }
+
+    if (self->client->decorations & Decor_Titlebar) {
+        Appearance *t, *l, *m, *n, *i, *d, *s, *c;
+
+        t = (client_focused(self->client) ?
+             self->a_focused_title : self->a_unfocused_title);
+        l = (client_focused(self->client) ?
+             self->a_focused_label : self->a_unfocused_label);
+        m = (client_focused(self->client) ?
+             (self->client->max_vert || self->client->max_horz ?
+              theme_a_focused_pressed_set_max :
+              (self->max_press ?
+               theme_a_focused_pressed_max : theme_a_focused_unpressed_max)) :
+             (self->client->max_vert || self->client->max_horz ?
+              theme_a_unfocused_pressed_set_max :
+              (self->max_press ?
+               theme_a_unfocused_pressed_max :
+               theme_a_unfocused_unpressed_max)));
+        n = self->a_icon;
+        i = (client_focused(self->client) ?
+             (self->iconify_press ?
+              theme_a_focused_pressed_iconify :
+              theme_a_focused_unpressed_iconify) :
+             (self->iconify_press ?
+              theme_a_unfocused_pressed_iconify :
+              theme_a_unfocused_unpressed_iconify));
+        d = (client_focused(self->client) ?
+             (self->client->desktop == DESKTOP_ALL ?
+              theme_a_focused_pressed_set_desk :
+              (self->desk_press ?
+               theme_a_focused_pressed_desk :
+               theme_a_focused_unpressed_desk)) :
+             (self->client->desktop == DESKTOP_ALL ?
+              theme_a_unfocused_pressed_set_desk :
+              (self->desk_press ?
+               theme_a_unfocused_pressed_desk :
+               theme_a_unfocused_unpressed_desk)));
+        s = (client_focused(self->client) ?
+             (self->client->shaded ?
+              theme_a_focused_pressed_set_shade :
+              (self->shade_press ?
+               theme_a_focused_pressed_shade :
+               theme_a_focused_unpressed_shade)) :
+             (self->client->shaded ?
+              theme_a_unfocused_pressed_set_shade :
+              (self->shade_press ?
+               theme_a_unfocused_pressed_shade :
+               theme_a_unfocused_unpressed_shade)));
+        c = (client_focused(self->client) ?
+             (self->close_press ?
+              theme_a_focused_pressed_close :
+              theme_a_focused_unpressed_close) :
+             (self->close_press ?
+              theme_a_unfocused_pressed_close :
+              theme_a_unfocused_unpressed_close));
+
+        paint(self->title, t);
+
+        /* set parents for any parent relative guys */
+        l->surface.data.planar.parent = t;
+        l->surface.data.planar.parentx = self->label_x;
+        l->surface.data.planar.parenty = theme_bevel;
+
+        m->surface.data.planar.parent = t;
+        m->surface.data.planar.parentx = self->max_x;
+        m->surface.data.planar.parenty = theme_bevel + 1;
+
+        n->surface.data.planar.parent = t;
+        n->surface.data.planar.parentx = self->icon_x;
+        n->surface.data.planar.parenty = theme_bevel + 1;
+
+        i->surface.data.planar.parent = t;
+        i->surface.data.planar.parentx = self->iconify_x;
+        i->surface.data.planar.parenty = theme_bevel + 1;
+
+        d->surface.data.planar.parent = t;
+        d->surface.data.planar.parentx = self->desk_x;
+        d->surface.data.planar.parenty = theme_bevel + 1;
+
+        s->surface.data.planar.parent = t;
+        s->surface.data.planar.parentx = self->shade_x;
+        s->surface.data.planar.parenty = theme_bevel + 1;
+
+        c->surface.data.planar.parent = t;
+        c->surface.data.planar.parentx = self->close_x;
+        c->surface.data.planar.parenty = theme_bevel + 1;
+
+        framerender_label(self, l);
+        framerender_max(self, m);
+        framerender_icon(self, n);
+        framerender_iconify(self, i);
+        framerender_desk(self, d);
+        framerender_shade(self, s);
+        framerender_close(self, c);
+    }
+
+    if (self->client->decorations & Decor_Handle) {
+        Appearance *h, *g;
+
+        h = (client_focused(self->client) ?
+             self->a_focused_handle : self->a_unfocused_handle);
+        g = (client_focused(self->client) ?
+             theme_a_focused_grip : theme_a_unfocused_grip);
+
+        if (g->surface.data.planar.grad == Background_ParentRelative) {
+            g->surface.data.planar.parent = h;
+            paint(self->handle, h);
+        } else
+            paint(self->handle, h);
+
+        g->surface.data.planar.parentx = 0;
+        g->surface.data.planar.parenty = 0;
+
+        paint(self->lgrip, g);
+
+        g->surface.data.planar.parentx = self->width - theme_grip_width;
+        g->surface.data.planar.parenty = 0;
+
+        paint(self->rgrip, g);
+    }
+}
+
+static void framerender_label(Frame *self, Appearance *a)
+{
+    if (self->label_x < 0) return;
+
+
+    /* set the texture's text! */
+    a->texture[0].data.text.string = self->client->title;
+    RECT_SET(a->texture[0].position, 0, 0,
+             self->label_width, theme_label_height);
+
+    paint(self->label, a);
+}
+
+static void framerender_icon(Frame *self, Appearance *a)
+{
+    if (self->icon_x < 0) return;
+
+    if (self->client->nicons) {
+        Icon *icon = client_icon(self->client,
+                                 theme_button_size, theme_button_size);
+        a->texture[0].type = RGBA;
+        a->texture[0].data.rgba.width = icon->width;
+        a->texture[0].data.rgba.height = icon->height;
+        a->texture[0].data.rgba.data = icon->data;
+        RECT_SET(self->a_icon->texture[0].position, 0, 0,
+                 theme_button_size,theme_button_size);
+    } else
+        a->texture[0].type = NoTexture;
+
+    paint(self->icon, a);
+}
+
+static void framerender_max(Frame *self, Appearance *a)
+{
+    if (self->max_x < 0) return;
+
+    RECT_SET(a->texture[0].position, 0, 0,
+             theme_button_size, theme_button_size);
+    paint(self->max, a);
+}
+
+static void framerender_iconify(Frame *self, Appearance *a)
+{
+    if (self->iconify_x < 0) return;
+
+    RECT_SET(a->texture[0].position, 0, 0,
+             theme_button_size, theme_button_size);
+    paint(self->iconify, a);
+}
+
+static void framerender_desk(Frame *self, Appearance *a)
+{
+    if (self->desk_x < 0) return;
+
+    RECT_SET(a->texture[0].position, 0, 0,
+             theme_button_size, theme_button_size);
+    paint(self->desk, a);
+}
+
+static void framerender_shade(Frame *self, Appearance *a)
+{
+    if (self->shade_x < 0) return;
+
+    RECT_SET(a->texture[0].position, 0, 0,
+             theme_button_size, theme_button_size);
+    paint(self->shade, a);
+}
+
+static void framerender_close(Frame *self, Appearance *a)
+{
+    if (self->close_x < 0) return;
+
+    RECT_SET(a->texture[0].position, 0, 0,
+             theme_button_size, theme_button_size);
+    paint(self->close, a);
+}
+
+void framerender_popup_label(Window win, Size *sz, char *text)
+{
+    Appearance *a;
+
+    a = theme_app_hilite_label;
+    a->texture[0].data.text.string = text;
+    RECT_SET(a->area, 0, 0, sz->width, sz->height);
+    a->texture[0].position = a->area;
+
+    XSetWindowBorderWidth(ob_display, win, theme_bwidth);
+    XSetWindowBorder(ob_display, win, theme_b_color->pixel);
+
+    paint(win, a);
+}
+
+void framerender_size_popup_label(char *text, Size *sz)
+{
+    Appearance *a;
+
+    a = theme_app_hilite_label;
+    a->texture[0].data.text.string = text;
+
+    appearance_minsize(a, sz);
+    sz->width += theme_bevel * 2;
+    sz->height += theme_bevel * 2;
+}
diff --git a/openbox/framerender.h b/openbox/framerender.h
new file mode 100644 (file)
index 0000000..c02c9e7
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __framerender_h
+#define __framerender_h
+
+#include "frame.h"
+
+void framerender_frame(Frame *self);
+
+void framerender_popup_label(Window win, Size *sz, char *text);
+void framerender_size_popup_label(char *text, Size *sz);
+
+#endif
index c4784aff5ef96dab4a887c173998e51fbf5cffa3..afe43f2745b73ca2d0ff7b58ae8465b122317f51 100644 (file)
@@ -6,17 +6,18 @@
 #include "prop.h"
 #include "screen.h"
 #include "focus.h"
+#include "frame.h"
 #include "extensions.h"
 #include "parse.h"
 #include "grab.h"
-#include "engine.h"
 #include "plugin.h"
 #include "timer.h"
 #include "group.h"
 #include "config.h"
 #include "gettext.h"
-#include "../render/render.h"
-#include "../render/font.h"
+#include "render/render.h"
+#include "render/font.h"
+#include "render/theme.h"
 
 #ifdef HAVE_FCNTL_H
 #  include <fcntl.h>
@@ -64,6 +65,7 @@ int main(int argc, char **argv)
     struct sigaction action;
     sigset_t sigset;
     char *path;
+    char *theme;
 
     ob_state = State_Starting;
 
@@ -157,9 +159,9 @@ int main(int argc, char **argv)
        timer_startup();
        render_startup();
        font_startup();
+        theme_startup();
        event_startup();
         grab_startup();
-        engine_startup();
         plugin_startup();
         /* load the plugins specified in the pluginrc */
         plugin_loadall();
@@ -171,9 +173,12 @@ int main(int argc, char **argv)
         /* we're done with parsing now, kill it */
         parse_shutdown();
 
-        /* load the engine specified in the rc */
-       engine_load();
+        /* load the theme specified in the rc file */
+        theme = theme_load("ebox"); /* woot i like this theme :) */
+        g_free(theme);
+        if (!theme) return 1;
 
+        frame_startup();
        focus_startup();
        screen_startup();
         group_startup();
@@ -197,9 +202,10 @@ int main(int argc, char **argv)
         group_shutdown();
        screen_shutdown();
        focus_shutdown();
-       engine_shutdown();
+        frame_shutdown();
         grab_shutdown();
        event_shutdown();
+        theme_shutdown();
        render_shutdown();
        timer_shutdown();
         config_shutdown();
index 4dcdc2ca8c440d432b0e9560d10b1c208b322b71..64896e07249d6806cb7f2d6678a5b3a417991b3e 100644 (file)
@@ -4,7 +4,7 @@
 #  include <stdlib.h>
 #endif
 
-int yylineno = 1;
+extern int lineno;
 %}
 
 real [-0-9][0-9]*\.[0-9]+
@@ -15,9 +15,9 @@ bool ([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][
 
 %%
 
-^[ \t]*#.*\n /* comment */ { ++yylineno; }
+^[ \t]*#.*\n /* comment */ { ++lineno; }
 ^[ \t]*#.*   /* comment */
-^[ \t]*\n    /* empty lines */ { ++yylineno; }
+^[ \t]*\n    /* empty lines */ { ++lineno; }
 [ \t]        /* whitespace */
 {real}       { yylval.real = atof(yytext); return REAL; }
 {integer}    { yylval.integer = atoi(yytext); return INTEGER; }
index 125f18038dc02bee22cf9d1f9929232e10421a14..de221f9f094fd6f13ce4e50c3f60566846632391 100644 (file)
@@ -23,7 +23,7 @@ extern int yylex();
 extern int yyparse();
 void yyerror(char *err);
 
-extern int yylineno;
+extern int lineno;
 extern FILE *yyin;
 
 static char *path;
@@ -56,14 +56,14 @@ void parse_set_section(char *section);
 
 sections:
   | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
-    { ++yylineno; } lines
+    { ++lineno; } lines
   ;
 
 lines:
   | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
-    { ++yylineno; }
+    { ++lineno; }
   | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
-    { ++yylineno; }
+    { ++lineno; }
   ;
 
 tokens:
@@ -115,8 +115,10 @@ listtoken:
 
 %%
 
+int lineno;
+
 void yyerror(char *err) {
-    g_message("%s:%d: %s", path, yylineno, err);
+    g_message("%s:%d: %s", path, lineno, err);
 }
 
 void parse_rc()
@@ -134,7 +136,7 @@ void parse_rc()
         }
     }
 
-    yylineno = 1;
+    lineno = 1;
 
     yyparse();
 
index 49d3d22d46316c5b7a7d0f266010c84cf1cbd03b..9f14ea8cb68f735d3952005920986be890fb2b8f 100644 (file)
@@ -4,7 +4,6 @@
 #include "screen.h"
 #include "client.h"
 #include "frame.h"
-#include "engine.h"
 #include "focus.h"
 #include "dispatch.h"
 #include "../render/render.h"
@@ -287,14 +286,14 @@ void screen_set_desktop(guint num)
     for (it = stacking_list; it != NULL; it = it->next) {
         Client *c = it->data;
        if (!c->frame->visible && client_should_show(c))
-            engine_frame_show(c->frame);
+            frame_show(c->frame);
     }
 
     /* hide windows from bottom to top */
     for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
         Client *c = it->data;
        if (c->frame->visible && !client_should_show(c))
-            engine_frame_hide(c->frame);
+            frame_hide(c->frame);
     }
 
     /* focus the last focused window on the desktop, and ignore enter events
@@ -396,14 +395,14 @@ void screen_show_desktop(gboolean show)
        for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
            Client *client = it->data;
            if (client->frame->visible && !client_should_show(client))
-                engine_frame_hide(client->frame);
+                frame_hide(client->frame);
        }
     } else {
         /* top to bottom */
        for (it = stacking_list; it != NULL; it = it->next) {
            Client *client = it->data;
            if (!client->frame->visible && client_should_show(client))
-                engine_frame_show(client->frame);
+                frame_show(client->frame);
        }
     }
 
index 81809649848b74766b6a8ca255660f1f4b99055b..115c1182553c3c8947b191403d7b53be269901e9 100644 (file)
@@ -116,6 +116,8 @@ static void event(ObEvent *e, void *foo)
     if (e->type == Event_X_KeyRelease)
         return;
 
+    g_assert(e->type == Event_X_KeyPress);
+
     if (e->data.x.e->xkey.keycode == reset_key &&
         e->data.x.e->xkey.state == reset_state) {
         reset_chains();
index 37c22bd80843d277cd711e8f2b1bd141060fe1a8..b2173c25156a9a2a3c870a7a59a3cb4cf4b71e67 100644 (file)
@@ -3,9 +3,7 @@
 #include "kernel/action.h"
 #include "kernel/event.h"
 #include "kernel/client.h"
-#include "kernel/frame.h"
 #include "kernel/grab.h"
-#include "kernel/engine.h"
 #include "kernel/parse.h"
 #include "kernel/frame.h"
 #include "translate.h"
@@ -242,8 +240,8 @@ static void event(ObEvent *e, void *foo)
             button = e->data.x.e->xbutton.button;
             state = e->data.x.e->xbutton.state;
         }
-        context = engine_get_context(e->data.x.client,
-                                     e->data.x.e->xbutton.window);
+        context = frame_context(e->data.x.client->frame,
+                                e->data.x.e->xbutton.window);
 
         fire_button(MouseAction_Press, context,
                     e->data.x.client, e->data.x.e->xbutton.state,
@@ -257,8 +255,8 @@ static void event(ObEvent *e, void *foo)
             break;
 
     case Event_X_ButtonRelease:
-        context = engine_get_context(e->data.x.client,
-                                     e->data.x.e->xbutton.window);
+        context = frame_context(e->data.x.client->frame,
+                                e->data.x.e->xbutton.window);
         if (e->data.x.e->xbutton.button == button) {
             /* end drags */
             if (drag_used) {
@@ -316,8 +314,8 @@ static void event(ObEvent *e, void *foo)
                 (ABS(dx) >= threshold || ABS(dy) >= threshold))
                 drag = TRUE;
             if (drag) {
-                context = engine_get_context(e->data.x.client,
-                                             e->data.x.e->xbutton.window);
+                context = frame_context(e->data.x.client->frame,
+                                        e->data.x.e->xbutton.window);
                 drag_used = fire_motion(MouseAction_Motion, context,
                                         e->data.x.client,
                                         state, button, cx, cy, cw, ch, dx, dy,
index 7a8b3196a1496ac318b639fde6084f4e6ae6ea24..f3de6485c3017d748284a33b4dd943da72374d2e 100644 (file)
@@ -9,3 +9,4 @@ mask.lo
 render.lo
 test.lo
 libobrender.la
+theme.lo
index eaa89d56e04bf155203c161c788e7d7509e4cad0..6a5d4c65a621617d6886562ebcfea4b0e9107817 100644 (file)
@@ -2,7 +2,7 @@
 #define __font_h
 #include <X11/Xft/Xft.h>
 #include "render.h"
-#include "../kernel/geom.h"
+#include "kernel/geom.h"
 
 void font_startup(void);
 ObFont *font_open(char *fontstring);
index 89716f852f205ff6d03e847ef471053a8b6488e1..9328daf154997269549221597e7abbb767c8cce1 100644 (file)
@@ -2,7 +2,7 @@
 #define __mask_h
 
 #include "render.h"
-#include "../kernel/geom.h"
+#include "kernel/geom.h"
 
 pixmap_mask *pixmap_mask_new(int w, int h, char *data);
 pixmap_mask *pixmap_mask_copy(pixmap_mask *src);
index 1a41b219bcb77333a50c652221976b61f05e1bd5..ff11c65cde1bb55fa7a441afec2059a3c9ee620f 100644 (file)
@@ -6,7 +6,7 @@
 #include <X11/Xft/Xft.h>
 #include <glib.h>
 #include "color.h"
-#include "../kernel/geom.h"
+#include "kernel/geom.h"
 
 typedef enum {
     Surface_Planar,
diff --git a/render/theme.c b/render/theme.c
new file mode 100644 (file)
index 0000000..d6f248c
--- /dev/null
@@ -0,0 +1,819 @@
+#include "render.h"
+#include "color.h"
+#include "font.h"
+#include "mask.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+/* style settings - geometry */
+int theme_bevel;
+int theme_handle_height;
+int theme_bwidth;
+int theme_cbwidth;
+/* style settings - colors */
+color_rgb *theme_b_color;
+color_rgb *theme_cb_focused_color;
+color_rgb *theme_cb_unfocused_color;
+color_rgb *theme_title_focused_color;
+color_rgb *theme_title_unfocused_color;
+color_rgb *theme_titlebut_focused_color;
+color_rgb *theme_titlebut_unfocused_color;
+/* style settings - fonts */
+int theme_winfont_height;
+ObFont *theme_winfont;
+gboolean theme_winfont_shadow;
+int theme_winfont_shadow_offset;
+int theme_winfont_shadow_tint;
+/* style settings - title layout */
+char *theme_title_layout;
+/* style settings - masks */
+pixmap_mask *theme_max_set_mask;
+pixmap_mask *theme_max_unset_mask;
+pixmap_mask *theme_iconify_mask;
+pixmap_mask *theme_desk_set_mask;
+pixmap_mask *theme_desk_unset_mask;
+pixmap_mask *theme_shade_set_mask;
+pixmap_mask *theme_shade_unset_mask;
+pixmap_mask *theme_close_mask;
+
+/* global appearances */
+Appearance *theme_a_focused_unpressed_max;
+Appearance *theme_a_focused_pressed_max;
+Appearance *theme_a_focused_pressed_set_max;
+Appearance *theme_a_unfocused_unpressed_max;
+Appearance *theme_a_unfocused_pressed_max;
+Appearance *theme_a_unfocused_pressed_set_max;
+Appearance *theme_a_focused_unpressed_close;
+Appearance *theme_a_focused_pressed_close;
+Appearance *theme_a_unfocused_unpressed_close;
+Appearance *theme_a_unfocused_pressed_close;
+Appearance *theme_a_focused_unpressed_desk;
+Appearance *theme_a_focused_pressed_desk;
+Appearance *theme_a_focused_pressed_set_desk;
+Appearance *theme_a_unfocused_unpressed_desk;
+Appearance *theme_a_unfocused_pressed_desk;
+Appearance *theme_a_unfocused_pressed_set_desk;
+Appearance *theme_a_focused_unpressed_shade;
+Appearance *theme_a_focused_pressed_shade;
+Appearance *theme_a_focused_pressed_set_shade;
+Appearance *theme_a_unfocused_unpressed_shade;
+Appearance *theme_a_unfocused_pressed_shade;
+Appearance *theme_a_unfocused_pressed_set_shade;
+Appearance *theme_a_focused_unpressed_iconify;
+Appearance *theme_a_focused_pressed_iconify;
+Appearance *theme_a_unfocused_unpressed_iconify;
+Appearance *theme_a_unfocused_pressed_iconify;
+Appearance *theme_a_focused_grip;
+Appearance *theme_a_unfocused_grip;
+Appearance *theme_a_focused_title;
+Appearance *theme_a_unfocused_title;
+Appearance *theme_a_focused_label;
+Appearance *theme_a_unfocused_label;
+Appearance *theme_a_icon; /* always parentrelative, so no focused/unfocused */
+Appearance *theme_a_focused_handle;
+Appearance *theme_a_unfocused_handle;
+
+Appearance *theme_app_hilite_label;
+Appearance *theme_app_unhilite_label;
+
+void theme_startup()
+{
+    theme_b_color = theme_cb_unfocused_color = theme_cb_focused_color = 
+        theme_title_unfocused_color = theme_title_focused_color = 
+        theme_titlebut_unfocused_color = theme_titlebut_focused_color = NULL;
+    theme_winfont = NULL;
+    theme_title_layout = NULL;
+    theme_max_set_mask = theme_max_unset_mask = NULL;
+    theme_desk_set_mask = theme_desk_unset_mask = NULL;
+    theme_shade_set_mask = theme_shade_unset_mask = NULL;
+    theme_iconify_mask = theme_close_mask = NULL;
+
+    theme_a_focused_unpressed_max = appearance_new(Surface_Planar, 1);
+    theme_a_focused_pressed_max = appearance_new(Surface_Planar, 1);
+    theme_a_focused_pressed_set_max = appearance_new(Surface_Planar, 1);
+    theme_a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1);
+    theme_a_unfocused_pressed_max = appearance_new(Surface_Planar, 1);
+    theme_a_unfocused_pressed_set_max = appearance_new(Surface_Planar, 1);
+    theme_a_focused_unpressed_close = NULL;
+    theme_a_focused_pressed_close = NULL;
+    theme_a_unfocused_unpressed_close = NULL;
+    theme_a_unfocused_pressed_close = NULL;
+    theme_a_focused_unpressed_desk = NULL;
+    theme_a_focused_pressed_desk = NULL;
+    theme_a_focused_pressed_set_desk = NULL;
+    theme_a_unfocused_unpressed_desk = NULL;
+    theme_a_unfocused_pressed_desk = NULL;
+    theme_a_unfocused_pressed_set_desk = NULL;
+    theme_a_focused_unpressed_shade = NULL;
+    theme_a_focused_pressed_shade = NULL;
+    theme_a_focused_pressed_set_shade = NULL;
+    theme_a_unfocused_unpressed_shade = NULL;
+    theme_a_unfocused_pressed_shade = NULL;
+    theme_a_unfocused_pressed_set_shade = NULL;
+    theme_a_focused_unpressed_iconify = NULL;
+    theme_a_focused_pressed_iconify = NULL;
+    theme_a_unfocused_unpressed_iconify = NULL;
+    theme_a_unfocused_pressed_iconify = NULL;
+    theme_a_focused_grip = appearance_new(Surface_Planar, 0);
+    theme_a_unfocused_grip = appearance_new(Surface_Planar, 0);
+    theme_a_focused_title = appearance_new(Surface_Planar, 0);
+    theme_a_unfocused_title = appearance_new(Surface_Planar, 0);
+    theme_a_focused_label = appearance_new(Surface_Planar, 1);
+    theme_a_unfocused_label = appearance_new(Surface_Planar, 1);
+    theme_a_icon = appearance_new(Surface_Planar, 1);
+    theme_a_focused_handle = appearance_new(Surface_Planar, 0);
+    theme_a_unfocused_handle = appearance_new(Surface_Planar, 0);
+    theme_app_hilite_label = appearance_new(Surface_Planar, 1);
+    theme_app_unhilite_label = appearance_new(Surface_Planar, 1);
+
+}
+
+void theme_shutdown()
+{
+    color_free(theme_b_color);
+    color_free(theme_cb_unfocused_color);
+    color_free(theme_cb_focused_color);
+    color_free(theme_title_unfocused_color);
+    color_free(theme_title_focused_color);
+    color_free(theme_titlebut_unfocused_color);
+    color_free(theme_titlebut_focused_color);
+
+    pixmap_mask_free(theme_max_set_mask);
+    pixmap_mask_free(theme_max_unset_mask);
+    pixmap_mask_free(theme_desk_set_mask);
+    pixmap_mask_free(theme_desk_unset_mask);
+    pixmap_mask_free(theme_shade_set_mask);
+    pixmap_mask_free(theme_shade_unset_mask);
+    pixmap_mask_free(theme_iconify_mask);
+    pixmap_mask_free(theme_close_mask);
+
+    font_close(theme_winfont);
+    g_free(theme_title_layout);
+
+    appearance_free(theme_a_focused_unpressed_max);
+    appearance_free(theme_a_focused_pressed_max);
+    appearance_free(theme_a_focused_pressed_set_max);
+    appearance_free(theme_a_unfocused_unpressed_max);
+    appearance_free(theme_a_unfocused_pressed_max);
+    appearance_free(theme_a_unfocused_pressed_set_max);
+    appearance_free(theme_a_focused_unpressed_close);
+    appearance_free(theme_a_focused_pressed_close);
+    appearance_free(theme_a_unfocused_unpressed_close);
+    appearance_free(theme_a_unfocused_pressed_close);
+    appearance_free(theme_a_focused_unpressed_desk);
+    appearance_free(theme_a_focused_pressed_desk);
+    appearance_free(theme_a_unfocused_unpressed_desk);
+    appearance_free(theme_a_unfocused_pressed_desk);
+    appearance_free(theme_a_focused_unpressed_shade);
+    appearance_free(theme_a_focused_pressed_shade);
+    appearance_free(theme_a_unfocused_unpressed_shade);
+    appearance_free(theme_a_unfocused_pressed_shade);
+    appearance_free(theme_a_focused_unpressed_iconify);
+    appearance_free(theme_a_focused_pressed_iconify);
+    appearance_free(theme_a_unfocused_unpressed_iconify);
+    appearance_free(theme_a_unfocused_pressed_iconify);
+    appearance_free(theme_a_focused_grip);
+    appearance_free(theme_a_unfocused_grip);
+    appearance_free(theme_a_focused_title);
+    appearance_free(theme_a_unfocused_title);
+    appearance_free(theme_a_focused_label);
+    appearance_free(theme_a_unfocused_label);
+    appearance_free(theme_a_icon);
+    appearance_free(theme_a_focused_handle);
+    appearance_free(theme_a_unfocused_handle);
+    appearance_free(theme_app_hilite_label);
+    appearance_free(theme_app_unhilite_label);
+}
+
+static XrmDatabase loaddb(char *theme)
+{
+    XrmDatabase db;
+
+    db = XrmGetFileDatabase(theme);
+    if (db == NULL) {
+       char *s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
+                                  theme, NULL);
+       db = XrmGetFileDatabase(s);
+       g_free(s);
+    }
+    if (db == NULL) {
+       char *s = g_build_filename(THEMEDIR, theme, NULL);
+       db = XrmGetFileDatabase(s);
+       g_free(s);
+    }
+    return db;
+}
+
+static char *create_class_name(char *rname)
+{
+    char *rclass = g_strdup(rname);
+    char *p = rclass;
+
+    while (TRUE) {
+       *p = toupper(*p);
+       p = strchr(p+1, '.');
+       if (p == NULL) break;
+       ++p;
+       if (*p == '\0') break;
+    }
+    return rclass;
+}
+
+static gboolean read_int(XrmDatabase db, char *rname, int *value)
+{
+    gboolean ret = FALSE;
+    char *rclass = create_class_name(rname);
+    char *rettype, *end;
+    XrmValue retvalue;
+  
+    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+       retvalue.addr != NULL) {
+       *value = (int)strtol(retvalue.addr, &end, 10);
+       if (end != retvalue.addr)
+           ret = TRUE;
+    }
+
+    g_free(rclass);
+    return ret;
+}
+
+static gboolean read_string(XrmDatabase db, char *rname, char **value)
+{
+    gboolean ret = FALSE;
+    char *rclass = create_class_name(rname);
+    char *rettype;
+    XrmValue retvalue;
+  
+    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+       retvalue.addr != NULL) {
+       *value = g_strdup(retvalue.addr);
+       ret = TRUE;
+    }
+
+    g_free(rclass);
+    return ret;
+}
+
+static gboolean read_color(XrmDatabase db, char *rname, color_rgb **value)
+{
+    gboolean ret = FALSE;
+    char *rclass = create_class_name(rname);
+    char *rettype;
+    XrmValue retvalue;
+  
+    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+       retvalue.addr != NULL) {
+       color_rgb *c = color_parse(retvalue.addr);
+       if (c != NULL) {
+           *value = c;
+           ret = TRUE;
+       }
+    }
+
+    g_free(rclass);
+    return ret;
+}
+
+static gboolean read_mask(XrmDatabase db, char *rname, char *theme,
+                          pixmap_mask **value)
+{
+    gboolean ret = FALSE;
+    char *rclass = create_class_name(rname);
+    char *rettype;
+    char *s;
+    char *button_dir;
+    XrmValue retvalue;
+    int hx, hy; /* ignored */
+    unsigned int w, h;
+    unsigned char *b;
+  
+    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+        retvalue.addr != NULL) {
+
+       button_dir = g_strdup_printf("%s_buttons", theme);
+
+        s = g_build_filename(g_get_home_dir(), ".openbox", "themes",
+                             button_dir, retvalue.addr, NULL);
+
+        if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess)
+            ret = TRUE;
+        else {
+            g_free(s);
+            s = g_build_filename(THEMEDIR, button_dir, retvalue.addr, NULL);
+       
+            if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == BitmapSuccess) 
+                ret = TRUE;
+            else {
+                char *themename;
+
+                g_free(s);
+                themename = g_path_get_basename(theme);
+                s = g_strdup_printf("%s/%s_buttons/%s", theme,
+                                    themename, retvalue.addr);
+                g_free(themename);
+                if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) ==
+                    BitmapSuccess) 
+                    ret = TRUE;
+                else
+                    g_message("Unable to find bitmap '%s'", retvalue.addr);
+            }
+        }
+
+        if (ret) {
+            *value = pixmap_mask_new(w, h, (char*)b);
+            XFree(b);
+        }
+      
+        g_free(s);
+        g_free(button_dir);
+    }
+
+    g_free(rclass);
+    return ret;
+}
+
+static void parse_appearance(char *tex, SurfaceColorType *grad,
+                             ReliefType *relief, BevelType *bevel,
+                             gboolean *interlaced, gboolean *border)
+{
+    char *t;
+
+    /* convert to all lowercase */
+    for (t = tex; *t != '\0'; ++t)
+       *t = g_ascii_tolower(*t);
+
+    if (strstr(tex, "parentrelative") != NULL) {
+       *grad = Background_ParentRelative;
+    } else {
+       if (strstr(tex, "gradient") != NULL) {
+           if (strstr(tex, "crossdiagonal") != NULL)
+               *grad = Background_CrossDiagonal;
+           else if (strstr(tex, "rectangle") != NULL)
+               *grad = Background_Rectangle;
+           else if (strstr(tex, "pyramid") != NULL)
+               *grad = Background_Pyramid;
+           else if (strstr(tex, "pipecross") != NULL)
+               *grad = Background_PipeCross;
+           else if (strstr(tex, "elliptic") != NULL)
+               *grad = Background_Elliptic;
+           else if (strstr(tex, "horizontal") != NULL)
+               *grad = Background_Horizontal;
+           else if (strstr(tex, "vertical") != NULL)
+               *grad = Background_Vertical;
+           else
+               *grad = Background_Diagonal;
+       } else {
+           *grad = Background_Solid;
+       }
+
+       if (strstr(tex, "sunken") != NULL)
+           *relief = Sunken;
+       else if (strstr(tex, "flat") != NULL)
+           *relief = Flat;
+       else
+           *relief = Raised;
+       
+       *border = FALSE;
+       if (*relief == Flat) {
+           if (strstr(tex, "border") != NULL)
+               *border = TRUE;
+       } else {
+           if (strstr(tex, "bevel2") != NULL)
+               *bevel = Bevel2;
+           else
+               *bevel = Bevel1;
+       }
+
+       if (strstr(tex, "interlaced") != NULL)
+           *interlaced = TRUE;
+       else
+           *interlaced = FALSE;
+    }
+}
+
+
+static gboolean read_appearance(XrmDatabase db, char *rname, Appearance *value)
+{
+    gboolean ret = FALSE;
+    char *rclass = create_class_name(rname), *cname, *ctoname, *bcname;
+    char *rettype;
+    XrmValue retvalue;
+
+    cname = g_strconcat(rname, ".color", NULL);
+    ctoname = g_strconcat(rname, ".colorTo", NULL);
+    bcname = g_strconcat(rname, ".borderColor", NULL);
+
+    if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
+       retvalue.addr != NULL) {
+       parse_appearance(retvalue.addr,
+                        &value->surface.data.planar.grad,
+                        &value->surface.data.planar.relief,
+                        &value->surface.data.planar.bevel,
+                        &value->surface.data.planar.interlaced,
+                        &value->surface.data.planar.border);
+       if (!read_color(db, cname, &value->surface.data.planar.primary))
+           value->surface.data.planar.primary = color_new(0, 0, 0);
+       if (!read_color(db, ctoname, &value->surface.data.planar.secondary))
+           value->surface.data.planar.secondary = color_new(0, 0, 0);
+       if (value->surface.data.planar.border)
+           if (!read_color(db, bcname,
+                           &value->surface.data.planar.border_color))
+               value->surface.data.planar.border_color = color_new(0, 0, 0);
+       ret = TRUE;
+    }
+
+    g_free(bcname);
+    g_free(ctoname);
+    g_free(cname);
+    g_free(rclass);
+    return ret;
+}
+
+static void set_default_appearance(Appearance *a)
+{
+    a->surface.data.planar.grad = Background_Solid;
+    a->surface.data.planar.relief = Flat;
+    a->surface.data.planar.bevel = Bevel1;
+    a->surface.data.planar.interlaced = FALSE;
+    a->surface.data.planar.border = FALSE;
+    a->surface.data.planar.primary = color_new(0, 0, 0);
+    a->surface.data.planar.secondary = color_new(0, 0, 0);
+}
+
+char *theme_load(char *theme)
+{
+    XrmDatabase db = NULL;
+    char *loaded = NULL;
+    Justify winjust;
+    char *winjust_str;
+    char *winfont_str;
+
+    if (theme) {
+       db = loaddb(theme);
+        if (db == NULL) {
+           g_warning("Failed to load the theme '%s'", theme);
+           g_message("Falling back to the default: '%s'", DEFAULT_THEME);
+       } else
+            loaded = g_strdup(theme);
+    }
+    if (db == NULL) {
+       db = loaddb(DEFAULT_THEME);
+       if (db == NULL) {
+           g_warning("Failed to load the theme '%s'.", DEFAULT_THEME);
+           return NULL;
+       } else
+            loaded = g_strdup(DEFAULT_THEME);
+    }
+
+    /* load the font stuff */
+    winfont_str = "arial-8:bold";
+    theme_winfont_shadow = FALSE;
+    theme_winfont_shadow_offset = 1;
+    theme_winfont_shadow_tint = 25;
+
+    theme_winfont = font_open(winfont_str);
+    theme_winfont_height = font_height(theme_winfont, theme_winfont_shadow,
+                                      theme_winfont_shadow_offset);
+
+    winjust = Justify_Left;
+    if (read_string(db, "window.justify", &winjust_str)) {
+        if (!g_ascii_strcasecmp(winjust_str, "right"))
+            winjust = Justify_Right;
+        else if (!g_ascii_strcasecmp(winjust_str, "center"))
+            winjust = Justify_Center;
+        g_free(winjust_str);
+    }
+
+    /* load the title layout */
+    theme_title_layout = g_strdup("NLIMC");
+
+    if (!read_int(db, "handleWidth", &theme_handle_height) ||
+       theme_handle_height < 0 || theme_handle_height > 100)
+        theme_handle_height = 6;
+    if (!read_int(db, "bevelWidth", &theme_bevel) ||
+       theme_bevel <= 0 || theme_bevel > 100) theme_bevel = 3;
+    if (!read_int(db, "borderWidth", &theme_bwidth) ||
+       theme_bwidth < 0 || theme_bwidth > 100) theme_bwidth = 1;
+    if (!read_int(db, "frameWidth", &theme_cbwidth) ||
+       theme_cbwidth < 0 || theme_cbwidth > 100) theme_cbwidth = theme_bevel;
+
+    if (!read_color(db, "borderColor", &theme_b_color))
+       theme_b_color = color_new(0, 0, 0);
+    if (!read_color(db, "window.frame.focusColor", &theme_cb_focused_color))
+       theme_cb_focused_color = color_new(0xff, 0xff, 0xff);
+    if (!read_color(db, "window.frame.unfocusColor", &theme_cb_unfocused_color))
+       theme_cb_unfocused_color = color_new(0xff, 0xff, 0xff);
+    if (!read_color(db, "window.label.focus.textColor",
+                    &theme_title_focused_color))
+       theme_title_focused_color = color_new(0x0, 0x0, 0x0);
+    if (!read_color(db, "window.label.unfocus.textColor",
+                    &theme_title_unfocused_color))
+       theme_title_unfocused_color = color_new(0xff, 0xff, 0xff);
+    if (!read_color(db, "window.button.focus.picColor",
+                    &theme_titlebut_focused_color))
+       theme_titlebut_focused_color = color_new(0, 0, 0);
+    if (!read_color(db, "window.button.unfocus.picColor",
+                    &theme_titlebut_unfocused_color))
+       theme_titlebut_unfocused_color = color_new(0xff, 0xff, 0xff);
+
+    if (read_mask(db, "window.button.max.mask", theme, &theme_max_unset_mask)){
+        if (!read_mask(db, "window.button.max.toggled.mask", theme,
+                       &theme_max_set_mask)) {
+            theme_max_set_mask = pixmap_mask_copy(theme_max_unset_mask);
+        }
+    } else {
+        {
+            char data[] = { 0x7f, 0x7f, 0x7f, 0x41, 0x41, 0x41, 0x7f };
+            theme_max_unset_mask = pixmap_mask_new(7, 7, data);
+        }
+        {
+            char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f };
+            theme_max_set_mask = pixmap_mask_new(7, 7, data);
+        }
+    }
+
+    if (!read_mask(db, "window.button.icon.mask", theme,
+                   &theme_iconify_mask)) {
+        char data[] = { 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f };
+        theme_iconify_mask = pixmap_mask_new(7, 7, data);
+    }
+
+    if (read_mask(db, "window.button.stick.mask", theme,
+                   &theme_desk_unset_mask)) {
+        if (!read_mask(db, "window.button.stick.toggled.mask", theme,
+                       &theme_desk_set_mask)) {
+            theme_desk_set_mask =
+                pixmap_mask_copy(theme_desk_unset_mask);
+        }
+    } else {
+        {
+            char data[] = { 0x63, 0x63, 0x00, 0x00, 0x00, 0x63, 0x63 };
+            theme_desk_unset_mask = pixmap_mask_new(7, 7, data);
+        }
+        {
+            char data[] = { 0x00, 0x36, 0x36, 0x08, 0x36, 0x36, 0x00 };
+            theme_desk_set_mask = pixmap_mask_new(7, 7, data);
+        }
+    }
+
+    if (read_mask(db, "window.button.shade.mask", theme,
+                   &theme_shade_unset_mask)) {
+        if (!read_mask(db, "window.button.shade.toggled.mask", theme,
+                       &theme_shade_set_mask)) {
+            theme_shade_set_mask =
+                pixmap_mask_copy(theme_shade_unset_mask);
+        }
+    } else {
+        {
+            char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 };
+            theme_shade_unset_mask = pixmap_mask_new(7, 7, data);
+        }
+        {
+            char data[] = { 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x7f };
+            theme_shade_set_mask = pixmap_mask_new(7, 7, data);
+        }
+    }
+
+    if (!read_mask(db, "window.button.close.mask", theme,
+                   &theme_close_mask)) {
+        char data[] = { 0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63 };
+        theme_close_mask = pixmap_mask_new(7, 7, data);
+    }        
+
+    /* read the decoration textures */
+    if (!read_appearance(db, "window.title.focus", theme_a_focused_title))
+       set_default_appearance(theme_a_focused_title);
+    if (!read_appearance(db, "window.title.unfocus", theme_a_unfocused_title))
+       set_default_appearance(theme_a_unfocused_title);
+    if (!read_appearance(db, "window.label.focus", theme_a_focused_label))
+       set_default_appearance(theme_a_focused_label);
+    if (!read_appearance(db, "window.label.unfocus", theme_a_unfocused_label))
+       set_default_appearance(theme_a_unfocused_label);
+    if (!read_appearance(db, "window.handle.focus", theme_a_focused_handle))
+       set_default_appearance(theme_a_focused_handle);
+    if (!read_appearance(db, "window.handle.unfocus", theme_a_unfocused_handle))
+       set_default_appearance(theme_a_unfocused_handle);
+    if (!read_appearance(db, "window.grip.focus", theme_a_focused_grip))
+       set_default_appearance(theme_a_focused_grip);
+    if (!read_appearance(db, "window.grip.unfocus", theme_a_unfocused_grip))
+       set_default_appearance(theme_a_unfocused_grip);
+
+    /* read the appearances for rendering non-decorations. these cannot be
+       parent-relative */
+    if (theme_a_focused_label->surface.data.planar.grad !=
+        Background_ParentRelative) {
+        if (!read_appearance(db, "window.label.focus", theme_app_hilite_label))
+            set_default_appearance(theme_app_hilite_label);
+    } else {
+        if (!read_appearance(db, "window.title.focus", theme_app_hilite_label))
+            set_default_appearance(theme_app_hilite_label);
+    }
+    if (theme_a_unfocused_label->surface.data.planar.grad !=
+        Background_ParentRelative) {
+        if (!read_appearance(db, "window.label.unfocus",
+                             theme_app_unhilite_label))
+            set_default_appearance(theme_app_unhilite_label);
+    } else {
+        if (!read_appearance(db, "window.title.unfocus",
+                             theme_app_unhilite_label))
+            set_default_appearance(theme_app_unhilite_label);
+    }
+
+    /* read buttons textures */
+    if (!read_appearance(db, "window.button.pressed.focus",
+                        theme_a_focused_pressed_max))
+       if (!read_appearance(db, "window.button.pressed",
+                             theme_a_focused_pressed_max))
+           set_default_appearance(theme_a_focused_pressed_max);
+    if (!read_appearance(db, "window.button.pressed.unfocus",
+                        theme_a_unfocused_pressed_max))
+       if (!read_appearance(db, "window.button.pressed",
+                            theme_a_unfocused_pressed_max))
+           set_default_appearance(theme_a_unfocused_pressed_max);
+    if (!read_appearance(db, "window.button.focus",
+                        theme_a_focused_unpressed_max))
+       set_default_appearance(theme_a_focused_unpressed_max);
+    if (!read_appearance(db, "window.button.unfocus",
+                        theme_a_unfocused_unpressed_max))
+       set_default_appearance(theme_a_unfocused_unpressed_max);
+
+    theme_a_unfocused_unpressed_close =
+        appearance_copy(theme_a_unfocused_unpressed_max);
+    theme_a_unfocused_pressed_close =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_focused_unpressed_close =
+        appearance_copy(theme_a_focused_unpressed_max);
+    theme_a_focused_pressed_close =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_unfocused_unpressed_desk =
+        appearance_copy(theme_a_unfocused_unpressed_max);
+    theme_a_unfocused_pressed_desk =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_unfocused_pressed_set_desk =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_focused_unpressed_desk =
+        appearance_copy(theme_a_focused_unpressed_max);
+    theme_a_focused_pressed_desk =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_focused_pressed_set_desk =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_unfocused_unpressed_shade =
+        appearance_copy(theme_a_unfocused_unpressed_max);
+    theme_a_unfocused_pressed_shade =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_unfocused_pressed_set_shade =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_focused_unpressed_shade =
+        appearance_copy(theme_a_focused_unpressed_max);
+    theme_a_focused_pressed_shade =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_focused_pressed_set_shade =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_unfocused_unpressed_iconify =
+        appearance_copy(theme_a_unfocused_unpressed_max);
+    theme_a_unfocused_pressed_iconify =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_focused_unpressed_iconify =
+        appearance_copy(theme_a_focused_unpressed_max);
+    theme_a_focused_pressed_iconify =
+        appearance_copy(theme_a_focused_pressed_max);
+    theme_a_unfocused_pressed_set_max =
+        appearance_copy(theme_a_unfocused_pressed_max);
+    theme_a_focused_pressed_set_max =
+        appearance_copy(theme_a_focused_pressed_max);
+
+    theme_a_icon->surface.data.planar.grad = Background_ParentRelative;
+
+    /* set up the textures */
+    theme_a_focused_label->texture[0].type = 
+        theme_app_hilite_label->texture[0].type = Text;
+    theme_a_focused_label->texture[0].data.text.justify =
+        theme_app_hilite_label->texture[0].data.text.justify = winjust;
+    theme_a_focused_label->texture[0].data.text.font =
+        theme_app_hilite_label->texture[0].data.text.font = theme_winfont;
+    theme_a_focused_label->texture[0].data.text.shadow =
+        theme_app_hilite_label->texture[0].data.text.shadow =
+        theme_winfont_shadow;
+    theme_a_focused_label->texture[0].data.text.offset =
+        theme_app_hilite_label->texture[0].data.text.offset =
+        theme_winfont_shadow_offset;
+    theme_a_focused_label->texture[0].data.text.tint =
+        theme_app_hilite_label->texture[0].data.text.tint =
+        theme_winfont_shadow_tint;
+    theme_a_focused_label->texture[0].data.text.color =
+        theme_app_hilite_label->texture[0].data.text.color =
+        theme_title_focused_color;
+
+    theme_a_unfocused_label->texture[0].type =
+        theme_app_unhilite_label->texture[0].type = Text;
+    theme_a_unfocused_label->texture[0].data.text.justify =
+        theme_app_unhilite_label->texture[0].data.text.justify = winjust;
+    theme_a_unfocused_label->texture[0].data.text.font =
+        theme_app_unhilite_label->texture[0].data.text.font = theme_winfont;
+    theme_a_unfocused_label->texture[0].data.text.shadow =
+        theme_app_unhilite_label->texture[0].data.text.shadow =
+        theme_winfont_shadow;
+    theme_a_unfocused_label->texture[0].data.text.offset =
+        theme_app_unhilite_label->texture[0].data.text.offset =
+        theme_winfont_shadow_offset;
+    theme_a_unfocused_label->texture[0].data.text.tint =
+        theme_app_unhilite_label->texture[0].data.text.tint =
+        theme_winfont_shadow_tint;
+    theme_a_unfocused_label->texture[0].data.text.color =
+        theme_app_unhilite_label->texture[0].data.text.color =
+        theme_title_unfocused_color;
+
+    theme_a_focused_unpressed_max->texture[0].type = 
+        theme_a_focused_pressed_max->texture[0].type = 
+        theme_a_focused_pressed_set_max->texture[0].type =  
+        theme_a_unfocused_unpressed_max->texture[0].type = 
+        theme_a_unfocused_pressed_max->texture[0].type = 
+        theme_a_unfocused_pressed_set_max->texture[0].type = 
+        theme_a_focused_unpressed_close->texture[0].type = 
+        theme_a_focused_pressed_close->texture[0].type = 
+        theme_a_unfocused_unpressed_close->texture[0].type = 
+        theme_a_unfocused_pressed_close->texture[0].type = 
+        theme_a_focused_unpressed_desk->texture[0].type = 
+        theme_a_focused_pressed_desk->texture[0].type = 
+        theme_a_focused_pressed_set_desk->texture[0].type = 
+        theme_a_unfocused_unpressed_desk->texture[0].type = 
+        theme_a_unfocused_pressed_desk->texture[0].type = 
+        theme_a_unfocused_pressed_set_desk->texture[0].type = 
+        theme_a_focused_unpressed_shade->texture[0].type = 
+        theme_a_focused_pressed_shade->texture[0].type = 
+        theme_a_focused_pressed_set_shade->texture[0].type = 
+        theme_a_unfocused_unpressed_shade->texture[0].type = 
+        theme_a_unfocused_pressed_shade->texture[0].type = 
+        theme_a_unfocused_pressed_set_shade->texture[0].type = 
+        theme_a_focused_unpressed_iconify->texture[0].type = 
+        theme_a_focused_pressed_iconify->texture[0].type = 
+        theme_a_unfocused_unpressed_iconify->texture[0].type = 
+        theme_a_unfocused_pressed_iconify->texture[0].type = Bitmask;
+    theme_a_focused_unpressed_max->texture[0].data.mask.mask = 
+        theme_a_unfocused_unpressed_max->texture[0].data.mask.mask = 
+        theme_a_focused_pressed_max->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_max->texture[0].data.mask.mask =
+        theme_max_unset_mask;
+    theme_a_focused_pressed_set_max->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_set_max->texture[0].data.mask.mask =
+        theme_max_set_mask;
+    theme_a_focused_pressed_close->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_close->texture[0].data.mask.mask =
+        theme_a_focused_unpressed_close->texture[0].data.mask.mask = 
+        theme_a_unfocused_unpressed_close->texture[0].data.mask.mask =
+        theme_close_mask;
+    theme_a_focused_unpressed_desk->texture[0].data.mask.mask = 
+        theme_a_unfocused_unpressed_desk->texture[0].data.mask.mask = 
+        theme_a_focused_pressed_desk->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_desk->texture[0].data.mask.mask =
+        theme_desk_unset_mask;
+    theme_a_focused_pressed_set_desk->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_set_desk->texture[0].data.mask.mask =
+        theme_desk_set_mask;
+    theme_a_focused_unpressed_shade->texture[0].data.mask.mask = 
+        theme_a_unfocused_unpressed_shade->texture[0].data.mask.mask = 
+        theme_a_focused_pressed_shade->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_shade->texture[0].data.mask.mask =
+        theme_shade_unset_mask;
+    theme_a_focused_pressed_set_shade->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_set_shade->texture[0].data.mask.mask =
+        theme_shade_set_mask;
+    theme_a_focused_unpressed_iconify->texture[0].data.mask.mask = 
+        theme_a_unfocused_unpressed_iconify->texture[0].data.mask.mask = 
+        theme_a_focused_pressed_iconify->texture[0].data.mask.mask = 
+        theme_a_unfocused_pressed_iconify->texture[0].data.mask.mask =
+        theme_iconify_mask;
+    theme_a_focused_unpressed_max->texture[0].data.mask.color = 
+        theme_a_focused_pressed_max->texture[0].data.mask.color = 
+        theme_a_focused_pressed_set_max->texture[0].data.mask.color = 
+        theme_a_focused_unpressed_close->texture[0].data.mask.color = 
+        theme_a_focused_pressed_close->texture[0].data.mask.color = 
+        theme_a_focused_unpressed_desk->texture[0].data.mask.color = 
+        theme_a_focused_pressed_desk->texture[0].data.mask.color = 
+        theme_a_focused_pressed_set_desk->texture[0].data.mask.color = 
+        theme_a_focused_unpressed_shade->texture[0].data.mask.color = 
+        theme_a_focused_pressed_shade->texture[0].data.mask.color = 
+        theme_a_focused_pressed_set_shade->texture[0].data.mask.color = 
+        theme_a_focused_unpressed_iconify->texture[0].data.mask.color = 
+        theme_a_focused_pressed_iconify->texture[0].data.mask.color =
+        theme_titlebut_focused_color;
+    theme_a_unfocused_unpressed_max->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_max->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_set_max->texture[0].data.mask.color = 
+        theme_a_unfocused_unpressed_close->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_close->texture[0].data.mask.color = 
+        theme_a_unfocused_unpressed_desk->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_desk->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_set_desk->texture[0].data.mask.color = 
+        theme_a_unfocused_unpressed_shade->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_shade->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_set_shade->texture[0].data.mask.color = 
+        theme_a_unfocused_unpressed_iconify->texture[0].data.mask.color = 
+        theme_a_unfocused_pressed_iconify->texture[0].data.mask.color =
+        theme_titlebut_unfocused_color;
+
+    XrmDestroyDatabase(db);
+
+    return loaded;
+}
diff --git a/render/theme.h b/render/theme.h
new file mode 100644 (file)
index 0000000..5d5bac1
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef __theme_h
+#define __theme_h
+
+#include "render.h"
+#include "color.h"
+#include "font.h"
+#include "mask.h"
+
+extern int theme_bevel;
+extern int theme_handle_height;
+extern int theme_bwidth;
+extern int theme_cbwidth;
+
+#define theme_label_height (theme_winfont_height + 2)
+#define theme_title_height (theme_label_height + theme_bevel * 2)
+#define theme_button_size  (theme_label_height - 2)
+#define theme_grip_width   (theme_button_size * 2)
+
+extern color_rgb *theme_b_color;
+extern color_rgb *theme_cb_focused_color;
+extern color_rgb *theme_cb_unfocused_color;
+extern color_rgb *theme_title_focused_color;
+extern color_rgb *theme_title_unfocused_color;
+extern color_rgb *theme_titlebut_focused_color;
+extern color_rgb *theme_titlebut_unfocused_color;
+
+extern int theme_winfont_height;
+extern ObFont *theme_winfont;
+extern char *theme_title_layout;
+
+extern pixmap_mask *theme_max_set_mask;
+extern pixmap_mask *theme_max_unset_mask;
+extern pixmap_mask *theme_iconify_mask;
+extern pixmap_mask *theme_desk_set_mask;
+extern pixmap_mask *theme_desk_unset_mask;
+extern pixmap_mask *theme_shade_set_mask;
+extern pixmap_mask *theme_shade_unset_mask;
+extern pixmap_mask *theme_close_mask;
+
+extern Appearance *theme_a_focused_unpressed_max;
+extern Appearance *theme_a_focused_pressed_max;
+extern Appearance *theme_a_focused_pressed_set_max;
+extern Appearance *theme_a_unfocused_unpressed_max;
+extern Appearance *theme_a_unfocused_pressed_max;
+extern Appearance *theme_a_unfocused_pressed_set_max;
+extern Appearance *theme_a_focused_unpressed_close;
+extern Appearance *theme_a_focused_pressed_close;
+extern Appearance *theme_a_unfocused_unpressed_close;
+extern Appearance *theme_a_unfocused_pressed_close;
+extern Appearance *theme_a_focused_unpressed_desk;
+extern Appearance *theme_a_focused_pressed_desk;
+extern Appearance *theme_a_focused_pressed_set_desk;
+extern Appearance *theme_a_unfocused_unpressed_desk;
+extern Appearance *theme_a_unfocused_pressed_desk;
+extern Appearance *theme_a_unfocused_pressed_set_desk;
+extern Appearance *theme_a_focused_unpressed_shade;
+extern Appearance *theme_a_focused_pressed_shade;
+extern Appearance *theme_a_focused_pressed_set_shade;
+extern Appearance *theme_a_unfocused_unpressed_shade;
+extern Appearance *theme_a_unfocused_pressed_shade;
+extern Appearance *theme_a_unfocused_pressed_set_shade;
+extern Appearance *theme_a_focused_unpressed_iconify;
+extern Appearance *theme_a_focused_pressed_iconify;
+extern Appearance *theme_a_unfocused_unpressed_iconify;
+extern Appearance *theme_a_unfocused_pressed_iconify;
+extern Appearance *theme_a_focused_grip;
+extern Appearance *theme_a_unfocused_grip;
+extern Appearance *theme_a_focused_title;
+extern Appearance *theme_a_unfocused_title;
+extern Appearance *theme_a_focused_label;
+extern Appearance *theme_a_unfocused_label;
+extern Appearance *theme_a_icon;
+extern Appearance *theme_a_focused_handle;
+extern Appearance *theme_a_unfocused_handle;
+
+extern Appearance *theme_app_hilite_label;
+extern Appearance *theme_app_unhilite_label;
+
+void theme_startup();
+void theme_shutdown();
+
+char *theme_load(char *theme);
+
+#endif
This page took 0.148725 seconds and 4 git commands to generate.