From 883a38eeb21e4c166e31f25a9af32b739d85d409 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 28 Mar 2003 04:42:26 +0000 Subject: split the render functions into obrender.c. rename all the src files to obfoo so no more conflicts with code elsewhere in the tree. --- engines/openbox/Makefile.am | 4 +- engines/openbox/obengine.c | 779 ++++++++++++++++++++++++++++++++ engines/openbox/obengine.h | 109 +++++ engines/openbox/obrender.c | 199 +++++++++ engines/openbox/obrender.h | 8 + engines/openbox/obtheme.c | 514 +++++++++++++++++++++ engines/openbox/obtheme.h | 8 + engines/openbox/openbox.c | 1030 ------------------------------------------- engines/openbox/openbox.h | 58 --- engines/openbox/theme.c | 514 --------------------- engines/openbox/theme.h | 8 - 11 files changed, 1619 insertions(+), 1612 deletions(-) create mode 100644 engines/openbox/obengine.c create mode 100644 engines/openbox/obengine.h create mode 100644 engines/openbox/obrender.c create mode 100644 engines/openbox/obrender.h create mode 100644 engines/openbox/obtheme.c create mode 100644 engines/openbox/obtheme.h delete mode 100644 engines/openbox/openbox.c delete mode 100644 engines/openbox/openbox.h delete mode 100644 engines/openbox/theme.c delete mode 100644 engines/openbox/theme.h diff --git a/engines/openbox/Makefile.am b/engines/openbox/Makefile.am index c239e8e8..800956d9 100644 --- a/engines/openbox/Makefile.am +++ b/engines/openbox/Makefile.am @@ -11,9 +11,9 @@ CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \ engine_LTLIBRARIES=openbox.la openbox_la_LDFLAGS=-module -avoid-version -openbox_la_SOURCES=openbox.c theme.c +openbox_la_SOURCES=obengine.c obtheme.c obrender.c -noinst_HEADERS=openbox.h theme.h +noinst_HEADERS=obengine.h obtheme.h obrender.h MAINTAINERCLEANFILES= Makefile.in diff --git a/engines/openbox/obengine.c b/engines/openbox/obengine.c new file mode 100644 index 00000000..090852c3 --- /dev/null +++ b/engines/openbox/obengine.c @@ -0,0 +1,779 @@ +#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" + +#include +#include + +#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask) +#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask) +#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \ + ButtonMotionMask | ExposureMask) + +/* style settings - geometry */ +int s_bevel; +int s_handle_height; +int s_bwidth; +int s_cbwidth; +/* style settings - colors */ +color_rgb *s_b_color; +color_rgb *s_cb_focused_color; +color_rgb *s_cb_unfocused_color; +color_rgb *s_title_focused_color; +color_rgb *s_title_unfocused_color; +color_rgb *s_titlebut_focused_color; +color_rgb *s_titlebut_unfocused_color; +/* style settings - fonts */ +int s_winfont_height; +int s_winfont_shadow; +int s_winfont_shadow_offset; +ObFont *s_winfont; +/* style settings - masks */ +pixmap_mask *s_max_mask; +pixmap_mask *s_icon_mask; +pixmap_mask *s_desk_mask; +pixmap_mask *s_close_mask; + +/* global appearances */ +Appearance *a_focused_unpressed_max; +Appearance *a_focused_pressed_max; +Appearance *a_unfocused_unpressed_max; +Appearance *a_unfocused_pressed_max; +Appearance *a_focused_unpressed_close; +Appearance *a_focused_pressed_close; +Appearance *a_unfocused_unpressed_close; +Appearance *a_unfocused_pressed_close; +Appearance *a_focused_unpressed_desk; +Appearance *a_focused_pressed_desk; +Appearance *a_unfocused_unpressed_desk; +Appearance *a_unfocused_pressed_desk; +Appearance *a_focused_unpressed_iconify; +Appearance *a_focused_pressed_iconify; +Appearance *a_unfocused_unpressed_iconify; +Appearance *a_unfocused_pressed_iconify; +Appearance *a_focused_grip; +Appearance *a_unfocused_grip; +Appearance *a_focused_title; +Appearance *a_unfocused_title; +Appearance *a_focused_label; +Appearance *a_unfocused_label; +Appearance *a_icon; /* always parentrelative, so no focused/unfocused */ +Appearance *a_focused_handle; +Appearance *a_unfocused_handle; + +static void layout_title(ObFrame *self); +static void frame_mouse_press(const ObEvent *e, ObFrame *self); +static void frame_mouse_release(const ObEvent *e, ObFrame *self); + +gboolean startup() +{ + g_quark_from_string("none"); + g_quark_from_string("root"); + g_quark_from_string("client"); + g_quark_from_string("titlebar"); + g_quark_from_string("handle"); + g_quark_from_string("frame"); + g_quark_from_string("blcorner"); + g_quark_from_string("brcorner"); + g_quark_from_string("maximize"); + g_quark_from_string("alldesktops"); + g_quark_from_string("iconify"); + g_quark_from_string("icon"); + g_quark_from_string("close"); + + s_b_color = s_cb_unfocused_color = s_cb_focused_color = + s_title_unfocused_color = s_title_focused_color = + s_titlebut_unfocused_color = s_titlebut_focused_color = NULL; + s_winfont = NULL; + s_max_mask = s_icon_mask = s_desk_mask = s_close_mask = NULL; + + a_focused_unpressed_max = appearance_new(Surface_Planar, 1); + a_focused_pressed_max = appearance_new(Surface_Planar, 1); + a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1); + a_unfocused_pressed_max = appearance_new(Surface_Planar, 1); + a_focused_unpressed_close = NULL; + a_focused_pressed_close = NULL; + a_unfocused_unpressed_close = NULL; + a_unfocused_pressed_close = NULL; + a_focused_unpressed_desk = NULL; + a_focused_pressed_desk = NULL; + a_unfocused_unpressed_desk = NULL; + a_unfocused_pressed_desk = NULL; + a_focused_unpressed_iconify = NULL; + a_focused_pressed_iconify = NULL; + a_unfocused_unpressed_iconify = NULL; + a_unfocused_pressed_iconify = NULL; + a_focused_grip = appearance_new(Surface_Planar, 0); + a_unfocused_grip = appearance_new(Surface_Planar, 0); + a_focused_title = appearance_new(Surface_Planar, 0); + a_unfocused_title = appearance_new(Surface_Planar, 0); + a_focused_label = appearance_new(Surface_Planar, 1); + a_unfocused_label = appearance_new(Surface_Planar, 1); + a_icon = appearance_new(Surface_Planar, 1); + a_focused_handle = appearance_new(Surface_Planar, 0); + a_unfocused_handle = appearance_new(Surface_Planar, 0); + + if (load()) { + RECT_SET(a_focused_pressed_desk->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_unpressed_desk->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_pressed_desk->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_unpressed_desk->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_pressed_iconify->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_unpressed_iconify->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_pressed_iconify->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_unpressed_iconify->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_unpressed_iconify->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_pressed_max->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_unpressed_max->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_pressed_max->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_unpressed_max->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_pressed_close->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_focused_unpressed_close->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_pressed_close->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + RECT_SET(a_unfocused_unpressed_close->area, 0, 0, + BUTTON_SIZE, BUTTON_SIZE); + + RECT_SET(a_focused_grip->area, 0, 0, GRIP_WIDTH, s_handle_height); + RECT_SET(a_unfocused_grip->area, 0, 0, GRIP_WIDTH, s_handle_height); + return TRUE; + } else + return FALSE; +} + +void shutdown() +{ + if (s_b_color != NULL) color_free(s_b_color); + if (s_cb_unfocused_color != NULL) color_free(s_cb_unfocused_color); + if (s_cb_focused_color != NULL) color_free(s_cb_focused_color); + if (s_title_unfocused_color != NULL) color_free(s_title_unfocused_color); + if (s_title_focused_color != NULL) color_free(s_title_focused_color); + if (s_titlebut_unfocused_color != NULL) + color_free(s_titlebut_unfocused_color); + if (s_titlebut_focused_color != NULL) + color_free(s_titlebut_focused_color); + + if (s_max_mask != NULL) pixmap_mask_free(s_max_mask); + if (s_desk_mask != NULL) pixmap_mask_free(s_desk_mask); + if (s_icon_mask != NULL) pixmap_mask_free(s_icon_mask); + if (s_close_mask != NULL) pixmap_mask_free(s_close_mask); + + if (s_winfont != NULL) font_close(s_winfont); + + appearance_free(a_focused_unpressed_max); + appearance_free(a_focused_pressed_max); + appearance_free(a_unfocused_unpressed_max); + appearance_free(a_unfocused_pressed_max); + if (a_focused_unpressed_close != NULL) + appearance_free(a_focused_unpressed_close); + if (a_focused_pressed_close != NULL) + appearance_free(a_focused_pressed_close); + if (a_unfocused_unpressed_close != NULL) + appearance_free(a_unfocused_unpressed_close); + if (a_unfocused_pressed_close != NULL) + appearance_free(a_unfocused_pressed_close); + if (a_focused_unpressed_desk != NULL) + appearance_free(a_focused_unpressed_desk); + if (a_focused_pressed_desk != NULL) + appearance_free(a_focused_pressed_desk); + if (a_unfocused_unpressed_desk != NULL) + appearance_free(a_unfocused_unpressed_desk); + if (a_unfocused_pressed_desk != NULL) + appearance_free(a_unfocused_pressed_desk); + if (a_focused_unpressed_iconify != NULL) + appearance_free(a_focused_unpressed_iconify); + if (a_focused_pressed_iconify != NULL) + appearance_free(a_focused_pressed_iconify); + if (a_unfocused_unpressed_iconify != NULL) + appearance_free(a_unfocused_unpressed_iconify); + if (a_unfocused_pressed_iconify != NULL) + appearance_free(a_unfocused_pressed_iconify); + appearance_free(a_focused_grip); + appearance_free(a_unfocused_grip); + appearance_free(a_focused_title); + appearance_free(a_unfocused_title); + appearance_free(a_focused_label); + appearance_free(a_unfocused_label); + appearance_free(a_icon); + appearance_free(a_focused_handle); + appearance_free(a_unfocused_handle); +} + +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->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, s_b_color->pixel); + XSetWindowBorder(ob_display, self->label, s_b_color->pixel); + XSetWindowBorder(ob_display, self->rgrip, s_b_color->pixel); + XSetWindowBorder(ob_display, self->lgrip, 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->lgrip, GRIP_WIDTH, s_handle_height); + XResizeWindow(ob_display, self->rgrip, GRIP_WIDTH, s_handle_height); + + /* set up the dynamic appearances */ + self->a_unfocused_title = appearance_copy(a_unfocused_title); + self->a_focused_title = appearance_copy(a_focused_title); + self->a_unfocused_label = appearance_copy(a_unfocused_label); + self->a_focused_label = appearance_copy(a_focused_label); + self->a_unfocused_handle = appearance_copy(a_unfocused_handle); + self->a_focused_handle = appearance_copy(a_focused_handle); + self->a_icon = appearance_copy(a_icon); + + self->max_press = self->close_press = self->desk_press = + self->iconify_press = FALSE; + + dispatch_register(Event_X_ButtonPress, (EventHandler)frame_mouse_press, + self); + dispatch_register(Event_X_ButtonRelease, (EventHandler)frame_mouse_release, + 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)frame_mouse_press, self); + dispatch_register(0, (EventHandler)frame_mouse_release, 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 = -s_bevel; + xrect[0].y = -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 = -s_bevel; + xrect[1].y = HANDLE_Y(self); + xrect[1].width = self->width + self->bwidth * 2; + xrect[1].height = 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 = s_bwidth; + self->cbwidth = 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->icon_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); + /* make all the titlebar stuff not render */ + self->frame.client->decorations &= ~(Decor_Icon | Decor_Iconify | + Decor_Maximize | Decor_Close | + Decor_AllDesktops); + } + + if (self->frame.client->decorations & Decor_Handle) { + XMoveResizeWindow(ob_display, self->handle, + -self->bwidth, HANDLE_Y(self), + self->width, 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 += s_handle_height + + self->bwidth; + XMapWindow(ob_display, self->handle); + + if (self->a_focused_handle->surface.data.planar.grad == + Background_ParentRelative) + RECT_SET(self->a_focused_handle->area, 0, 0, + self->width, s_handle_height); + else + RECT_SET(self->a_focused_handle->area, + GRIP_WIDTH + self->bwidth, 0, + self->width - (GRIP_WIDTH + self->bwidth) * 2, + s_handle_height); + if (self->a_unfocused_handle->surface.data.planar.grad == + Background_ParentRelative) + RECT_SET(self->a_unfocused_handle->area, 0, 0, + self->width, s_handle_height); + else + RECT_SET(self->a_unfocused_handle->area, + GRIP_WIDTH + self->bwidth, 0, + self->width - (GRIP_WIDTH + self->bwidth) * 2, + 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) { + render_frame(self); + + frame_adjust_shape(self); + } +} + +void frame_adjust_state(ObFrame *self) +{ + render_frame(self); +} + +void frame_adjust_focus(ObFrame *self) +{ + render_frame(self); +} + +void frame_adjust_title(ObFrame *self) +{ + render_frame(self); +} + +void frame_adjust_icon(ObFrame *self) +{ + render_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->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->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; + ConfigValue layout; + + n = d = i = l = m = c = FALSE; + + if (!config_get("titlebar.layout", Config_String, &layout)) { + layout.string = "NDLIMC"; + config_set("titlebar.layout", Config_String, layout); + } + + /* figure out whats being shown, and the width of the label */ + self->label_width = self->width - (s_bevel + 1) * 2; + for (lc = layout.string; *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 + 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 + 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 + 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 + 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 + 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 (!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 = s_bevel + 1; + for (lc = layout.string; *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, s_bevel + 1); + x += BUTTON_SIZE + s_bevel + 1; + break; + case 'D': + if (!d) break; + self->desk_x = x; + XMapWindow(ob_display, self->desk); + XMoveWindow(ob_display, self->desk, x, s_bevel + 1); + x += BUTTON_SIZE + s_bevel + 1; + break; + case 'I': + if (!i) break; + self->iconify_x = x; + XMapWindow(ob_display, self->iconify); + XMoveWindow(ob_display, self->iconify, x, s_bevel + 1); + x += BUTTON_SIZE + s_bevel + 1; + break; + case 'L': + if (!l) break; + self->label_x = x; + XMapWindow(ob_display, self->label); + XMoveWindow(ob_display, self->label, x, s_bevel); + x += self->label_width + s_bevel + 1; + break; + case 'M': + if (!m) break; + self->max_x = x; + XMapWindow(ob_display, self->max); + XMoveWindow(ob_display, self->max, x, s_bevel + 1); + x += BUTTON_SIZE + s_bevel + 1; + break; + case 'C': + if (!c) break; + self->close_x = x; + XMapWindow(ob_display, self->close); + XMoveWindow(ob_display, self->close, x, s_bevel + 1); + x += BUTTON_SIZE + 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 frame_mouse_press(const ObEvent *e, ObFrame *self) +{ + Window win = e->data.x.e->xbutton.window; + if (win == self->max) { + self->max_press = TRUE; + render_frame(self); + } else if (win == self->close) { + self->close_press = TRUE; + render_frame(self); + } else if (win == self->iconify) { + self->iconify_press = TRUE; + render_frame(self); + } else if (win == self->desk) { + self->desk_press = TRUE; + render_frame(self); + } +} + +static void frame_mouse_release(const ObEvent *e, ObFrame *self) +{ + Window win = e->data.x.e->xbutton.window; + if (win == self->max) { + self->max_press = FALSE; + render_frame(self); + } else if (win == self->close) { + self->close_press = FALSE; + render_frame(self); + } else if (win == self->iconify) { + self->iconify_press = FALSE; + render_frame(self); + } else if (win == self->desk) { + self->desk_press = FALSE; + render_frame(self); + } +} diff --git a/engines/openbox/obengine.h b/engines/openbox/obengine.h new file mode 100644 index 00000000..839b8b8a --- /dev/null +++ b/engines/openbox/obengine.h @@ -0,0 +1,109 @@ +#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 (s_winfont_height + 2) +#define TITLE_HEIGHT (LABEL_HEIGHT + 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 s_bevel; +extern int s_handle_height; +extern int s_bwidth; +extern int s_cbwidth; + +extern color_rgb *s_b_color; +extern color_rgb *s_cb_focused_color; +extern color_rgb *s_cb_unfocused_color; +extern color_rgb *s_title_focused_color; +extern color_rgb *s_title_unfocused_color; +extern color_rgb *s_titlebut_focused_color; +extern color_rgb *s_titlebut_unfocused_color; + +extern int s_winfont_height; +extern int s_winfont_shadow; +extern int s_winfont_shadow_offset; +extern ObFont *s_winfont; + +extern pixmap_mask *s_max_mask; +extern pixmap_mask *s_icon_mask; +extern pixmap_mask *s_desk_mask; +extern pixmap_mask *s_close_mask; + +extern Appearance *a_focused_unpressed_max; +extern Appearance *a_focused_pressed_max; +extern Appearance *a_unfocused_unpressed_max; +extern Appearance *a_unfocused_pressed_max; +extern Appearance *a_focused_unpressed_close; +extern Appearance *a_focused_pressed_close; +extern Appearance *a_unfocused_unpressed_close; +extern Appearance *a_unfocused_pressed_close; +extern Appearance *a_focused_unpressed_desk; +extern Appearance *a_focused_pressed_desk; +extern Appearance *a_unfocused_unpressed_desk; +extern Appearance *a_unfocused_pressed_desk; +extern Appearance *a_focused_unpressed_iconify; +extern Appearance *a_focused_pressed_iconify; +extern Appearance *a_unfocused_unpressed_iconify; +extern Appearance *a_unfocused_pressed_iconify; +extern Appearance *a_focused_grip; +extern Appearance *a_unfocused_grip; +extern Appearance *a_focused_title; +extern Appearance *a_unfocused_title; +extern Appearance *a_focused_label; +extern Appearance *a_unfocused_label; +extern Appearance *a_icon; +extern Appearance *a_focused_handle; +extern Appearance *a_unfocused_handle; + +typedef struct ObFrame { + Frame frame; + + Window title; + Window label; + Window max; + Window close; + Window desk; + 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 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 iconify_press; +} ObFrame; + +#endif diff --git a/engines/openbox/obrender.c b/engines/openbox/obrender.c new file mode 100644 index 00000000..518c4669 --- /dev/null +++ b/engines/openbox/obrender.c @@ -0,0 +1,199 @@ +#include "obengine.h" +#include "../../kernel/openbox.h" +#include "../../kernel/screen.h" + +static void render_label(ObFrame *self, Appearance *a); +static void render_max(ObFrame *self, Appearance *a); +static void render_icon(ObFrame *self, Appearance *a); +static void render_iconify(ObFrame *self, Appearance *a); +static void render_desk(ObFrame *self, Appearance *a); +static void render_close(ObFrame *self, Appearance *a); + +void render_frame(ObFrame *self) +{ + if (client_focused(self->frame.client)) { + XSetWindowBorder(ob_display, self->frame.plate, + s_cb_focused_color->pixel); + } else { + XSetWindowBorder(ob_display, self->frame.plate, + s_cb_unfocused_color->pixel); + } + + if (self->frame.client->decorations & Decor_Titlebar) { + Appearance *t, *l, *m, *n, *i, *d, *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->max_press || + self->frame.client->max_vert || self->frame.client->max_horz) ? + a_focused_pressed_max : a_focused_unpressed_max) : + ((self->max_press || + self->frame.client->max_vert || self->frame.client->max_horz) ? + a_unfocused_pressed_max : a_unfocused_unpressed_max)); + n = self->a_icon; + i = (client_focused(self->frame.client) ? + (self->iconify_press ? + a_focused_pressed_iconify : a_focused_unpressed_iconify) : + (self->iconify_press ? + a_unfocused_pressed_iconify : a_unfocused_unpressed_iconify)); + d = (client_focused(self->frame.client) ? + (self->desk_press || self->frame.client->desktop == DESKTOP_ALL ? + a_focused_pressed_desk : a_focused_unpressed_desk) : + (self->desk_press || self->frame.client->desktop == DESKTOP_ALL ? + a_unfocused_pressed_desk : a_unfocused_unpressed_desk)); + c = (client_focused(self->frame.client) ? + (self->close_press ? + a_focused_pressed_close : a_focused_unpressed_close) : + (self->close_press ? + a_unfocused_pressed_close : 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 = s_bevel; + + m->surface.data.planar.parent = t; + m->surface.data.planar.parentx = self->max_x; + m->surface.data.planar.parenty = s_bevel + 1; + + n->surface.data.planar.parent = t; + n->surface.data.planar.parentx = self->icon_x; + n->surface.data.planar.parenty = s_bevel + 1; + + i->surface.data.planar.parent = t; + i->surface.data.planar.parentx = self->iconify_x; + i->surface.data.planar.parenty = s_bevel + 1; + + d->surface.data.planar.parent = t; + d->surface.data.planar.parentx = self->desk_x; + d->surface.data.planar.parenty = s_bevel + 1; + + c->surface.data.planar.parent = t; + c->surface.data.planar.parentx = self->close_x; + c->surface.data.planar.parenty = s_bevel + 1; + + render_label(self, l); + render_max(self, m); + render_icon(self, n); + render_iconify(self, i); + render_desk(self, d); + render_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) ? + a_focused_grip : 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 render_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 render_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 render_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 render_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 render_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 render_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); +} + +GQuark get_context(Client *client, Window win) +{ + ObFrame *self; + + if (win == ob_root) return g_quark_try_string("root"); + if (client == NULL) return g_quark_try_string("none"); + if (win == client->window) return g_quark_try_string("client"); + + self = (ObFrame*) client->frame; + if (win == self->frame.window) return g_quark_try_string("frame"); + if (win == self->frame.plate) return g_quark_try_string("client"); + if (win == self->title) return g_quark_try_string("titlebar"); + if (win == self->label) return g_quark_try_string("titlebar"); + if (win == self->handle) return g_quark_try_string("handle"); + if (win == self->lgrip) return g_quark_try_string("blcorner"); + if (win == self->rgrip) return g_quark_try_string("brcorner"); + if (win == self->max) return g_quark_try_string("maximize"); + if (win == self->iconify) return g_quark_try_string("iconify"); + if (win == self->close) return g_quark_try_string("close"); + if (win == self->icon) return g_quark_try_string("icon"); + if (win == self->desk) return g_quark_try_string("alldesktops"); + + return g_quark_try_string("none"); +} diff --git a/engines/openbox/obrender.h b/engines/openbox/obrender.h new file mode 100644 index 00000000..fd7cc4d7 --- /dev/null +++ b/engines/openbox/obrender.h @@ -0,0 +1,8 @@ +#ifndef __engines_openbox_render_h +#define __engines_openbox_render_h + +#include "obengine.h" + +void render_frame(ObFrame *self); + +#endif diff --git a/engines/openbox/obtheme.c b/engines/openbox/obtheme.c new file mode 100644 index 00000000..fcdc2cdd --- /dev/null +++ b/engines/openbox/obtheme.c @@ -0,0 +1,514 @@ +#include "obengine.h" +#include "../../kernel/config.h" +#include "../../kernel/openbox.h" + +#include +#include +#include +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#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; +} + +gboolean read_bool(XrmDatabase db, char *rname, gboolean *value) +{ + gboolean ret = FALSE; + char *rclass = create_class_name(rname); + char *rettype; + XrmValue retvalue; + + if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && + retvalue.addr != NULL) { + if (!g_ascii_strcasecmp(retvalue.addr, "true")) + *value = TRUE; + else + *value = FALSE; + ret = TRUE; + } + + g_free(rclass); + return ret; +} + +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; +} + +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; +} + +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; +} + +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; + ConfigValue theme; + + if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && + retvalue.addr != NULL) { + if (!config_get("theme", Config_String, &theme)) + g_assert_not_reached(); /* where's the default!? its not set? */ + + button_dir = g_strdup_printf("%s_buttons", theme.string); + + 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(theme.string); + s = g_strdup_printf("%s_buttons/%s", theme.string, + themename); + g_free(themename); + if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == + BitmapSuccess) + ret = TRUE; + else + g_message("Unable to find bitmap '%s'", s); + } + } + + 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; + } +} + + +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; +} + +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 load() +{ + XrmDatabase db = NULL; + Justify winjust; + char *winjuststr; + ConfigValue theme, shadow, offset, font; + + if (config_get("theme", Config_String, &theme)) { + db = loaddb(theme.string); + if (db == NULL) { + g_warning("Failed to load the theme '%s'", theme.string); + 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; + } + /* change to reflect what was actually loaded */ + theme.string = DEFAULT_THEME; + config_set("theme", Config_String, theme); + } + + /* load the font, not from the theme file tho, its in the config */ + + if (!config_get("font.shadow", Config_Bool, &shadow)) { + shadow.bool = TRUE; /* default */ + config_set("font.shadow", Config_Bool, shadow); + } + s_winfont_shadow = shadow.bool; + if (!config_get("font.shadow.offset", Config_Integer, &offset) || + offset.integer < 0 || offset.integer >= 10) { + offset.integer = 1; /* default */ + config_set("font.shadow.offset", Config_Integer, offset); + } + s_winfont_shadow_offset = offset.integer; + if (!config_get("font", Config_String, &font)) { + font.string = DEFAULT_FONT; + config_set("font", Config_String, font); + } + s_winfont = font_open(font.string); + s_winfont_height = font_height(s_winfont, s_winfont_shadow, + s_winfont_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", &s_handle_height) || + s_handle_height < 0 || s_handle_height > 100) s_handle_height = 6; + if (!read_int(db, "bevelWidth", &s_bevel) || + s_bevel <= 0 || s_bevel > 100) s_bevel = 3; + if (!read_int(db, "borderWidth", &s_bwidth) || + s_bwidth < 0 || s_bwidth > 100) s_bwidth = 1; + if (!read_int(db, "frameWidth", &s_cbwidth) || + s_cbwidth < 0 || s_cbwidth > 100) s_cbwidth = s_bevel; + + if (!read_color(db, "borderColor", &s_b_color)) + s_b_color = color_new(0, 0, 0); + if (!read_color(db, "window.frame.focusColor", &s_cb_focused_color)) + s_cb_focused_color = color_new(0xff, 0xff, 0xff); + if (!read_color(db, "window.frame.unfocusColor", &s_cb_unfocused_color)) + s_cb_unfocused_color = color_new(0xff, 0xff, 0xff); + if (!read_color(db, "window.label.focus.textColor", + &s_title_focused_color)) + s_title_focused_color = color_new(0xff, 0xff, 0xff); + if (!read_color(db, "window.label.unfocus.textColor", + &s_title_unfocused_color)) + s_title_unfocused_color = color_new(0xff, 0xff, 0xff); + if (!read_color(db, "window.button.focus.picColor", + &s_titlebut_focused_color)) + s_titlebut_focused_color = color_new(0, 0, 0); + if (!read_color(db, "window.button.unfocus.picColor", + &s_titlebut_unfocused_color)) + s_titlebut_unfocused_color = color_new(0xff, 0xff, 0xff); + + if (!read_mask(db, "window.button.max.mask", &s_max_mask)) { + char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f }; + s_max_mask = pixmap_mask_new(7, 7, data); + } + if (!read_mask(db, "window.button.icon.mask", &s_icon_mask)) { + char data[] = { 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e }; + s_icon_mask = pixmap_mask_new(7, 7, data); + } + if (!read_mask(db, "window.button.stick.mask", &s_desk_mask)) { + char data[] = { 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x00 }; + s_desk_mask = pixmap_mask_new(7, 7, data); + } + if (!read_mask(db, "window.button.close.mask", &s_close_mask)) { + char data[] = { 0x22, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x22 }; + s_close_mask = pixmap_mask_new(7, 7, data); + } + + if (!read_appearance(db, "window.title.focus", a_focused_title)) + set_default_appearance(a_focused_title); + if (!read_appearance(db, "window.title.unfocus", a_unfocused_title)) + set_default_appearance(a_unfocused_title); + if (!read_appearance(db, "window.label.focus", a_focused_label)) + set_default_appearance(a_focused_label); + if (!read_appearance(db, "window.label.unfocus", a_unfocused_label)) + set_default_appearance(a_unfocused_label); + if (!read_appearance(db, "window.handle.focus", a_focused_handle)) + set_default_appearance(a_focused_handle); + if (!read_appearance(db, "window.handle.unfocus", a_unfocused_handle)) + set_default_appearance(a_unfocused_handle); + if (!read_appearance(db, "window.grip.focus", a_focused_grip)) + set_default_appearance(a_focused_grip); + if (!read_appearance(db, "window.grip.unfocus", a_unfocused_grip)) + set_default_appearance(a_unfocused_grip); + + if (!read_appearance(db, "window.button.pressed.focus", + a_focused_pressed_max)) + if (!read_appearance(db, "window.button.pressed", + a_focused_pressed_max)) + set_default_appearance(a_focused_pressed_max); + if (!read_appearance(db, "window.button.pressed.unfocus", + a_unfocused_pressed_max)) + if (!read_appearance(db, "window.button.pressed", + a_unfocused_pressed_max)) + set_default_appearance(a_unfocused_pressed_max); + if (!read_appearance(db, "window.button.focus", + a_focused_unpressed_max)) + set_default_appearance(a_focused_unpressed_max); + if (!read_appearance(db, "window.button.unfocus", + a_unfocused_unpressed_max)) + set_default_appearance(a_unfocused_unpressed_max); + + a_unfocused_unpressed_close = appearance_copy(a_unfocused_unpressed_max); + a_unfocused_pressed_close = appearance_copy(a_unfocused_pressed_max); + a_focused_unpressed_close = appearance_copy(a_focused_unpressed_max); + a_focused_pressed_close = appearance_copy(a_focused_pressed_max); + a_unfocused_unpressed_desk = appearance_copy(a_unfocused_unpressed_max); + a_unfocused_pressed_desk = appearance_copy(a_unfocused_pressed_max); + a_focused_unpressed_desk = appearance_copy(a_focused_unpressed_max); + a_focused_pressed_desk = appearance_copy(a_focused_pressed_max); + a_unfocused_unpressed_iconify = appearance_copy(a_unfocused_unpressed_max); + a_unfocused_pressed_iconify = appearance_copy(a_unfocused_pressed_max); + a_focused_unpressed_iconify = appearance_copy(a_focused_unpressed_max); + a_focused_pressed_iconify = appearance_copy(a_focused_pressed_max); + + a_icon->surface.data.planar.grad = Background_ParentRelative; + + /* set up the textures */ + a_focused_label->texture[0].type = Text; + a_focused_label->texture[0].data.text.justify = winjust; + a_focused_label->texture[0].data.text.font = s_winfont; + a_focused_label->texture[0].data.text.shadow = s_winfont_shadow; + a_focused_label->texture[0].data.text.offset = s_winfont_shadow_offset; + a_focused_label->texture[0].data.text.color = s_title_focused_color; + + a_unfocused_label->texture[0].type = Text; + a_unfocused_label->texture[0].data.text.justify = winjust; + a_unfocused_label->texture[0].data.text.font = s_winfont; + a_unfocused_label->texture[0].data.text.shadow = s_winfont_shadow; + a_unfocused_label->texture[0].data.text.offset = s_winfont_shadow_offset; + a_unfocused_label->texture[0].data.text.color = s_title_unfocused_color; + + a_focused_unpressed_max->texture[0].type = + a_focused_pressed_max->texture[0].type = + a_unfocused_unpressed_max->texture[0].type = + a_unfocused_pressed_max->texture[0].type = + a_focused_unpressed_close->texture[0].type = + a_focused_pressed_close->texture[0].type = + a_unfocused_unpressed_close->texture[0].type = + a_unfocused_pressed_close->texture[0].type = + a_focused_unpressed_desk->texture[0].type = + a_focused_pressed_desk->texture[0].type = + a_unfocused_unpressed_desk->texture[0].type = + a_unfocused_pressed_desk->texture[0].type = + a_focused_unpressed_iconify->texture[0].type = + a_focused_pressed_iconify->texture[0].type = + a_unfocused_unpressed_iconify->texture[0].type = + a_unfocused_pressed_iconify->texture[0].type = Bitmask; + a_focused_unpressed_max->texture[0].data.mask.mask = + a_focused_pressed_max->texture[0].data.mask.mask = + a_unfocused_unpressed_max->texture[0].data.mask.mask = + a_unfocused_pressed_max->texture[0].data.mask.mask = s_max_mask; + a_focused_unpressed_close->texture[0].data.mask.mask = + a_focused_pressed_close->texture[0].data.mask.mask = + a_unfocused_unpressed_close->texture[0].data.mask.mask = + a_unfocused_pressed_close->texture[0].data.mask.mask = s_close_mask; + a_focused_unpressed_desk->texture[0].data.mask.mask = + a_focused_pressed_desk->texture[0].data.mask.mask = + a_unfocused_unpressed_desk->texture[0].data.mask.mask = + a_unfocused_pressed_desk->texture[0].data.mask.mask = s_desk_mask; + a_focused_unpressed_iconify->texture[0].data.mask.mask = + a_focused_pressed_iconify->texture[0].data.mask.mask = + a_unfocused_unpressed_iconify->texture[0].data.mask.mask = + a_unfocused_pressed_iconify->texture[0].data.mask.mask = s_icon_mask; + a_focused_unpressed_max->texture[0].data.mask.color = + a_focused_pressed_max->texture[0].data.mask.color = + a_focused_unpressed_close->texture[0].data.mask.color = + a_focused_pressed_close->texture[0].data.mask.color = + a_focused_unpressed_desk->texture[0].data.mask.color = + a_focused_pressed_desk->texture[0].data.mask.color = + a_focused_unpressed_iconify->texture[0].data.mask.color = + a_focused_pressed_iconify->texture[0].data.mask.color = + s_titlebut_focused_color; + a_unfocused_unpressed_max->texture[0].data.mask.color = + a_unfocused_pressed_max->texture[0].data.mask.color = + a_unfocused_unpressed_close->texture[0].data.mask.color = + a_unfocused_pressed_close->texture[0].data.mask.color = + a_unfocused_unpressed_desk->texture[0].data.mask.color = + a_unfocused_pressed_desk->texture[0].data.mask.color = + a_unfocused_unpressed_iconify->texture[0].data.mask.color = + a_unfocused_pressed_iconify->texture[0].data.mask.color = + s_titlebut_unfocused_color; + + XrmDestroyDatabase(db); + return TRUE; +} + + diff --git a/engines/openbox/obtheme.h b/engines/openbox/obtheme.h new file mode 100644 index 00000000..1b6011fe --- /dev/null +++ b/engines/openbox/obtheme.h @@ -0,0 +1,8 @@ +#ifndef __engine_theme_h +#define __engine_theme_h + +#include + +gboolean load(); + +#endif diff --git a/engines/openbox/openbox.c b/engines/openbox/openbox.c deleted file mode 100644 index 938a74fb..00000000 --- a/engines/openbox/openbox.c +++ /dev/null @@ -1,1030 +0,0 @@ -#include "theme.h" -#include "../../kernel/openbox.h" -#include "../../kernel/screen.h" -#include "../../kernel/extensions.h" -#include "../../kernel/dispatch.h" -#include "../../kernel/config.h" -#include "../../kernel/frame.h" -#include "../../render/render.h" -#include "../../render/color.h" -#include "../../render/font.h" -#include "../../render/mask.h" - -#include -#include - -#define LABEL_HEIGHT (s_winfont_height + 2) -#define TITLE_HEIGHT (LABEL_HEIGHT + 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) - -#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask) -#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask) -#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \ - ButtonMotionMask | ExposureMask) - -/* style settings - geometry */ -int s_bevel; -int s_handle_height; -int s_bwidth; -int s_cbwidth; -/* style settings - colors */ -color_rgb *s_b_color; -color_rgb *s_cb_focused_color; -color_rgb *s_cb_unfocused_color; -color_rgb *s_title_focused_color; -color_rgb *s_title_unfocused_color; -color_rgb *s_titlebut_focused_color; -color_rgb *s_titlebut_unfocused_color; -/* style settings - fonts */ -int s_winfont_height; -int s_winfont_shadow; -int s_winfont_shadow_offset; -ObFont *s_winfont; -/* style settings - masks */ -pixmap_mask *s_max_mask; -pixmap_mask *s_icon_mask; -pixmap_mask *s_desk_mask; -pixmap_mask *s_close_mask; - -/* global appearances */ -Appearance *a_focused_unpressed_max; -Appearance *a_focused_pressed_max; -Appearance *a_unfocused_unpressed_max; -Appearance *a_unfocused_pressed_max; -Appearance *a_focused_unpressed_close; -Appearance *a_focused_pressed_close; -Appearance *a_unfocused_unpressed_close; -Appearance *a_unfocused_pressed_close; -Appearance *a_focused_unpressed_desk; -Appearance *a_focused_pressed_desk; -Appearance *a_unfocused_unpressed_desk; -Appearance *a_unfocused_pressed_desk; -Appearance *a_focused_unpressed_iconify; -Appearance *a_focused_pressed_iconify; -Appearance *a_unfocused_unpressed_iconify; -Appearance *a_unfocused_pressed_iconify; -Appearance *a_focused_grip; -Appearance *a_unfocused_grip; -Appearance *a_focused_title; -Appearance *a_unfocused_title; -Appearance *a_focused_label; -Appearance *a_unfocused_label; -Appearance *a_icon; /* always parentrelative, so no focused/unfocused */ -Appearance *a_focused_handle; -Appearance *a_unfocused_handle; - -typedef struct ObFrame { - Frame frame; - - Window title; - Window label; - Window max; - Window close; - Window desk; - 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 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 iconify_press; -} ObFrame; - -static void layout_title(ObFrame *self); -static void render(ObFrame *self); -static void render_label(ObFrame *self, Appearance *a); -static void render_max(ObFrame *self, Appearance *a); -static void render_icon(ObFrame *self, Appearance *a); -static void render_iconify(ObFrame *self, Appearance *a); -static void render_desk(ObFrame *self, Appearance *a); -static void render_close(ObFrame *self, Appearance *a); - -static void frame_mouse_press(const ObEvent *e, ObFrame *self); -static void frame_mouse_release(const ObEvent *e, ObFrame *self); - -gboolean startup() -{ - g_quark_from_string("none"); - g_quark_from_string("root"); - g_quark_from_string("client"); - g_quark_from_string("titlebar"); - g_quark_from_string("handle"); - g_quark_from_string("frame"); - g_quark_from_string("blcorner"); - g_quark_from_string("brcorner"); - g_quark_from_string("maximize"); - g_quark_from_string("alldesktops"); - g_quark_from_string("iconify"); - g_quark_from_string("icon"); - g_quark_from_string("close"); - - s_b_color = s_cb_unfocused_color = s_cb_focused_color = - s_title_unfocused_color = s_title_focused_color = - s_titlebut_unfocused_color = s_titlebut_focused_color = NULL; - s_winfont = NULL; - s_max_mask = s_icon_mask = s_desk_mask = s_close_mask = NULL; - - a_focused_unpressed_max = appearance_new(Surface_Planar, 1); - a_focused_pressed_max = appearance_new(Surface_Planar, 1); - a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1); - a_unfocused_pressed_max = appearance_new(Surface_Planar, 1); - a_focused_unpressed_close = NULL; - a_focused_pressed_close = NULL; - a_unfocused_unpressed_close = NULL; - a_unfocused_pressed_close = NULL; - a_focused_unpressed_desk = NULL; - a_focused_pressed_desk = NULL; - a_unfocused_unpressed_desk = NULL; - a_unfocused_pressed_desk = NULL; - a_focused_unpressed_iconify = NULL; - a_focused_pressed_iconify = NULL; - a_unfocused_unpressed_iconify = NULL; - a_unfocused_pressed_iconify = NULL; - a_focused_grip = appearance_new(Surface_Planar, 0); - a_unfocused_grip = appearance_new(Surface_Planar, 0); - a_focused_title = appearance_new(Surface_Planar, 0); - a_unfocused_title = appearance_new(Surface_Planar, 0); - a_focused_label = appearance_new(Surface_Planar, 1); - a_unfocused_label = appearance_new(Surface_Planar, 1); - a_icon = appearance_new(Surface_Planar, 1); - a_focused_handle = appearance_new(Surface_Planar, 0); - a_unfocused_handle = appearance_new(Surface_Planar, 0); - - if (load()) { - RECT_SET(a_focused_pressed_desk->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_unpressed_desk->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_pressed_desk->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_unpressed_desk->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_pressed_iconify->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_unpressed_iconify->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_pressed_iconify->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_unpressed_iconify->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_unpressed_iconify->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_pressed_max->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_unpressed_max->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_pressed_max->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_unpressed_max->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_pressed_close->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_focused_unpressed_close->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_pressed_close->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - RECT_SET(a_unfocused_unpressed_close->area, 0, 0, - BUTTON_SIZE, BUTTON_SIZE); - - RECT_SET(a_focused_grip->area, 0, 0, GRIP_WIDTH, s_handle_height); - RECT_SET(a_unfocused_grip->area, 0, 0, GRIP_WIDTH, s_handle_height); - return TRUE; - } else - return FALSE; -} - -void shutdown() -{ - if (s_b_color != NULL) color_free(s_b_color); - if (s_cb_unfocused_color != NULL) color_free(s_cb_unfocused_color); - if (s_cb_focused_color != NULL) color_free(s_cb_focused_color); - if (s_title_unfocused_color != NULL) color_free(s_title_unfocused_color); - if (s_title_focused_color != NULL) color_free(s_title_focused_color); - if (s_titlebut_unfocused_color != NULL) - color_free(s_titlebut_unfocused_color); - if (s_titlebut_focused_color != NULL) - color_free(s_titlebut_focused_color); - - if (s_max_mask != NULL) pixmap_mask_free(s_max_mask); - if (s_desk_mask != NULL) pixmap_mask_free(s_desk_mask); - if (s_icon_mask != NULL) pixmap_mask_free(s_icon_mask); - if (s_close_mask != NULL) pixmap_mask_free(s_close_mask); - - if (s_winfont != NULL) font_close(s_winfont); - - appearance_free(a_focused_unpressed_max); - appearance_free(a_focused_pressed_max); - appearance_free(a_unfocused_unpressed_max); - appearance_free(a_unfocused_pressed_max); - if (a_focused_unpressed_close != NULL) - appearance_free(a_focused_unpressed_close); - if (a_focused_pressed_close != NULL) - appearance_free(a_focused_pressed_close); - if (a_unfocused_unpressed_close != NULL) - appearance_free(a_unfocused_unpressed_close); - if (a_unfocused_pressed_close != NULL) - appearance_free(a_unfocused_pressed_close); - if (a_focused_unpressed_desk != NULL) - appearance_free(a_focused_unpressed_desk); - if (a_focused_pressed_desk != NULL) - appearance_free(a_focused_pressed_desk); - if (a_unfocused_unpressed_desk != NULL) - appearance_free(a_unfocused_unpressed_desk); - if (a_unfocused_pressed_desk != NULL) - appearance_free(a_unfocused_pressed_desk); - if (a_focused_unpressed_iconify != NULL) - appearance_free(a_focused_unpressed_iconify); - if (a_focused_pressed_iconify != NULL) - appearance_free(a_focused_pressed_iconify); - if (a_unfocused_unpressed_iconify != NULL) - appearance_free(a_unfocused_unpressed_iconify); - if (a_unfocused_pressed_iconify != NULL) - appearance_free(a_unfocused_pressed_iconify); - appearance_free(a_focused_grip); - appearance_free(a_unfocused_grip); - appearance_free(a_focused_title); - appearance_free(a_unfocused_title); - appearance_free(a_focused_label); - appearance_free(a_unfocused_label); - appearance_free(a_icon); - appearance_free(a_focused_handle); - appearance_free(a_unfocused_handle); -} - -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->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, s_b_color->pixel); - XSetWindowBorder(ob_display, self->label, s_b_color->pixel); - XSetWindowBorder(ob_display, self->rgrip, s_b_color->pixel); - XSetWindowBorder(ob_display, self->lgrip, 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->lgrip, GRIP_WIDTH, s_handle_height); - XResizeWindow(ob_display, self->rgrip, GRIP_WIDTH, s_handle_height); - - /* set up the dynamic appearances */ - self->a_unfocused_title = appearance_copy(a_unfocused_title); - self->a_focused_title = appearance_copy(a_focused_title); - self->a_unfocused_label = appearance_copy(a_unfocused_label); - self->a_focused_label = appearance_copy(a_focused_label); - self->a_unfocused_handle = appearance_copy(a_unfocused_handle); - self->a_focused_handle = appearance_copy(a_focused_handle); - self->a_icon = appearance_copy(a_icon); - - self->max_press = self->close_press = self->desk_press = - self->iconify_press = FALSE; - - dispatch_register(Event_X_ButtonPress, (EventHandler)frame_mouse_press, - self); - dispatch_register(Event_X_ButtonRelease, (EventHandler)frame_mouse_release, - 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)frame_mouse_press, self); - dispatch_register(0, (EventHandler)frame_mouse_release, 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 = -s_bevel; - xrect[0].y = -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 = -s_bevel; - xrect[1].y = HANDLE_Y(self); - xrect[1].width = self->width + self->bwidth * 2; - xrect[1].height = 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 = s_bwidth; - self->cbwidth = 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->icon_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); - /* make all the titlebar stuff not render */ - self->frame.client->decorations &= ~(Decor_Icon | Decor_Iconify | - Decor_Maximize | Decor_Close | - Decor_AllDesktops); - } - - if (self->frame.client->decorations & Decor_Handle) { - XMoveResizeWindow(ob_display, self->handle, - -self->bwidth, HANDLE_Y(self), - self->width, 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 += s_handle_height + - self->bwidth; - XMapWindow(ob_display, self->handle); - - if (self->a_focused_handle->surface.data.planar.grad == - Background_ParentRelative) - RECT_SET(self->a_focused_handle->area, 0, 0, - self->width, s_handle_height); - else - RECT_SET(self->a_focused_handle->area, - GRIP_WIDTH + self->bwidth, 0, - self->width - (GRIP_WIDTH + self->bwidth) * 2, - s_handle_height); - if (self->a_unfocused_handle->surface.data.planar.grad == - Background_ParentRelative) - RECT_SET(self->a_unfocused_handle->area, 0, 0, - self->width, s_handle_height); - else - RECT_SET(self->a_unfocused_handle->area, - GRIP_WIDTH + self->bwidth, 0, - self->width - (GRIP_WIDTH + self->bwidth) * 2, - 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) { - render(self); - - frame_adjust_shape(self); - } -} - -void frame_adjust_state(ObFrame *self) -{ - render(self); -} - -void frame_adjust_focus(ObFrame *self) -{ - render(self); -} - -void frame_adjust_title(ObFrame *self) -{ - render(self); -} - -void frame_adjust_icon(ObFrame *self) -{ - render(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->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->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; - ConfigValue layout; - - n = d = i = l = m = c = FALSE; - - if (!config_get("titlebar.layout", Config_String, &layout)) { - layout.string = "NDLIMC"; - config_set("titlebar.layout", Config_String, layout); - } - - /* figure out whats being shown, and the width of the label */ - self->label_width = self->width - (s_bevel + 1) * 2; - for (lc = layout.string; *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 + 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 + 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 + 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 + 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 + 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 (!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 = s_bevel + 1; - for (lc = layout.string; *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, s_bevel + 1); - x += BUTTON_SIZE + s_bevel + 1; - break; - case 'D': - if (!d) break; - self->desk_x = x; - XMapWindow(ob_display, self->desk); - XMoveWindow(ob_display, self->desk, x, s_bevel + 1); - x += BUTTON_SIZE + s_bevel + 1; - break; - case 'I': - if (!i) break; - self->iconify_x = x; - XMapWindow(ob_display, self->iconify); - XMoveWindow(ob_display, self->iconify, x, s_bevel + 1); - x += BUTTON_SIZE + s_bevel + 1; - break; - case 'L': - if (!l) break; - self->label_x = x; - XMapWindow(ob_display, self->label); - XMoveWindow(ob_display, self->label, x, s_bevel); - x += self->label_width + s_bevel + 1; - break; - case 'M': - if (!m) break; - self->max_x = x; - XMapWindow(ob_display, self->max); - XMoveWindow(ob_display, self->max, x, s_bevel + 1); - x += BUTTON_SIZE + s_bevel + 1; - break; - case 'C': - if (!c) break; - self->close_x = x; - XMapWindow(ob_display, self->close); - XMoveWindow(ob_display, self->close, x, s_bevel + 1); - x += BUTTON_SIZE + 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 render(ObFrame *self) -{ - if (client_focused(self->frame.client)) { - XSetWindowBorder(ob_display, self->frame.plate, - s_cb_focused_color->pixel); - } else { - XSetWindowBorder(ob_display, self->frame.plate, - s_cb_unfocused_color->pixel); - } - - if (self->frame.client->decorations & Decor_Titlebar) { - Appearance *t, *l, *m, *n, *i, *d, *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->max_press || - self->frame.client->max_vert || self->frame.client->max_horz) ? - a_focused_pressed_max : a_focused_unpressed_max) : - ((self->max_press || - self->frame.client->max_vert || self->frame.client->max_horz) ? - a_unfocused_pressed_max : a_unfocused_unpressed_max)); - n = self->a_icon; - i = (client_focused(self->frame.client) ? - (self->iconify_press ? - a_focused_pressed_iconify : a_focused_unpressed_iconify) : - (self->iconify_press ? - a_unfocused_pressed_iconify : a_unfocused_unpressed_iconify)); - d = (client_focused(self->frame.client) ? - (self->desk_press || self->frame.client->desktop == DESKTOP_ALL ? - a_focused_pressed_desk : a_focused_unpressed_desk) : - (self->desk_press || self->frame.client->desktop == DESKTOP_ALL ? - a_unfocused_pressed_desk : a_unfocused_unpressed_desk)); - c = (client_focused(self->frame.client) ? - (self->close_press ? - a_focused_pressed_close : a_focused_unpressed_close) : - (self->close_press ? - a_unfocused_pressed_close : 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 = s_bevel; - - m->surface.data.planar.parent = t; - m->surface.data.planar.parentx = self->max_x; - m->surface.data.planar.parenty = s_bevel + 1; - - n->surface.data.planar.parent = t; - n->surface.data.planar.parentx = self->icon_x; - n->surface.data.planar.parenty = s_bevel + 1; - - i->surface.data.planar.parent = t; - i->surface.data.planar.parentx = self->iconify_x; - i->surface.data.planar.parenty = s_bevel + 1; - - d->surface.data.planar.parent = t; - d->surface.data.planar.parentx = self->desk_x; - d->surface.data.planar.parenty = s_bevel + 1; - - c->surface.data.planar.parent = t; - c->surface.data.planar.parentx = self->close_x; - c->surface.data.planar.parenty = s_bevel + 1; - - render_label(self, l); - render_max(self, m); - render_icon(self, n); - render_iconify(self, i); - render_desk(self, d); - render_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) ? - a_focused_grip : 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 render_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 render_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 render_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 render_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 render_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 render_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); -} - -GQuark get_context(Client *client, Window win) -{ - ObFrame *self; - - if (win == ob_root) return g_quark_try_string("root"); - if (client == NULL) return g_quark_try_string("none"); - if (win == client->window) return g_quark_try_string("client"); - - self = (ObFrame*) client->frame; - if (win == self->frame.window) return g_quark_try_string("frame"); - if (win == self->frame.plate) return g_quark_try_string("client"); - if (win == self->title) return g_quark_try_string("titlebar"); - if (win == self->label) return g_quark_try_string("titlebar"); - if (win == self->handle) return g_quark_try_string("handle"); - if (win == self->lgrip) return g_quark_try_string("blcorner"); - if (win == self->rgrip) return g_quark_try_string("brcorner"); - if (win == self->max) return g_quark_try_string("maximize"); - if (win == self->iconify) return g_quark_try_string("iconify"); - if (win == self->close) return g_quark_try_string("close"); - if (win == self->icon) return g_quark_try_string("icon"); - if (win == self->desk) return g_quark_try_string("alldesktops"); - - return g_quark_try_string("none"); -} - -static void frame_mouse_press(const ObEvent *e, ObFrame *self) -{ - Window win = e->data.x.e->xbutton.window; - if (win == self->max) { - self->max_press = TRUE; - render(self); - } else if (win == self->close) { - self->close_press = TRUE; - render(self); - } else if (win == self->iconify) { - self->iconify_press = TRUE; - render(self); - } else if (win == self->desk) { - self->desk_press = TRUE; - render(self); - } -} - -static void frame_mouse_release(const ObEvent *e, ObFrame *self) -{ - Window win = e->data.x.e->xbutton.window; - if (win == self->max) { - self->max_press = FALSE; - render(self); - } else if (win == self->close) { - self->close_press = FALSE; - render(self); - } else if (win == self->iconify) { - self->iconify_press = FALSE; - render(self); - } else if (win == self->desk) { - self->desk_press = FALSE; - render(self); - } -} diff --git a/engines/openbox/openbox.h b/engines/openbox/openbox.h deleted file mode 100644 index 5e9b9818..00000000 --- a/engines/openbox/openbox.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __engine_openbox_h -#define __engine_openbox_h - -#include "../../render/render.h" -#include "../../render/color.h" -#include "../../render/font.h" -#include "../../render/mask.h" - -extern int s_bevel; -extern int s_handle_height; -extern int s_bwidth; -extern int s_cbwidth; - -extern color_rgb *s_b_color; -extern color_rgb *s_cb_focused_color; -extern color_rgb *s_cb_unfocused_color; -extern color_rgb *s_title_focused_color; -extern color_rgb *s_title_unfocused_color; -extern color_rgb *s_titlebut_focused_color; -extern color_rgb *s_titlebut_unfocused_color; - -extern int s_winfont_height; -extern int s_winfont_shadow; -extern int s_winfont_shadow_offset; -extern ObFont *s_winfont; - -extern pixmap_mask *s_max_mask; -extern pixmap_mask *s_icon_mask; -extern pixmap_mask *s_desk_mask; -extern pixmap_mask *s_close_mask; - -extern Appearance *a_focused_unpressed_max; -extern Appearance *a_focused_pressed_max; -extern Appearance *a_unfocused_unpressed_max; -extern Appearance *a_unfocused_pressed_max; -extern Appearance *a_focused_unpressed_close; -extern Appearance *a_focused_pressed_close; -extern Appearance *a_unfocused_unpressed_close; -extern Appearance *a_unfocused_pressed_close; -extern Appearance *a_focused_unpressed_desk; -extern Appearance *a_focused_pressed_desk; -extern Appearance *a_unfocused_unpressed_desk; -extern Appearance *a_unfocused_pressed_desk; -extern Appearance *a_focused_unpressed_iconify; -extern Appearance *a_focused_pressed_iconify; -extern Appearance *a_unfocused_unpressed_iconify; -extern Appearance *a_unfocused_pressed_iconify; -extern Appearance *a_focused_grip; -extern Appearance *a_unfocused_grip; -extern Appearance *a_focused_title; -extern Appearance *a_unfocused_title; -extern Appearance *a_focused_label; -extern Appearance *a_unfocused_label; -extern Appearance *a_icon; -extern Appearance *a_focused_handle; -extern Appearance *a_unfocused_handle; - -#endif diff --git a/engines/openbox/theme.c b/engines/openbox/theme.c deleted file mode 100644 index c775ff9e..00000000 --- a/engines/openbox/theme.c +++ /dev/null @@ -1,514 +0,0 @@ -#include "openbox.h" -#include "../../kernel/config.h" -#include "../../kernel/openbox.h" - -#include -#include -#include -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_CTYPE_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#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; -} - -gboolean read_bool(XrmDatabase db, char *rname, gboolean *value) -{ - gboolean ret = FALSE; - char *rclass = create_class_name(rname); - char *rettype; - XrmValue retvalue; - - if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && - retvalue.addr != NULL) { - if (!g_ascii_strcasecmp(retvalue.addr, "true")) - *value = TRUE; - else - *value = FALSE; - ret = TRUE; - } - - g_free(rclass); - return ret; -} - -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; -} - -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; -} - -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; -} - -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; - ConfigValue theme; - - if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) && - retvalue.addr != NULL) { - if (!config_get("theme", Config_String, &theme)) - g_assert_not_reached(); /* where's the default!? its not set? */ - - button_dir = g_strdup_printf("%s_buttons", theme.string); - - 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(theme.string); - s = g_strdup_printf("%s_buttons/%s", theme.string, - themename); - g_free(themename); - if (XReadBitmapFileData(s, &w, &h, &b, &hx, &hy) == - BitmapSuccess) - ret = TRUE; - else - g_message("Unable to find bitmap '%s'", s); - } - } - - 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; - } -} - - -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; -} - -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 load() -{ - XrmDatabase db = NULL; - Justify winjust; - char *winjuststr; - ConfigValue theme, shadow, offset, font; - - if (config_get("theme", Config_String, &theme)) { - db = loaddb(theme.string); - if (db == NULL) { - g_warning("Failed to load the theme '%s'", theme.string); - 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; - } - /* change to reflect what was actually loaded */ - theme.string = DEFAULT_THEME; - config_set("theme", Config_String, theme); - } - - /* load the font, not from the theme file tho, its in the config */ - - if (!config_get("font.shadow", Config_Bool, &shadow)) { - shadow.bool = TRUE; /* default */ - config_set("font.shadow", Config_Bool, shadow); - } - s_winfont_shadow = shadow.bool; - if (!config_get("font.shadow.offset", Config_Integer, &offset) || - offset.integer < 0 || offset.integer >= 10) { - offset.integer = 1; /* default */ - config_set("font.shadow.offset", Config_Integer, offset); - } - s_winfont_shadow_offset = offset.integer; - if (!config_get("font", Config_String, &font)) { - font.string = DEFAULT_FONT; - config_set("font", Config_String, font); - } - s_winfont = font_open(font.string); - s_winfont_height = font_height(s_winfont, s_winfont_shadow, - s_winfont_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", &s_handle_height) || - s_handle_height < 0 || s_handle_height > 100) s_handle_height = 6; - if (!read_int(db, "bevelWidth", &s_bevel) || - s_bevel <= 0 || s_bevel > 100) s_bevel = 3; - if (!read_int(db, "borderWidth", &s_bwidth) || - s_bwidth < 0 || s_bwidth > 100) s_bwidth = 1; - if (!read_int(db, "frameWidth", &s_cbwidth) || - s_cbwidth < 0 || s_cbwidth > 100) s_cbwidth = s_bevel; - - if (!read_color(db, "borderColor", &s_b_color)) - s_b_color = color_new(0, 0, 0); - if (!read_color(db, "window.frame.focusColor", &s_cb_focused_color)) - s_cb_focused_color = color_new(0xff, 0xff, 0xff); - if (!read_color(db, "window.frame.unfocusColor", &s_cb_unfocused_color)) - s_cb_unfocused_color = color_new(0xff, 0xff, 0xff); - if (!read_color(db, "window.label.focus.textColor", - &s_title_focused_color)) - s_title_focused_color = color_new(0xff, 0xff, 0xff); - if (!read_color(db, "window.label.unfocus.textColor", - &s_title_unfocused_color)) - s_title_unfocused_color = color_new(0xff, 0xff, 0xff); - if (!read_color(db, "window.button.focus.picColor", - &s_titlebut_focused_color)) - s_titlebut_focused_color = color_new(0, 0, 0); - if (!read_color(db, "window.button.unfocus.picColor", - &s_titlebut_unfocused_color)) - s_titlebut_unfocused_color = color_new(0xff, 0xff, 0xff); - - if (!read_mask(db, "window.button.max.mask", &s_max_mask)) { - char data[] = { 0x7c, 0x44, 0x47, 0x47, 0x7f, 0x1f, 0x1f }; - s_max_mask = pixmap_mask_new(7, 7, data); - } - if (!read_mask(db, "window.button.icon.mask", &s_icon_mask)) { - char data[] = { 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e }; - s_icon_mask = pixmap_mask_new(7, 7, data); - } - if (!read_mask(db, "window.button.stick.mask", &s_desk_mask)) { - char data[] = { 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x00 }; - s_desk_mask = pixmap_mask_new(7, 7, data); - } - if (!read_mask(db, "window.button.close.mask", &s_close_mask)) { - char data[] = { 0x22, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x22 }; - s_close_mask = pixmap_mask_new(7, 7, data); - } - - if (!read_appearance(db, "window.title.focus", a_focused_title)) - set_default_appearance(a_focused_title); - if (!read_appearance(db, "window.title.unfocus", a_unfocused_title)) - set_default_appearance(a_unfocused_title); - if (!read_appearance(db, "window.label.focus", a_focused_label)) - set_default_appearance(a_focused_label); - if (!read_appearance(db, "window.label.unfocus", a_unfocused_label)) - set_default_appearance(a_unfocused_label); - if (!read_appearance(db, "window.handle.focus", a_focused_handle)) - set_default_appearance(a_focused_handle); - if (!read_appearance(db, "window.handle.unfocus", a_unfocused_handle)) - set_default_appearance(a_unfocused_handle); - if (!read_appearance(db, "window.grip.focus", a_focused_grip)) - set_default_appearance(a_focused_grip); - if (!read_appearance(db, "window.grip.unfocus", a_unfocused_grip)) - set_default_appearance(a_unfocused_grip); - - if (!read_appearance(db, "window.button.pressed.focus", - a_focused_pressed_max)) - if (!read_appearance(db, "window.button.pressed", - a_focused_pressed_max)) - set_default_appearance(a_focused_pressed_max); - if (!read_appearance(db, "window.button.pressed.unfocus", - a_unfocused_pressed_max)) - if (!read_appearance(db, "window.button.pressed", - a_unfocused_pressed_max)) - set_default_appearance(a_unfocused_pressed_max); - if (!read_appearance(db, "window.button.focus", - a_focused_unpressed_max)) - set_default_appearance(a_focused_unpressed_max); - if (!read_appearance(db, "window.button.unfocus", - a_unfocused_unpressed_max)) - set_default_appearance(a_unfocused_unpressed_max); - - a_unfocused_unpressed_close = appearance_copy(a_unfocused_unpressed_max); - a_unfocused_pressed_close = appearance_copy(a_unfocused_pressed_max); - a_focused_unpressed_close = appearance_copy(a_focused_unpressed_max); - a_focused_pressed_close = appearance_copy(a_focused_pressed_max); - a_unfocused_unpressed_desk = appearance_copy(a_unfocused_unpressed_max); - a_unfocused_pressed_desk = appearance_copy(a_unfocused_pressed_max); - a_focused_unpressed_desk = appearance_copy(a_focused_unpressed_max); - a_focused_pressed_desk = appearance_copy(a_focused_pressed_max); - a_unfocused_unpressed_iconify = appearance_copy(a_unfocused_unpressed_max); - a_unfocused_pressed_iconify = appearance_copy(a_unfocused_pressed_max); - a_focused_unpressed_iconify = appearance_copy(a_focused_unpressed_max); - a_focused_pressed_iconify = appearance_copy(a_focused_pressed_max); - - a_icon->surface.data.planar.grad = Background_ParentRelative; - - /* set up the textures */ - a_focused_label->texture[0].type = Text; - a_focused_label->texture[0].data.text.justify = winjust; - a_focused_label->texture[0].data.text.font = s_winfont; - a_focused_label->texture[0].data.text.shadow = s_winfont_shadow; - a_focused_label->texture[0].data.text.offset = s_winfont_shadow_offset; - a_focused_label->texture[0].data.text.color = s_title_focused_color; - - a_unfocused_label->texture[0].type = Text; - a_unfocused_label->texture[0].data.text.justify = winjust; - a_unfocused_label->texture[0].data.text.font = s_winfont; - a_unfocused_label->texture[0].data.text.shadow = s_winfont_shadow; - a_unfocused_label->texture[0].data.text.offset = s_winfont_shadow_offset; - a_unfocused_label->texture[0].data.text.color = s_title_unfocused_color; - - a_focused_unpressed_max->texture[0].type = - a_focused_pressed_max->texture[0].type = - a_unfocused_unpressed_max->texture[0].type = - a_unfocused_pressed_max->texture[0].type = - a_focused_unpressed_close->texture[0].type = - a_focused_pressed_close->texture[0].type = - a_unfocused_unpressed_close->texture[0].type = - a_unfocused_pressed_close->texture[0].type = - a_focused_unpressed_desk->texture[0].type = - a_focused_pressed_desk->texture[0].type = - a_unfocused_unpressed_desk->texture[0].type = - a_unfocused_pressed_desk->texture[0].type = - a_focused_unpressed_iconify->texture[0].type = - a_focused_pressed_iconify->texture[0].type = - a_unfocused_unpressed_iconify->texture[0].type = - a_unfocused_pressed_iconify->texture[0].type = Bitmask; - a_focused_unpressed_max->texture[0].data.mask.mask = - a_focused_pressed_max->texture[0].data.mask.mask = - a_unfocused_unpressed_max->texture[0].data.mask.mask = - a_unfocused_pressed_max->texture[0].data.mask.mask = s_max_mask; - a_focused_unpressed_close->texture[0].data.mask.mask = - a_focused_pressed_close->texture[0].data.mask.mask = - a_unfocused_unpressed_close->texture[0].data.mask.mask = - a_unfocused_pressed_close->texture[0].data.mask.mask = s_close_mask; - a_focused_unpressed_desk->texture[0].data.mask.mask = - a_focused_pressed_desk->texture[0].data.mask.mask = - a_unfocused_unpressed_desk->texture[0].data.mask.mask = - a_unfocused_pressed_desk->texture[0].data.mask.mask = s_desk_mask; - a_focused_unpressed_iconify->texture[0].data.mask.mask = - a_focused_pressed_iconify->texture[0].data.mask.mask = - a_unfocused_unpressed_iconify->texture[0].data.mask.mask = - a_unfocused_pressed_iconify->texture[0].data.mask.mask = s_icon_mask; - a_focused_unpressed_max->texture[0].data.mask.color = - a_focused_pressed_max->texture[0].data.mask.color = - a_focused_unpressed_close->texture[0].data.mask.color = - a_focused_pressed_close->texture[0].data.mask.color = - a_focused_unpressed_desk->texture[0].data.mask.color = - a_focused_pressed_desk->texture[0].data.mask.color = - a_focused_unpressed_iconify->texture[0].data.mask.color = - a_focused_pressed_iconify->texture[0].data.mask.color = - s_titlebut_focused_color; - a_unfocused_unpressed_max->texture[0].data.mask.color = - a_unfocused_pressed_max->texture[0].data.mask.color = - a_unfocused_unpressed_close->texture[0].data.mask.color = - a_unfocused_pressed_close->texture[0].data.mask.color = - a_unfocused_unpressed_desk->texture[0].data.mask.color = - a_unfocused_pressed_desk->texture[0].data.mask.color = - a_unfocused_unpressed_iconify->texture[0].data.mask.color = - a_unfocused_pressed_iconify->texture[0].data.mask.color = - s_titlebut_unfocused_color; - - XrmDestroyDatabase(db); - return TRUE; -} - - diff --git a/engines/openbox/theme.h b/engines/openbox/theme.h deleted file mode 100644 index 1b6011fe..00000000 --- a/engines/openbox/theme.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __engine_theme_h -#define __engine_theme_h - -#include - -gboolean load(); - -#endif -- cgit v1.2.3