move the openbox engine into librender and the kernel. the theme is loaded and stored inside librender. the frame is decorated and managed inside the kernel.

This commit is contained in:
Dana Jansens 2003-04-13 07:18:28 +00:00
parent fb16966596
commit 5cf61ee023
43 changed files with 1997 additions and 2309 deletions

View file

@ -1,6 +1,6 @@
include build/Makefile.incl include build/Makefile.incl
targets = render cwmcc obcl kernel plugins engines themes data targets = render cwmcc obcl kernel plugins themes data
all: libtool all: libtool
@for i in $(targets); do \ @for i in $(targets); do \

View file

@ -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

View file

@ -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

View file

@ -9,8 +9,8 @@ LIBS += $(GLIB_LIBS) $(GMODULE_LIBS) $(XFT_LIBS) $(X_LIBS) $(XINERAMA_LIBS) \
LDFLAGS += -Lrender -export-dynamic LDFLAGS += -Lrender -export-dynamic
target = openbox3 target = openbox3
sources = action.c client.c config.c dispatch.c engine.c event.c group.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 \ 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.c plugin.c prop.c screen.c stacking.c timer.c xerror.c \
parse.lex.c parse.tab.c parse.lex.c parse.tab.c
@ -41,7 +41,7 @@ $(dir)/%.lo: $(srcdir)/%.c $(depdir)/%.d
$(depdir)/%.d: $(srcdir)/%.c $(depdir)/%.d: $(srcdir)/%.c
@echo Building dependancies for $< @echo Building dependancies for $<
$(INSTALL) -d $(depdir) @$(INSTALL) -d $(depdir)
@$(CC) $(CPPFLAGS) $(CFLAGS) -w -MM -MF $@ -MQ $(<:.c=.lo) $< @$(CC) $(CPPFLAGS) $(CFLAGS) -w -MM -MF $@ -MQ $(<:.c=.lo) $<
install: install:

View file

@ -1,11 +1,13 @@
include build/Makefile.incl include build/Makefile.incl
dir = render 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 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) srcdir := $(srcdir)/$(dir)
target := $(addprefix $(dir)/, $(target)) target := $(addprefix $(dir)/, $(target))

View file

@ -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

View file

@ -84,9 +84,7 @@ static gboolean get_all(Window win, Atom prop, Atom type, int size,
&ret_items, &bytes_left, &xdata); &ret_items, &bytes_left, &xdata);
if (res == Success) { if (res == Success) {
if (ret_size == size && ret_items > 0) { if (ret_size == size && ret_items > 0) {
*data = g_malloc(ret_items * (size / 8) + sizeof(guchar*)); *data = g_memdup(xdata, ret_items * (size / 8));
g_memmove(*data, xdata, ret_items * (size / 8));
data[ret_items * (size / 8)] = NULL;
*num = ret_items; *num = ret_items;
ret = TRUE; ret = TRUE;
} }

View file

@ -5,36 +5,34 @@
#include <string.h> #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), 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); g_warning("Failed to read NET_SUPPORTED from 0x%lx", win);
*atoms = NULL; *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), 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); g_warning("Failed to read NET_CLIENT_LIST from 0x%lx", win);
*windows = NULL; *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), 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); g_warning("Failed to read NET_CLIENT_LIST_STACKING from 0x%lx", win);
*windows = NULL; *windows = NULL;
*num = 0;
} }
} }

View file

@ -4,11 +4,12 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <glib.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); void cwmcc_root_get_number_of_desktops(Window win, gulong *desktops);

View file

View file

@ -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

View file

@ -1,5 +0,0 @@
openbox.la
obengine.lo
obtheme.lo
obrender.lo
.libs

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -1,8 +0,0 @@
#ifndef __engines_openbox_render_h
#define __engines_openbox_render_h
#include "obengine.h"
void obrender_frame(ObFrame *self);
#endif

View file

@ -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;
}

View file

@ -1,8 +0,0 @@
#ifndef __engine_theme_h
#define __engine_theme_h
#include <glib.h>
gboolean obtheme_load();
#endif

View file

@ -1,4 +1,4 @@
all clean distclean install uninstall: all clean distclean install uninstall:
$(MAKE) -$(MAKEFLAGS) -C ../.. $@ $(MAKE) -$(MAKEFLAGS) -C .. $@
.PHONY: all clean distclean install uninstall .PHONY: all clean distclean install uninstall

View file

@ -4,3 +4,25 @@ parse.tab.c
parse.tab.h parse.tab.h
.libs .libs
parse.lex.c 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

View file

@ -2,12 +2,11 @@
#include "focus.h" #include "focus.h"
#include "stacking.h" #include "stacking.h"
#include "frame.h" #include "frame.h"
#include "framerender.h"
#include "screen.h" #include "screen.h"
#include "action.h" #include "action.h"
#include "dispatch.h" #include "dispatch.h"
#include "openbox.h" #include "openbox.h"
#include "engine.h"
#include "render/render.h"
#include <glib.h> #include <glib.h>
@ -649,10 +648,10 @@ static void popup_coords(char *format, int a, int b, gboolean hide)
char *text; char *text;
text = g_strdup_printf(format, a, b); text = g_strdup_printf(format, a, b);
engine_size_label(text, TRUE, TRUE, &s); framerender_size_popup_label(text, &s);
XMoveResizeWindow(ob_display, coords, XMoveResizeWindow(ob_display, coords,
10, 10, s.width, s.height); 10, 10, s.width, s.height);
engine_render_label(coords, &s, text, TRUE, TRUE); framerender_popup_label(coords, &s, text);
g_free(text); g_free(text);
XMapWindow(ob_display, coords); XMapWindow(ob_display, coords);
@ -733,12 +732,12 @@ static void popup_cycle(Client *c, gboolean hide)
a = screen_area(c->desktop); a = screen_area(c->desktop);
engine_size_label(c->title, TRUE, TRUE, &s); framerender_size_popup_label(c->title, &s);
XMoveResizeWindow(ob_display, coords, XMoveResizeWindow(ob_display, coords,
a->x + (a->width - s.width) / 2, a->x + (a->width - s.width) / 2,
a->y + (a->height - s.height) / 2, a->y + (a->height - s.height) / 2,
s.width, s.height); s.width, s.height);
engine_render_label(coords, &s, c->title, TRUE, TRUE); framerender_popup_label(coords, &s, c->title);
XMapWindow(ob_display, coords); XMapWindow(ob_display, coords);
} }

View file

@ -3,7 +3,6 @@
#include "prop.h" #include "prop.h"
#include "extensions.h" #include "extensions.h"
#include "frame.h" #include "frame.h"
#include "engine.h"
#include "event.h" #include "event.h"
#include "grab.h" #include "grab.h"
#include "focus.h" #include "focus.h"
@ -206,9 +205,9 @@ void client_manage(Window window)
XChangeSaveSet(ob_display, window, SetModeInsert); XChangeSaveSet(ob_display, window, SetModeInsert);
/* create the decoration frame for the client window */ /* 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); client_apply_startup_state(self);
@ -290,7 +289,7 @@ void client_unmanage(Client *self)
/* we dont want events no more */ /* we dont want events no more */
XSelectInput(ob_display, self->window, NoEventMask); XSelectInput(ob_display, self->window, NoEventMask);
engine_frame_hide(self->frame); frame_hide(self->frame);
client_list = g_list_remove(client_list, self); client_list = g_list_remove(client_list, self);
stacking_list = g_list_remove(stacking_list, self); stacking_list = g_list_remove(stacking_list, self);
@ -347,7 +346,7 @@ void client_unmanage(Client *self)
client_toggle_border(self, TRUE); client_toggle_border(self, TRUE);
/* reparent the window out of the frame, and free the frame */ /* 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; self->frame = NULL;
if (ob_state != State_Exiting) { if (ob_state != State_Exiting) {
@ -933,7 +932,7 @@ void client_setup_decor_and_functions(Client *self)
if (self->frame) { if (self->frame) {
/* change the decors on the frame, and with more/less decorations, /* change the decors on the frame, and with more/less decorations,
we may also need to be repositioned */ 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 */ /* with new decor, the window's maximized size may change */
client_remaximize(self); client_remaximize(self);
} }
@ -1051,7 +1050,7 @@ void client_update_wmhints(Client *self)
self->pixmap_icon_mask = None; self->pixmap_icon_mask = None;
if (self->frame) 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; self->title = data;
if (self->frame) if (self->frame)
engine_frame_adjust_title(self->frame); frame_adjust_title(self->frame);
} }
void client_update_icon_title(Client *self) void client_update_icon_title(Client *self)
@ -1224,7 +1223,7 @@ void client_update_icons(Client *self)
} }
if (self->frame) if (self->frame)
engine_frame_adjust_icon(self->frame); frame_adjust_icon(self->frame);
} }
void client_update_kwm_icon(Client *self) 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; self->pixmap_icon = self->pixmap_icon_mask = None;
} }
if (self->frame) if (self->frame)
engine_frame_adjust_icon(self->frame); frame_adjust_icon(self->frame);
} }
static void client_change_state(Client *self) static void client_change_state(Client *self)
@ -1278,7 +1277,7 @@ static void client_change_state(Client *self)
client_calc_layer(self); client_calc_layer(self);
if (self->frame) if (self->frame)
engine_frame_adjust_state(self->frame); frame_adjust_state(self->frame);
} }
static Client *search_focus_tree(Client *node, Client *skip) static Client *search_focus_tree(Client *node, Client *skip)
@ -1349,9 +1348,9 @@ static void client_showhide(Client *self)
{ {
if (client_should_show(self)) if (client_should_show(self))
engine_frame_show(self->frame); frame_show(self->frame);
else else
engine_frame_hide(self->frame); frame_hide(self->frame);
} }
gboolean client_normal(Client *self) { 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 */ /* move/resize the frame to match the request */
if (self->frame) { if (self->frame) {
if (moved || resized) if (moved || resized)
engine_frame_adjust_area(self->frame, moved, resized); frame_adjust_area(self->frame, moved, resized);
if (!user || final) { if (!user || final) {
XEvent event; XEvent event;
@ -1790,7 +1789,7 @@ void client_shade(Client *self, gboolean shade)
self->shaded = shade; self->shaded = shade;
client_change_state(self); client_change_state(self);
/* resize the frame to just the titlebar */ /* 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) void client_close(Client *self)
@ -1839,7 +1838,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
self->desktop = target; self->desktop = target;
PROP_SET32(self->window, net_wm_desktop, cardinal, target); PROP_SET32(self->window, net_wm_desktop, cardinal, target);
/* the frame can display the current desktop state */ /* 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 */ /* 'move' the window to the new desktop */
if (!donthide) if (!donthide)
client_showhide(self); client_showhide(self);

View file

@ -12,21 +12,6 @@ extern gboolean config_focus_last;
/*! Focus the last focused window as a fallback when switching desktops */ /*! Focus the last focused window as a fallback when switching desktops */
extern gboolean config_focus_last_on_desktop; 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 */ /*! The number of desktops */
extern int config_desktops_num; extern int config_desktops_num;
/*! Names for the desktops */ /*! Names for the desktops */

View file

@ -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);
}
}

View file

@ -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

View file

@ -5,12 +5,11 @@
#include "config.h" #include "config.h"
#include "screen.h" #include "screen.h"
#include "frame.h" #include "frame.h"
#include "engine.h" #include "framerender.h"
#include "focus.h" #include "focus.h"
#include "stacking.h" #include "stacking.h"
#include "extensions.h" #include "extensions.h"
#include "timer.h" #include "timer.h"
#include "engine.h"
#include "dispatch.h" #include "dispatch.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -368,6 +367,34 @@ static void event_handle_client(Client *client, XEvent *e)
int i=0; int i=0;
switch (e->type) { 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: case FocusIn:
focus_set_client(client); focus_set_client(client);
case FocusOut: case FocusOut:
@ -377,7 +404,7 @@ static void event_handle_client(Client *client, XEvent *e)
#endif #endif
/* focus state can affect the stacking layer */ /* focus state can affect the stacking layer */
client_calc_layer(client); client_calc_layer(client);
engine_frame_adjust_focus(client->frame); frame_adjust_focus(client->frame);
break; break;
case EnterNotify: case EnterNotify:
if (client_normal(client)) { if (client_normal(client)) {
@ -639,7 +666,7 @@ static void event_handle_client(Client *client, XEvent *e)
#ifdef SHAPE #ifdef SHAPE
if (extensions_shape && e->type == extensions_shape_event_basep) { if (extensions_shape && e->type == extensions_shape_event_basep) {
client->shaped = ((XShapeEvent*)e)->shaped; client->shaped = ((XShapeEvent*)e)->shaped;
engine_frame_adjust_shape(client->frame); frame_adjust_shape(client->frame);
} }
#endif #endif
} }

View file

@ -9,7 +9,6 @@
#include "dispatch.h" #include "dispatch.h"
#include "focus.h" #include "focus.h"
#include "parse.h" #include "parse.h"
#include "engine.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <glib.h> #include <glib.h>

View file

@ -1,4 +1,615 @@
#include "frame.h" #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) Context frame_context_from_string(char *name)
{ {
@ -35,6 +646,29 @@ Context frame_context_from_string(char *name)
return Context_None; 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) void frame_client_gravity(Frame *self, int *x, int *y)
{ {
/* horizontal */ /* horizontal */

View file

@ -3,6 +3,7 @@
#include "geom.h" #include "geom.h"
#include "client.h" #include "client.h"
#include "render/render.h"
typedef enum { typedef enum {
Context_None, Context_None,
@ -24,7 +25,8 @@ typedef enum {
NUM_CONTEXTS NUM_CONTEXTS
} Context; } 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 { typedef struct Frame {
Client *client; Client *client;
@ -35,8 +37,69 @@ typedef struct Frame {
Strut size; Strut size;
Rect area; Rect area;
gboolean visible; 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; } 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 /*! Applies gravity to the client's position to find where the frame should
be positioned. be positioned.
@return The proper coordinates for the frame, based on the client. @return The proper coordinates for the frame, based on the client.

248
openbox/framerender.c Normal file
View file

@ -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;
}

11
openbox/framerender.h Normal file
View file

@ -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

View file

@ -6,17 +6,18 @@
#include "prop.h" #include "prop.h"
#include "screen.h" #include "screen.h"
#include "focus.h" #include "focus.h"
#include "frame.h"
#include "extensions.h" #include "extensions.h"
#include "parse.h" #include "parse.h"
#include "grab.h" #include "grab.h"
#include "engine.h"
#include "plugin.h" #include "plugin.h"
#include "timer.h" #include "timer.h"
#include "group.h" #include "group.h"
#include "config.h" #include "config.h"
#include "gettext.h" #include "gettext.h"
#include "../render/render.h" #include "render/render.h"
#include "../render/font.h" #include "render/font.h"
#include "render/theme.h"
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> # include <fcntl.h>
@ -64,6 +65,7 @@ int main(int argc, char **argv)
struct sigaction action; struct sigaction action;
sigset_t sigset; sigset_t sigset;
char *path; char *path;
char *theme;
ob_state = State_Starting; ob_state = State_Starting;
@ -157,9 +159,9 @@ int main(int argc, char **argv)
timer_startup(); timer_startup();
render_startup(); render_startup();
font_startup(); font_startup();
theme_startup();
event_startup(); event_startup();
grab_startup(); grab_startup();
engine_startup();
plugin_startup(); plugin_startup();
/* load the plugins specified in the pluginrc */ /* load the plugins specified in the pluginrc */
plugin_loadall(); plugin_loadall();
@ -171,9 +173,12 @@ int main(int argc, char **argv)
/* we're done with parsing now, kill it */ /* we're done with parsing now, kill it */
parse_shutdown(); parse_shutdown();
/* load the engine specified in the rc */ /* load the theme specified in the rc file */
engine_load(); theme = theme_load("ebox"); /* woot i like this theme :) */
g_free(theme);
if (!theme) return 1;
frame_startup();
focus_startup(); focus_startup();
screen_startup(); screen_startup();
group_startup(); group_startup();
@ -197,9 +202,10 @@ int main(int argc, char **argv)
group_shutdown(); group_shutdown();
screen_shutdown(); screen_shutdown();
focus_shutdown(); focus_shutdown();
engine_shutdown(); frame_shutdown();
grab_shutdown(); grab_shutdown();
event_shutdown(); event_shutdown();
theme_shutdown();
render_shutdown(); render_shutdown();
timer_shutdown(); timer_shutdown();
config_shutdown(); config_shutdown();

View file

@ -4,7 +4,7 @@
# include <stdlib.h> # include <stdlib.h>
#endif #endif
int yylineno = 1; extern int lineno;
%} %}
real [-0-9][0-9]*\.[0-9]+ 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]*#.* /* comment */
^[ \t]*\n /* empty lines */ { ++yylineno; } ^[ \t]*\n /* empty lines */ { ++lineno; }
[ \t] /* whitespace */ [ \t] /* whitespace */
{real} { yylval.real = atof(yytext); return REAL; } {real} { yylval.real = atof(yytext); return REAL; }
{integer} { yylval.integer = atoi(yytext); return INTEGER; } {integer} { yylval.integer = atoi(yytext); return INTEGER; }

View file

@ -23,7 +23,7 @@ extern int yylex();
extern int yyparse(); extern int yyparse();
void yyerror(char *err); void yyerror(char *err);
extern int yylineno; extern int lineno;
extern FILE *yyin; extern FILE *yyin;
static char *path; static char *path;
@ -56,14 +56,14 @@ void parse_set_section(char *section);
sections: sections:
| sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n' | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
{ ++yylineno; } lines { ++lineno; } lines
; ;
lines: lines:
| lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n' | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
{ ++yylineno; } { ++lineno; }
| lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n' | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
{ ++yylineno; } { ++lineno; }
; ;
tokens: tokens:
@ -115,8 +115,10 @@ listtoken:
%% %%
int lineno;
void yyerror(char *err) { void yyerror(char *err) {
g_message("%s:%d: %s", path, yylineno, err); g_message("%s:%d: %s", path, lineno, err);
} }
void parse_rc() void parse_rc()
@ -134,7 +136,7 @@ void parse_rc()
} }
} }
yylineno = 1; lineno = 1;
yyparse(); yyparse();

View file

@ -4,7 +4,6 @@
#include "screen.h" #include "screen.h"
#include "client.h" #include "client.h"
#include "frame.h" #include "frame.h"
#include "engine.h"
#include "focus.h" #include "focus.h"
#include "dispatch.h" #include "dispatch.h"
#include "../render/render.h" #include "../render/render.h"
@ -287,14 +286,14 @@ void screen_set_desktop(guint num)
for (it = stacking_list; it != NULL; it = it->next) { for (it = stacking_list; it != NULL; it = it->next) {
Client *c = it->data; Client *c = it->data;
if (!c->frame->visible && client_should_show(c)) if (!c->frame->visible && client_should_show(c))
engine_frame_show(c->frame); frame_show(c->frame);
} }
/* hide windows from bottom to top */ /* hide windows from bottom to top */
for (it = g_list_last(stacking_list); it != NULL; it = it->prev) { for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
Client *c = it->data; Client *c = it->data;
if (c->frame->visible && !client_should_show(c)) 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 /* 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) { for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
Client *client = it->data; Client *client = it->data;
if (client->frame->visible && !client_should_show(client)) if (client->frame->visible && !client_should_show(client))
engine_frame_hide(client->frame); frame_hide(client->frame);
} }
} else { } else {
/* top to bottom */ /* top to bottom */
for (it = stacking_list; it != NULL; it = it->next) { for (it = stacking_list; it != NULL; it = it->next) {
Client *client = it->data; Client *client = it->data;
if (!client->frame->visible && client_should_show(client)) if (!client->frame->visible && client_should_show(client))
engine_frame_show(client->frame); frame_show(client->frame);
} }
} }

View file

@ -116,6 +116,8 @@ static void event(ObEvent *e, void *foo)
if (e->type == Event_X_KeyRelease) if (e->type == Event_X_KeyRelease)
return; return;
g_assert(e->type == Event_X_KeyPress);
if (e->data.x.e->xkey.keycode == reset_key && if (e->data.x.e->xkey.keycode == reset_key &&
e->data.x.e->xkey.state == reset_state) { e->data.x.e->xkey.state == reset_state) {
reset_chains(); reset_chains();

View file

@ -3,9 +3,7 @@
#include "kernel/action.h" #include "kernel/action.h"
#include "kernel/event.h" #include "kernel/event.h"
#include "kernel/client.h" #include "kernel/client.h"
#include "kernel/frame.h"
#include "kernel/grab.h" #include "kernel/grab.h"
#include "kernel/engine.h"
#include "kernel/parse.h" #include "kernel/parse.h"
#include "kernel/frame.h" #include "kernel/frame.h"
#include "translate.h" #include "translate.h"
@ -242,7 +240,7 @@ static void event(ObEvent *e, void *foo)
button = e->data.x.e->xbutton.button; button = e->data.x.e->xbutton.button;
state = e->data.x.e->xbutton.state; state = e->data.x.e->xbutton.state;
} }
context = engine_get_context(e->data.x.client, context = frame_context(e->data.x.client->frame,
e->data.x.e->xbutton.window); e->data.x.e->xbutton.window);
fire_button(MouseAction_Press, context, fire_button(MouseAction_Press, context,
@ -257,7 +255,7 @@ static void event(ObEvent *e, void *foo)
break; break;
case Event_X_ButtonRelease: case Event_X_ButtonRelease:
context = engine_get_context(e->data.x.client, context = frame_context(e->data.x.client->frame,
e->data.x.e->xbutton.window); e->data.x.e->xbutton.window);
if (e->data.x.e->xbutton.button == button) { if (e->data.x.e->xbutton.button == button) {
/* end drags */ /* end drags */
@ -316,7 +314,7 @@ static void event(ObEvent *e, void *foo)
(ABS(dx) >= threshold || ABS(dy) >= threshold)) (ABS(dx) >= threshold || ABS(dy) >= threshold))
drag = TRUE; drag = TRUE;
if (drag) { if (drag) {
context = engine_get_context(e->data.x.client, context = frame_context(e->data.x.client->frame,
e->data.x.e->xbutton.window); e->data.x.e->xbutton.window);
drag_used = fire_motion(MouseAction_Motion, context, drag_used = fire_motion(MouseAction_Motion, context,
e->data.x.client, e->data.x.client,

View file

@ -9,3 +9,4 @@ mask.lo
render.lo render.lo
test.lo test.lo
libobrender.la libobrender.la
theme.lo

View file

@ -2,7 +2,7 @@
#define __font_h #define __font_h
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include "render.h" #include "render.h"
#include "../kernel/geom.h" #include "kernel/geom.h"
void font_startup(void); void font_startup(void);
ObFont *font_open(char *fontstring); ObFont *font_open(char *fontstring);

View file

@ -2,7 +2,7 @@
#define __mask_h #define __mask_h
#include "render.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_new(int w, int h, char *data);
pixmap_mask *pixmap_mask_copy(pixmap_mask *src); pixmap_mask *pixmap_mask_copy(pixmap_mask *src);

View file

@ -6,7 +6,7 @@
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include <glib.h> #include <glib.h>
#include "color.h" #include "color.h"
#include "../kernel/geom.h" #include "kernel/geom.h"
typedef enum { typedef enum {
Surface_Planar, Surface_Planar,

819
render/theme.c Normal file
View file

@ -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;
}

84
render/theme.h Normal file
View file

@ -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