diff options
28 files changed, 2908 insertions, 128 deletions
@@ -1,3 +1,43 @@ +2007-11-01 Tomas Frydrych <tf@o-hand.com> + + * configure.ac: + * src/Makefile.am: + * src/core/Makefile.am: + * src/managers/maemo/Makefile.am: + * src/managers/simple/Makefile.am: + * src/comp-mgr/mb-wm-comp-mgr.c: + * src/comp-mgr/mb-wm-comp-mgr.h: + * src/core/mb-wm-types.h: + * src/core/mb-wm-client.c: + * src/core/mb-wm-client.h: + * src/core/mb-wm-main-context.c: + * src/core/mb-wm-object-props.h: + * src/core/mb-window-manager.c: + * src/core/mb-window-manager.h: + * src/core/mb-wm-atoms.c: + * src/core/mb-wm-client-base.c: + + Added composite manager. + + * src/theme-engines/mb-wm-theme-cairo.c: + * src/theme-engines/mb-wm-theme-simple.c: + * src/theme-engines/mb-wm-theme-xml.c: + * src/theme-engines/mb-wm-theme-xml.h: + * src/theme-engines/mb-wm-theme.c: + * src/theme-engines/mb-wm-theme.h: + * data/themes/Default/theme.xml: + + Added clr-shadow and clr-lowlight properties to theme. + + * src/core/mb-wm-client-window.c: + * src/core/mb-wm-client-window.h: + + Handling of initial _NET_WM_STATE property. + + * src/core/mb-wm-root-window.c: + + Handling of _MB_COMMAND ClientMessage. + 2007-10-29 Tomas Frydrych <tf@o-hand.com> * src/core/mb-wm-client-base.c: diff --git a/configure.ac b/configure.ac index 7ce3ee5..a641ef6 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,10 @@ AC_ARG_ENABLE(debug, [ --enable-debug Enable verbose debugging output], [want_debug=$enableval], [want_debug=no]) +AC_ARG_ENABLE(compositing-manager, + [ --enable-compositing-manager Enable compositing manager], + [comp_mgr=$enableval], [comp_mgr=no]) + if test "x$use_cairo" = "xyes"; then needed_pkgs="$needed_pkgs pangocairo " else @@ -42,6 +46,10 @@ if test "x$use_gtk" = "xyes"; then needed_pkgs="$needed_pkgs gtk+-2.0 " fi +if test "x$comp_mgr" = "xyes"; then + needed_pkgs="$needed_pkgs xcomposite xdamage " +fi + if test "x$want_debug" = "xyes"; then MBWM_DEBUG_CFLAGS="-O0 $MBWM_DEBUG_CFLAGS -DMBWM_WANT_DEBUG" MBWM_DEBUG_LDFLAGS="$MBWM_DEBUG_LDFLAGS -rdynamic" @@ -68,6 +76,11 @@ if test "$use_gtk" = yes; then AC_DEFINE(USE_GTK, 1, [GTK Integration]) fi +AM_CONDITIONAL(ENABLE_COMPOSITE, [test "x$comp_mgr" = "xyes"]) +if test "$comp_mgr" = yes; then + AC_DEFINE(ENABLE_COMPOSITE, 1, [Enable composite manager code]) +fi + AC_ARG_ENABLE(simple-manager, [ --disable-simple-manager Do not build simple window manager], [simple_manager=$enableval], [simple_manager=yes]) @@ -98,10 +111,11 @@ if test x$have_xcursor = xyes; then AC_DEFINE(HAVE_XCURSOR, [1], [Use XCursor to sync pointer themes]) fi -MBWM_INCS='-I$(top_srcdir)/src/core -I$(top_srcdir)/src/client-types -I$(top_srcdir)/src/theme-engines' +MBWM_INCS='-I$(top_srcdir)/src/core -I$(top_srcdir)/src/client-types -I$(top_srcdir)/src/theme-engines -I$(top_srcdir)/src/comp-mgr' MBWM_CORE_LIB='$(top_builddir)/src/core/libmatchbox-window-manager-2-core.a' MBWM_CLIENT_LIBS='$(top_builddir)/src/client-types' MBWM_THEME_LIBS='$(top_builddir)/src/theme-engines' +MBWM_COMPMGR_LIBS='$(top_builddir)/src/comp-mgr' MBWM_CFLAGS="$MBWM_CFLAGS $MBWM_DEBUG_CFLAGS $THEME_PNG_CFLAGS $XFIXES_CFLAGS $XCURSOR_CFLAGS" MBWM_LIBS="$MBWM_LIBS $THEME_PNG_LIBS $XFIXES_LIBS $XCURSOR_LIBS" @@ -111,6 +125,7 @@ AC_SUBST([MBWM_CORE_LIB]) AC_SUBST([MBWM_INCS]) AC_SUBST([MBWM_CLIENT_LIBS]) AC_SUBST([MBWM_THEME_LIBS]) +AC_SUBST([MBWM_COMPMGR_LIBS]) AC_SUBST([MBWM_DEBUG_CFLAGS]) AC_SUBST([MBWM_DEBUG_LDFLAGS]) @@ -119,6 +134,7 @@ Makefile src/Makefile src/core/Makefile src/client-types/Makefile +src/comp-mgr/Makefile src/managers/Makefile src/managers/simple/Makefile src/managers/maemo/Makefile @@ -146,7 +162,10 @@ echo " GTK integration : ${use_gtk} Managers: - Simple manager : ${simple_manager} - Maemo manager : ${maemo_manager} + Simple manager : ${simple_manager} + Maemo manager : ${maemo_manager} + + Compositing manager : ${comp_mgr} + Debugging output : ${want_debug} " diff --git a/data/themes/Default/theme.xml b/data/themes/Default/theme.xml index e821cdf..f944db4 100644 --- a/data/themes/Default/theme.xml +++ b/data/themes/Default/theme.xml @@ -1,6 +1,7 @@ <?xml version="1.0"?> <theme name="Default" author="Tomas Frydrych, tf@o-hand.com" - desc="" version="1.0" engine_version="2" engine_type="default"> + desc="" version="1.0" engine_version="2" engine_type="default" + shadow-type="gaussian" > <img src="test.png" /> <client type="app"> <decor type="north" clr-bg="#ff0000" clr-bg2="#ffffff" clr-fg="#ffffff" diff --git a/src/Makefile.am b/src/Makefile.am index 152c4ce..a46ed99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,8 @@ -SUBDIRS = core client-types theme-engines managers +if ENABLE_COMPOSITE +comp=comp-mgr +endif -MAINTAINERCLEANFILES = config.h.in Makefile.in
\ No newline at end of file +SUBDIRS = core client-types theme-engines $(comp) managers + +MAINTAINERCLEANFILES = Makefile.in
\ No newline at end of file diff --git a/src/comp-mgr/Makefile.am b/src/comp-mgr/Makefile.am new file mode 100644 index 0000000..79a77a7 --- /dev/null +++ b/src/comp-mgr/Makefile.am @@ -0,0 +1,9 @@ +noinst_LIBRARIES = libmatchbox-window-manager-2-compmgr.a + +core_h = mb-wm-comp-mgr.h +core_c = mb-wm-comp-mgr.c + +libmatchbox_window_manager_2_compmgr_a_SOURCES = $(core_h) $(core_c) +libmatchbox_window_manager_2_compmgr_a_CFLAGS = @MBWM_INCS@ @MBWM_CFLAGS@ + +MAINTAINERCLEANFILES = Makefile.in
\ No newline at end of file diff --git a/src/comp-mgr/mb-wm-comp-mgr.c b/src/comp-mgr/mb-wm-comp-mgr.c new file mode 100644 index 0000000..13aa402 --- /dev/null +++ b/src/comp-mgr/mb-wm-comp-mgr.c @@ -0,0 +1,1929 @@ +/* + * Matchbox Window Manager - A lightweight window manager not for the + * desktop. + * + * Authored By Matthew Allum <mallum@o-hand.com> + * Tomas Frydrych <tf@o-hand.com> + * + * Copyright (c) 2002, 2004, 2007 OpenedHand Ltd - http://o-hand.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "mb-wm.h" +#include "mb-wm-client.h" +#include "mb-wm-comp-mgr.h" + +#include <math.h> + +#include <X11/Xresource.h> +#include <X11/extensions/Xdamage.h> +#include <X11/extensions/Xrender.h> +#include <X11/extensions/Xcomposite.h> + +#define SHADOW_RADIUS 6 +#define SHADOW_OPACITY 0.75 +#define SHADOW_OFFSET_X (-SHADOW_RADIUS) +#define SHADOW_OFFSET_Y (-SHADOW_RADIUS) + +/* + * A helper object to store manager's per-client data + */ +struct MBWMCompMgrClient +{ + MBWMObject parent; + + MBWindowManagerClient * wm_client; + + int damaged; + Damage damage; + Picture picture; + XserverRegion extents; + XserverRegion border_clip; + Bool is_argb32; +}; + +static void +mb_wm_comp_mgr_client_show_real (MBWMCompMgrClient * client); + +static void +mb_wm_comp_mgr_client_hide_real (MBWMCompMgrClient * client); + +static void +mb_wm_comp_mgr_client_repair_real (MBWMCompMgrClient * client); + +static void +mb_wm_comp_mgr_client_configure_real (MBWMCompMgrClient * client); + +static void +mb_wm_comp_mgr_client_class_init (MBWMObjectClass *klass) +{ + MBWMCompMgrClientClass *c_klass = MB_WM_COMP_MGR_CLIENT_CLASS (klass); + + c_klass->show = mb_wm_comp_mgr_client_show_real; + c_klass->hide = mb_wm_comp_mgr_client_hide_real; + c_klass->repair = mb_wm_comp_mgr_client_repair_real; + c_klass->configure = mb_wm_comp_mgr_client_configure_real; + +#ifdef MBWM_WANT_DEBUG + klass->klass_name = "MBWMCompMgrClient"; +#endif +} + +static int +mb_wm_comp_mgr_client_init (MBWMObject *obj, va_list vap) +{ + MBWMCompMgrClient *client = MB_WM_COMP_MGR_CLIENT (obj); + MBWindowManager *wm = NULL; + MBWindowManagerClient *wm_client = NULL; + MBWMObjectProp prop; + XRenderPictFormat *format; + + prop = va_arg(vap, MBWMObjectProp); + while (prop) + { + switch (prop) + { + case MBWMObjectPropClient: + wm_client = va_arg(vap, MBWindowManagerClient *); + break; + default: + MBWMO_PROP_EAT (vap, prop); + } + + prop = va_arg(vap, MBWMObjectProp); + } + + if (!wm_client || !wm_client->wmref) + return 0; + + client->wm_client = wm_client; + wm = wm_client->wmref; + + /* Check visual */ + format = XRenderFindVisualFormat (wm->xdpy, wm_client->window->visual); + + if (format && format->type == PictTypeDirect && format->direct.alphaMask) + client->is_argb32 = True; + + return 1; +} + +static void +mb_wm_comp_mgr_client_destroy (MBWMObject* obj) +{ + MBWMCompMgrClient * c = MB_WM_COMP_MGR_CLIENT (obj); + MBWindowManager *wm = c->wm_client->wmref; + + mb_wm_comp_mgr_client_hide (c); + + if (c->damage) + XDamageDestroy (wm->xdpy, c->damage); + + if (c->picture) + XRenderFreePicture (wm->xdpy, c->picture); + + if (c->extents) + XFixesDestroyRegion (wm->xdpy, c->extents); + + if (c->border_clip) + XFixesDestroyRegion (wm->xdpy, c->border_clip); +} + +int +mb_wm_comp_mgr_client_class_type () +{ + static int type = 0; + + if (UNLIKELY(type == 0)) + { + static MBWMObjectClassInfo info = { + sizeof (MBWMCompMgrClientClass), + sizeof (MBWMCompMgrClient), + mb_wm_comp_mgr_client_init, + mb_wm_comp_mgr_client_destroy, + mb_wm_comp_mgr_client_class_init + }; + + type = mb_wm_object_register_class (&info, MB_WM_TYPE_OBJECT, 0); + } + + return type; +} + +/* + * This is a private method, hence static + */ +static MBWMCompMgrClient * +mb_wm_comp_mgr_client_new (MBWindowManagerClient * client) +{ + MBWMObject *c; + + c = mb_wm_object_new (MB_WM_TYPE_COMP_MGR_CLIENT, + MBWMObjectPropClient, client, + NULL); + + return MB_WM_COMP_MGR_CLIENT (c); +} + +static void +mb_wm_comp_mgr_add_damage (MBWMCompMgr * mgr, XserverRegion damage); + +static XserverRegion +mb_wm_comp_mgr_client_extents (MBWMCompMgrClient *client); + +static void +mb_wm_comp_mgr_client_hide_real (MBWMCompMgrClient * client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + MBWindowManagerClient * c; + Bool is_modal = mb_wm_client_is_modal (wm_client); + + if (is_modal && ((c = mb_wm_get_visible_main_client (wm)) != NULL)) + { + XserverRegion extents; + /* We need to make sure the any lowlighting on a 'parent' + * modal for app gets cleared. This is kind of a sledgehammer + * approach to it, but more suttle attempts oddly fail at times. + * + * FIXME: keep an eye on this for future revisions of composite + * - there may be a better way. + */ + mb_wm_comp_mgr_client_repair_real (c->cm_client); + extents = mb_wm_comp_mgr_client_extents (c->cm_client); + mb_wm_comp_mgr_add_damage (mgr, extents); + } + + if (client->damage) + { + XDamageDestroy (wm->xdpy, client->damage); + client->damage = None; + } + + if (client->extents) + { + mb_wm_comp_mgr_add_damage (mgr, client->extents); + client->extents = None; + } + + if (client->picture) + { + XRenderFreePicture (wm->xdpy, client->picture); + client->picture = None; + } +} + +static void +mb_wm_comp_mgr_client_show_real (MBWMCompMgrClient * client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + XserverRegion region; + XRenderPictureAttributes pa; + MBWMClientType ctype = MB_WM_CLIENT_CLIENT_TYPE (wm_client); + Bool is_modal; + + /* + * Destroying / Recreating the client pictures should hopefully save + * some memory in the server. + */ + if (!client->picture) + { + pa.subwindow_mode = IncludeInferiors; + + client->picture = + XRenderCreatePicture (wm->xdpy, + wm_client->xwin_frame, + client->is_argb32 ? + XRenderFindStandardFormat (wm->xdpy, + PictStandardARGB32) + + : XRenderFindVisualFormat (wm->xdpy, + wm_client->window->visual), + CPSubwindowMode, + &pa); + } + + if (client->damage != None) + XDamageDestroy (wm->xdpy, client->damage); + + client->damage = XDamageCreate (wm->xdpy, wm_client->xwin_frame, + XDamageReportNonEmpty); + + region = mb_wm_comp_mgr_client_extents (client); + + mb_wm_comp_mgr_add_damage (mgr, region); + + /* + * If the wm client is modal we have to add its parent to the damage + * in order for lowlighting to work + */ + if (mb_wm_client_is_modal (wm_client)) + { + MBWindowManagerClient * parent = + mb_wm_client_get_transient_for (wm_client); + + if (parent && parent->cm_client) + { + XserverRegion extents = + mb_wm_comp_mgr_client_extents (parent->cm_client); + + mb_wm_comp_mgr_add_damage (mgr, extents); + } + } + + if (!client->extents) + { + client->extents = mb_wm_comp_mgr_client_extents (client); + } +} + +void +mb_wm_comp_mgr_client_hide (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass + = MB_WM_COMP_MGR_CLIENT_CLASS(MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->hide != NULL); + klass->hide (client); +} + +void +mb_wm_comp_mgr_client_show (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass + = MB_WM_COMP_MGR_CLIENT_CLASS(MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->show != NULL); + klass->show (client); +} + +void +mb_wm_comp_mgr_client_configure (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass + = MB_WM_COMP_MGR_CLIENT_CLASS(MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->configure != NULL); + klass->configure (client); +} + +void +mb_wm_comp_mgr_client_repair (MBWMCompMgrClient * client) +{ + MBWMCompMgrClientClass *klass + = MB_WM_COMP_MGR_CLIENT_CLASS(MB_WM_OBJECT_GET_CLASS (client)); + + MBWM_ASSERT (klass->repair != NULL); + klass->repair (client); +} + +/* + * The Manager itself + */ + +typedef struct MBGaussianMap +{ + int size; + double * data; +} MBGaussianMap; + + +struct MBWMCompMgrPrivate +{ + MBGaussianMap * gaussian_map; + + Picture shadow_n_pic; + Picture shadow_e_pic; + Picture shadow_s_pic; + Picture shadow_w_pic; + + Picture shadow_ne_pic; + Picture shadow_nw_pic; + Picture shadow_se_pic; + Picture shadow_sw_pic; + + Picture shadow_pic; + + int shadow_dx; + int shadow_dy; + int shadow_padding_width; + int shadow_padding_height; + int shadow_style; + unsigned int shadow_color[4]; /* RGBA */ + + Picture trans_picture; + Picture black_picture; + Picture lowlight_picture; + unsigned int lowlight_params[4]; /* RGBA */ + + Picture root_picture; + Picture root_buffer; + + XserverRegion all_damage; + Bool dialog_shade; + int damage_event; +}; + +static void +mb_wm_comp_mgr_private_free (MBWMCompMgr *mgr) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + Display * xdpy = mgr->wm->xdpy; + + if (priv->gaussian_map) + free (priv->gaussian_map); + + XRenderFreePicture (xdpy, priv->shadow_n_pic); + XRenderFreePicture (xdpy, priv->shadow_e_pic); + XRenderFreePicture (xdpy, priv->shadow_s_pic); + XRenderFreePicture (xdpy, priv->shadow_w_pic); + + XRenderFreePicture (xdpy, priv->shadow_ne_pic); + XRenderFreePicture (xdpy, priv->shadow_nw_pic); + XRenderFreePicture (xdpy, priv->shadow_se_pic); + XRenderFreePicture (xdpy, priv->shadow_sw_pic); + + XRenderFreePicture (xdpy, priv->shadow_pic); + + XRenderFreePicture (xdpy, priv->black_picture); + XRenderFreePicture (xdpy, priv->lowlight_picture); + XRenderFreePicture (xdpy, priv->trans_picture); + + if (priv->root_picture) + XRenderFreePicture (xdpy, priv->root_picture); + + if (priv->root_buffer) + XRenderFreePicture (xdpy, priv->root_buffer); + + if (priv->all_damage) + XDamageDestroy (xdpy, priv->all_damage); + + free (priv); +} + +static void +mb_wm_comp_mgr_register_client_real (MBWMCompMgr * mgr, + MBWindowManagerClient * c) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + + if (c->cm_client) + return; + + c->cm_client = mb_wm_comp_mgr_client_new (c); +} + +static void +mb_wm_comp_mgr_unregister_client_real (MBWMCompMgr * mgr, + MBWindowManagerClient * client) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + + if (!client || !client->cm_client) + return; + + mb_wm_object_unref (MB_WM_OBJECT (client->cm_client)); + client->cm_client = NULL; +} + +static void +mb_wm_comp_mgr_turn_on_real (MBWMCompMgr *mgr); + +static void +mb_wm_comp_mgr_turn_off_real (MBWMCompMgr *mgr); + +static void +mb_wm_comp_mgr_render_real (MBWMCompMgr *mgr); + +static Bool +mb_wm_comp_mgr_handle_events_real (MBWMCompMgr * mgr, XEvent *ev); + +static void +mb_wm_comp_mgr_class_init (MBWMObjectClass *klass) +{ + MBWMCompMgrClass *cm_klass = MB_WM_COMP_MGR_CLASS (klass); + +#ifdef MBWM_WANT_DEBUG + klass->klass_name = "MBWMCompMgr"; +#endif + + cm_klass->register_client = mb_wm_comp_mgr_register_client_real; + cm_klass->unregister_client = mb_wm_comp_mgr_unregister_client_real; + cm_klass->turn_on = mb_wm_comp_mgr_turn_on_real; + cm_klass->turn_off = mb_wm_comp_mgr_turn_off_real; + cm_klass->render = mb_wm_comp_mgr_render_real; + cm_klass->handle_events = mb_wm_comp_mgr_handle_events_real; +} + +static void +mb_wm_comp_mgr_init_pictures (MBWMCompMgr *mgr); + +static Bool +mb_wm_comp_mgr_init_extensions (MBWMCompMgr *mgr); + +static int +mb_wm_comp_mgr_init (MBWMObject *obj, va_list vap) +{ + MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); + MBWindowManager * wm = NULL; + MBWMCompMgrPrivate * priv; + MBWMObjectProp prop; + + prop = va_arg(vap, MBWMObjectProp); + while (prop) + { + switch (prop) + { + case MBWMObjectPropWm: + wm = va_arg(vap, MBWindowManager *); + break; + default: + MBWMO_PROP_EAT (vap, prop); + } + + prop = va_arg(vap, MBWMObjectProp); + } + + if (!wm) + return 0; + + mgr->wm = wm; + mgr->priv = mb_wm_util_malloc0 (sizeof (MBWMCompMgrPrivate)); + priv = mgr->priv; + + priv->shadow_dx = SHADOW_OFFSET_X; + priv->shadow_dy = SHADOW_OFFSET_Y; + + /* Not really used yet */ + priv->shadow_padding_width = 0; + priv->shadow_padding_height = 0; + + if (!mb_wm_comp_mgr_init_extensions (mgr)) + return 0; + + mb_wm_theme_get_shadow_color (wm->theme, + &priv->shadow_color[0], + &priv->shadow_color[1], + &priv->shadow_color[2], + &priv->shadow_color[3]); + + mb_wm_theme_get_lowlight_color (wm->theme, + &priv->lowlight_params[0], + &priv->lowlight_params[1], + &priv->lowlight_params[2], + &priv->lowlight_params[3]); + + priv->shadow_style = mb_wm_theme_get_shadow_type (wm->theme); + + mb_wm_comp_mgr_init_pictures (mgr); + + return 1; +} + +static void +mb_wm_comp_mgr_destroy (MBWMObject* obj) +{ + MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); + + mb_wm_comp_mgr_turn_off (mgr); + mb_wm_comp_mgr_private_free (mgr); +} + +int +mb_wm_comp_mgr_class_type () +{ + static int type = 0; + + if (UNLIKELY(type == 0)) + { + static MBWMObjectClassInfo info = { + sizeof (MBWMCompMgrClass), + sizeof (MBWMCompMgr), + mb_wm_comp_mgr_init, + mb_wm_comp_mgr_destroy, + mb_wm_comp_mgr_class_init + }; + + type = mb_wm_object_register_class (&info, MB_WM_TYPE_OBJECT, 0); + } + + return type; +} + +/* Shadow Generation */ +static double +gaussian (double r, double x, double y) +{ + return ((1 / (sqrt (2 * M_PI * r))) * + exp ((- (x * x + y * y)) / (2 * r * r))); +} + + +static MBGaussianMap * +mb_wm_comp_mgr_make_gaussian_map (double r) +{ + MBGaussianMap *c; + int size = ((int) ceil ((r * 3)) + 1) & ~1; + int center = size / 2; + int x, y; + double t = 0.0; + double g; + + c = malloc (sizeof (MBGaussianMap) + size * size * sizeof (double)); + c->size = size; + + c->data = (double *) (c + 1); + + for (y = 0; y < size; y++) + for (x = 0; x < size; x++) + { + g = gaussian (r, (double) (x - center), (double) (y - center)); + t += g; + c->data[y * size + x] = g; + } + + for (y = 0; y < size; y++) + for (x = 0; x < size; x++) + c->data[y*size + x] /= t; + + return c; +} + +static unsigned char +mb_wm_comp_mgr_sum_gaussian (MBWMCompMgr* mgr, double opacity, + int x, int y, int width, int height) +{ + MBGaussianMap * map = mgr->priv->gaussian_map; + int fx, fy; + double * g_data; + double * g_line = map->data; + int g_size = map->size; + int center = g_size / 2; + int fx_start, fx_end; + int fy_start, fy_end; + double v; + + /* + * Compute set of filter values which are "in range", + * that's the set with: + * 0 <= x + (fx-center) && x + (fx-center) < width && + * 0 <= y + (fy-center) && y + (fy-center) < height + * + * 0 <= x + (fx - center) x + fx - center < width + * center - x <= fx fx < width + center - x + */ + + fx_start = center - x; + if (fx_start < 0) + fx_start = 0; + fx_end = width + center - x; + if (fx_end > g_size) + fx_end = g_size; + + fy_start = center - y; + if (fy_start < 0) + fy_start = 0; + fy_end = height + center - y; + if (fy_end > g_size) + fy_end = g_size; + + g_line = g_line + fy_start * g_size + fx_start; + + v = 0; + for (fy = fy_start; fy < fy_end; fy++) + { + g_data = g_line; + g_line += g_size; + + for (fx = fx_start; fx < fx_end; fx++) + v += *g_data++; + } + if (v > 1) + v = 1; + + return ((unsigned int) (v * opacity * 255.0)); +} + +#define MAX_TILE_SZ 16 /* make sure size/2 < MAX_TILE_SZ */ +#define WIDTH 320 +#define HEIGHT 320 + +static void +mb_wm_comp_mgr_shadow_setup_part (MBWMCompMgr * mgr, + XImage ** ximage, + Picture * pic, + Pixmap * pxm, + int width, + int height) +{ + MBWindowManager * wm = mgr->wm; + + *ximage = XCreateImage (wm->xdpy, DefaultVisual(wm->xdpy, wm->xscreen), + 8, ZPixmap, 0, 0, + width, height, 8, width * sizeof (unsigned char)); + + (*ximage)->data = malloc (width * height * sizeof (unsigned char)); + + *pxm = XCreatePixmap (wm->xdpy, wm->root_win->xwindow, + width, height, 8); + + *pic = XRenderCreatePicture (wm->xdpy, *pxm, + XRenderFindStandardFormat (wm->xdpy, + PictStandardA8), + 0, 0); +} + +static void +mb_wm_comp_mgr_shadow_finalise_part (MBWMCompMgr * mgr, + XImage * ximage, + Picture pic, + Pixmap pxm, + int width, + int height) +{ + MBWindowManager * wm = mgr->wm; + + GC gc = XCreateGC (wm->xdpy, pxm, 0, 0); + XPutImage (wm->xdpy, pxm, gc, ximage, 0, 0, 0, 0, width, height); + XDestroyImage (ximage); + XFreeGC (wm->xdpy, gc); + XFreePixmap (wm->xdpy, pxm); +} + +static void +mb_wm_comp_mgr_shadow_setup (MBWMCompMgr * mgr) +{ + MBWindowManager * wm = mgr->wm; + MBWMCompMgrPrivate * priv = mgr->priv; + XImage * ximage; + Pixmap pxm; + unsigned char * data; + int size; + int center; + int x, y; + unsigned char d; + int pwidth, pheight; + double opacity = SHADOW_OPACITY; + + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_NONE) + return; + + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_SIMPLE) + { + priv->shadow_padding_width = 0; + priv->shadow_padding_height = 0; + return; + } + + /* SHADOW_STYLE_GAUSSIAN */ + priv->gaussian_map = + mb_wm_comp_mgr_make_gaussian_map (SHADOW_RADIUS); + + priv->shadow_padding_width = priv->gaussian_map->size; + priv->shadow_padding_height = priv->gaussian_map->size; + + size = priv->gaussian_map->size; + center = size / 2; + + /* Top & bottom */ + pwidth = MAX_TILE_SZ; + pheight = size/2; + mb_wm_comp_mgr_shadow_setup_part (mgr, + &ximage, &priv->shadow_n_pic, &pxm, + pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + center, y - center, WIDTH, HEIGHT); + for (x = 0; x < pwidth; x++) + data[y * pwidth + x] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_n_pic, + pxm, pwidth, pheight); + + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + mb_wm_comp_mgr_shadow_setup_part(mgr, &ximage, &priv->shadow_s_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + center, y - center, WIDTH, HEIGHT); + for (x = 0; x < pwidth; x++) + data[(pheight - y - 1) * pwidth + x] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_s_pic, + pxm, pwidth, pheight); + + /* Sides */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + mb_wm_comp_mgr_shadow_setup_part (mgr, &ximage, &priv->shadow_w_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x - center, center, WIDTH, HEIGHT); + for (y = 0; y < pheight; y++) + data[y * pwidth + (pwidth - x - 1)] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_w_pic, + pxm, pwidth, pheight); + + mb_wm_comp_mgr_shadow_setup_part(mgr, &ximage, &priv->shadow_e_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x - center, center, WIDTH, HEIGHT); + for (y = 0; y < pheight; y++) + data[y * pwidth + x] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_e_pic, + pxm, pwidth, pheight); + + /* Corners */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + mb_wm_comp_mgr_shadow_setup_part (mgr, &ximage, &priv->shadow_nw_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x-center, y-center, WIDTH, HEIGHT); + + data[y * pwidth + x] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_nw_pic, + pxm, pwidth, pheight); + + mb_wm_comp_mgr_shadow_setup_part (mgr, &ximage, &priv->shadow_sw_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x-center, y-center, WIDTH, HEIGHT); + + data[(pheight - y - 1) * pwidth + x] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_sw_pic, + pxm, pwidth, pheight); + + mb_wm_comp_mgr_shadow_setup_part (mgr, &ximage, &priv->shadow_se_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x-center, y-center, WIDTH, HEIGHT); + + data[(pheight - y - 1) * pwidth + (pwidth - x -1)] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_se_pic, + pxm, pwidth, pheight); + + mb_wm_comp_mgr_shadow_setup_part(mgr, &ximage, &priv->shadow_ne_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + { + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + x-center, y-center, WIDTH, HEIGHT); + + data[y * pwidth + (pwidth - x -1)] = d; + } + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_ne_pic, + pxm, pwidth, pheight); + + /* Finally center */ + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + mb_wm_comp_mgr_shadow_setup_part (mgr, &ximage, &priv->shadow_pic, + &pxm, pwidth, pheight); + + data = (unsigned char*)ximage->data; + + d = mb_wm_comp_mgr_sum_gaussian (mgr, opacity, + center, center, WIDTH, HEIGHT); + + for (x = 0; x < pwidth; x++) + for (y = 0; y < pheight; y++) + data[y * pwidth + x] = d; + + mb_wm_comp_mgr_shadow_finalise_part (mgr, ximage, priv->shadow_pic, + pxm, pwidth, pheight); + +} + +static Picture +mb_wm_comp_mgr_shadow_gaussian_make_picture (MBWMCompMgr * mgr, + int width, int height) +{ + MBWindowManager * wm = mgr->wm; + MBWMCompMgrPrivate * priv = mgr->priv; + Picture pic; + Pixmap pxm; + int pwidth, pheight, x, y, dw, dh; + + pxm = XCreatePixmap (wm->xdpy, wm->root_win->xwindow, width, height, 8); + pic = XRenderCreatePicture (wm->xdpy, pxm, + XRenderFindStandardFormat (wm->xdpy, + PictStandardA8), + 0,0); + + pwidth = MAX_TILE_SZ; + pheight = MAX_TILE_SZ; + + for (x=0; x < width; x += pwidth) + for (y=0; y < height; y += pheight) + { + if ( (y + pheight) > height ) + dh = pheight - ((y + pheight)-height); + else + dh = pheight; + + if ( (x + pwidth) > width ) + dw = pwidth - ((x + pwidth)-width); + else + dw = pwidth; + + XRenderComposite (wm->xdpy, PictOpSrc, + priv->shadow_pic, None, pic, + 0, 0, 0, 0, x, y, dw, dh); + } + + /* Top & bottom */ + if ( width > (MAX_TILE_SZ*2) ) + { + pwidth = MAX_TILE_SZ; pheight = MAX_TILE_SZ; + + for (x=0; x < width; x += pwidth ) + { + if ( (x + pwidth) > width ) + dw = pwidth - ((x + pwidth)-width); + else + dw = pwidth; + + XRenderComposite (wm->xdpy, PictOpSrc, + priv->shadow_n_pic, None, pic, + 0, 0, 0, 0, x, 0, dw, pheight); + XRenderComposite (wm->xdpy, PictOpSrc, + priv->shadow_s_pic, None, pic, + 0, 0, 0, 0, x, height - pheight, dw, pheight); + } + } + + /* Sides */ + if ( height > (MAX_TILE_SZ*2) ) + { + pwidth = MAX_TILE_SZ; pheight = MAX_TILE_SZ; + + for (y=0; y < height; y += pheight) + { + if ( (y + pheight) > height ) + dh = pheight - ((y + pheight)-height); + else + dh = pheight; + + XRenderComposite (wm->xdpy, PictOpSrc /* PictOpIn */, + priv->shadow_e_pic, None, pic, + 0, 0, 0, 0, 0, y, pwidth, dh); + XRenderComposite (wm->xdpy, PictOpSrc /* PictOpIn */, + priv->shadow_w_pic, None, pic, + 0, 0, 0, 0, width - pwidth, y, pwidth, dh); + } + } + + /* Corners */ + pwidth = MAX_TILE_SZ; pheight = MAX_TILE_SZ; + + XRenderComposite (wm->xdpy, PictOpSrc, priv->shadow_nw_pic, None, pic, + 0, 0, 0, 0, 0, 0, pwidth, pheight); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->shadow_ne_pic, None, pic, + 0, 0, 0, 0, width - pwidth, 0, pwidth, pheight); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->shadow_sw_pic, None, pic, + 0, 0, 0, 0, 0, height - pheight, pwidth, pheight); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->shadow_se_pic, None, pic, + 0, 0, 0, 0, width - pwidth, height - pheight, + pwidth, pheight); + + XFreePixmap (wm->xdpy, pxm); + return pic; +} + +static XserverRegion +mb_wm_comp_mgr_client_extents (MBWMCompMgrClient *client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + MBWMCompMgrPrivate * priv = mgr->priv; + MBGeometry geom; + XRectangle r; + MBWMClientType ctype = MB_WM_CLIENT_CLIENT_TYPE (wm_client); + XserverRegion extents; + + mb_wm_client_get_coverage (wm_client, &geom); + + r.x = geom.x; + r.y = geom.y; + r.width = geom.width; + r.height = geom.height; + + if (priv->shadow_style) + { + if (ctype == MBWMClientTypeDialog +#if 0 + ctype == MBCLIENT_TYPE_TASK_MENU || + ctype == MBCLIENT_TYPE_OVERRIDE +#endif + ) + { + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_SIMPLE) + { + r.width += priv->shadow_dx; + r.height += priv->shadow_dy; + } + else + { + r.x += priv->shadow_dx; + r.y += priv->shadow_dy; + r.width += priv->shadow_padding_width; + r.height += priv->shadow_padding_height; + } + } + } + + extents = XFixesCreateRegion (wm->xdpy, &r, 1); + + return extents; +} + +static XserverRegion +mb_wm_comp_mgr_client_border_size (MBWMCompMgrClient * client, int x, int y) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + XserverRegion border; + + border = XFixesCreateRegionFromWindow (wm->xdpy, wm_client->xwin_frame, + WindowRegionBounding); + /* translate this */ + XFixesTranslateRegion (wm->xdpy, border, x, y); + return border; +} + +static Visual* +mb_wm_comp_mgr_get_argb32_visual (MBWMCompMgr * mgr) +{ + MBWindowManager * wm = mgr->wm; + XVisualInfo * xvi; + XVisualInfo template; + int nvi; + int i; + XRenderPictFormat * format; + Visual * visual = NULL; + + template.screen = wm->xscreen; + template.depth = 32; + template.class = TrueColor; + + if ((xvi = XGetVisualInfo (wm->xdpy, + VisualScreenMask|VisualDepthMask|VisualClassMask, + &template, + &nvi)) == NULL) + return NULL; + + for (i = 0; i < nvi; i++) + { + format = XRenderFindVisualFormat (wm->xdpy, xvi[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) + { + visual = xvi[i].visual; + break; + } + } + + XFree (xvi); + return visual; +} + +static void +mb_wm_comp_mgr_init_pictures (MBWMCompMgr *mgr) +{ + MBWindowManager * wm; + Window rwin; + MBWMCompMgrPrivate * priv; + Pixmap transPixmap, blackPixmap, lowlightPixmap, + redPixmap; + XRenderPictureAttributes pa; + XRenderColor c; + int i; + + if (!mgr) + return; + + wm = mgr->wm; + rwin = wm->root_win->xwindow; + priv = mgr->priv; + + { + Picture pics_to_free[] = { priv->trans_picture, + priv->black_picture, + priv->lowlight_picture, + priv->shadow_n_pic, + priv->shadow_e_pic, + priv->shadow_s_pic, + priv->shadow_w_pic, + priv->shadow_ne_pic, + priv->shadow_nw_pic, + priv->shadow_se_pic, + priv->shadow_sw_pic, + priv->shadow_pic }; + + for (i=0; i < (sizeof(pics_to_free)/sizeof(Picture)); i++) + if (pics_to_free[i] != None) + XRenderFreePicture (wm->xdpy, pics_to_free[i]); + } + + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_GAUSSIAN) + mb_wm_comp_mgr_shadow_setup (mgr); + + pa.subwindow_mode = IncludeInferiors; + pa.repeat = True; + + transPixmap = XCreatePixmap (wm->xdpy, rwin, 1, 1, 8); + + priv->trans_picture + = XRenderCreatePicture (wm->xdpy, transPixmap, + XRenderFindStandardFormat (wm->xdpy, + PictStandardA8), + CPRepeat, + &pa); + + c.red = c.green = c.blue = 0; + c.alpha = 0xddff; + + XRenderFillRectangle (wm->xdpy, PictOpSrc, priv->trans_picture, + &c, 0, 0, 1, 1); + + /* black pixmap used for shadows */ + + blackPixmap = XCreatePixmap (wm->xdpy, rwin, 1, 1, 32); + + priv->black_picture + = XRenderCreatePicture (wm->xdpy, blackPixmap, + XRenderFindStandardFormat (wm->xdpy, + PictStandardARGB32), + CPRepeat, + &pa); + + c.red = priv->shadow_color[0]; + c.green = priv->shadow_color[1]; + c.blue = priv->shadow_color[2]; + + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_GAUSSIAN) + c.alpha = 0xffff; + else + c.alpha = priv->shadow_color[3]; + + XRenderFillRectangle (wm->xdpy, PictOpSrc, priv->black_picture, + &c, 0, 0, 1, 1); + + /* Used for lowlights */ + lowlightPixmap = XCreatePixmap (wm->xdpy, rwin, 1, 1, 32); + priv->lowlight_picture + = XRenderCreatePicture (wm->xdpy, lowlightPixmap, + XRenderFindStandardFormat (wm->xdpy, + PictStandardARGB32), + CPRepeat, + &pa); + + c.red = priv->lowlight_params[0]; + c.green = priv->lowlight_params[1]; + c.blue = priv->lowlight_params[2]; + c.alpha = priv->lowlight_params[3]; + + XRenderFillRectangle (wm->xdpy, PictOpSrc, priv->lowlight_picture, + &c, 0, 0, 1, 1); + + + pa.repeat = False; + + priv->root_picture + = XRenderCreatePicture (wm->xdpy, rwin, + XRenderFindVisualFormat (wm->xdpy, + DefaultVisual (wm->xdpy, + wm->xscreen)), + CPSubwindowMode, + &pa); + + priv->all_damage = None; +} + +Bool +mb_wm_comp_mgr_init_extensions (MBWMCompMgr *mgr) +{ + MBWindowManager * wm = mgr->wm; + MBWMCompMgrPrivate * priv = mgr->priv; + int event_base, error_base; + int damage_error; + int xfixes_event, xfixes_error; + int render_event, render_error; + XRenderPictureAttributes pa; + Pixmap tmp_pxm; + + if (mgr->disabled) + return False; + + mgr->disabled = True; + + if (!XRenderQueryExtension (wm->xdpy, &render_event, &render_error)) + { + fprintf (stderr, "matchbox: No render extension\n"); + return False; + } + + if (!XCompositeQueryExtension (wm->xdpy, &event_base, &error_base)) + { + fprintf (stderr, "matchbox: No composite extension\n"); + return False; + } + + if (!XDamageQueryExtension (wm->xdpy, &priv->damage_event, &damage_error)) + { + fprintf (stderr, "matchbox: No damage extension\n"); + return False; + } + + if (!XFixesQueryExtension (wm->xdpy, &xfixes_event, &xfixes_error)) + { + fprintf (stderr, "matchbox: No XFixes extension\n"); + return False; + } + + mgr->disabled = False; + + XCompositeRedirectSubwindows (wm->xdpy, wm->root_win->xwindow, + CompositeRedirectManual); + + return True; +} + +/* Shuts the compositing down */ +static void +mb_wm_comp_mgr_turn_off_real (MBWMCompMgr *mgr) +{ + MBWindowManager * wm; + Window rwin; + MBWMCompMgrPrivate * priv; + MBWMList * l; + + if (!mgr) + return; + + priv = mgr->priv; + + if (mgr->disabled) + return; + + wm = mgr->wm; + rwin = wm->root_win->xwindow; + + /* + * really shut down the composite manager. + */ + XCompositeUnredirectSubwindows (wm->xdpy, rwin, CompositeRedirectManual); + + if (priv->root_picture) + { + XRenderFreePicture (wm->xdpy, priv->root_picture); + priv->root_picture = None; + } + + if (priv->root_buffer) + { + priv->root_buffer = None; + XRenderFreePicture (wm->xdpy, priv->root_buffer); + } + + if (priv->all_damage) + { + XDamageDestroy (wm->xdpy, priv->all_damage); + priv->all_damage = None; + } + + /* Free up any client composite resources */ + l = wm->clients; + + while (l) + { + MBWindowManagerClient * wmc = l->data; + MBWMCompMgrClient *c = wmc->cm_client; + + if (c) + { + mb_wm_object_unref (MB_WM_OBJECT (c)); + wmc->cm_client = NULL; + } + + l = l->next; + } + + mgr->disabled = True; +} + +static void +mb_wm_comp_mgr_render_region (MBWMCompMgr *mgr, XserverRegion region); + +static void +mb_wm_comp_mgr_turn_on_real (MBWMCompMgr *mgr) +{ + MBWindowManager * wm; + Window rwin; + MBWMCompMgrPrivate * priv; + MBWMList * l; + + if (!mgr) + return; + + priv = mgr->priv; + + if (!mgr->disabled) + return; + + wm = mgr->wm; + rwin = wm->root_win->xwindow; + + mgr->disabled = False; + + if (!mb_wm_comp_mgr_init_extensions (mgr)) + return; + + mb_wm_comp_mgr_init_pictures (mgr); + + XSync (wm->xdpy, False); + + if (!mb_wm_stack_empty (wm)) + { + MBWindowManagerClient * c; + + mb_wm_stack_enumerate (wm, c) + { + mb_wm_comp_mgr_register_client (mgr, c); + mb_wm_comp_mgr_client_show (c->cm_client); + } + + mb_wm_comp_mgr_render_region (mgr, None); + } +} + +static int +mb_wm_comp_mgr_client_get_translucency (MBWMCompMgrClient *client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + + return wm_client->window->translucency; +} + +static void +mb_wm_comp_mgr_add_damage (MBWMCompMgr * mgr, XserverRegion damage) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + MBWindowManager * wm = mgr->wm; + + if (priv->all_damage) + { + XFixesUnionRegion (wm->xdpy, priv->all_damage, priv->all_damage, + damage); + + XFixesDestroyRegion (wm->xdpy, damage); + } + else + priv->all_damage = damage; + + mb_wm_display_sync_queue (wm, MBWMSyncVisibility); +} + +static void +mb_wm_comp_mgr_client_repair_real (MBWMCompMgrClient * client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + XserverRegion parts; + MBGeometry geom; + + parts = XFixesCreateRegion (wm->xdpy, 0, 0); + + /* translate region */ + XDamageSubtract (wm->xdpy, client->damage, None, parts); + + mb_wm_client_get_coverage (wm_client, &geom); + + XFixesTranslateRegion (wm->xdpy, parts, geom.x, geom.y); + mb_wm_comp_mgr_add_damage (mgr, parts); +} + +static void +mb_wm_comp_mgr_client_configure_real (MBWMCompMgrClient * client) +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + XserverRegion damage = None; + XserverRegion extents; + + extents = mb_wm_comp_mgr_client_extents (client); + + if (client->picture) + { + XRenderFreePicture (wm->xdpy, client->picture); + client->picture = None; + } + + damage = XFixesCreateRegion (wm->xdpy, 0, 0); + + if (client->extents) + { + XFixesCopyRegion (wm->xdpy, damage, client->extents); + XFixesDestroyRegion (wm->xdpy, client->extents); + } + + XFixesUnionRegion (wm->xdpy, damage, damage, extents); + + client->extents = extents; + + mb_wm_comp_mgr_add_damage (mgr, damage); +} + +static Bool +mb_wm_comp_mgr_handle_events_real (MBWMCompMgr * mgr, XEvent *ev) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + MBWindowManager * wm = mgr->wm; + + if (ev->type == priv->damage_event + XDamageNotify) + { + XDamageNotifyEvent * de = (XDamageNotifyEvent*) ev; + MBWindowManagerClient * c; + + c = mb_wm_managed_client_from_frame (wm, de->drawable); + + if (c && c->cm_client) + mb_wm_comp_mgr_client_repair_real (c->cm_client); + else + { + MBWM_DBG ("failed to find damaged window \n"); + } + } + + return False; +} + +static void +_render_a_client (MBWMCompMgrClient *client, + XserverRegion region, + int lowlight_type) /*0 none, 1 app, 2 full*/ +{ + MBWindowManagerClient * wm_client = client->wm_client; + MBWindowManager * wm = wm_client->wmref; + MBWMCompMgr * mgr = wm->comp_mgr; + MBWMCompMgrPrivate * priv = mgr->priv; + MBWMClientType ctype = MB_WM_CLIENT_CLIENT_TYPE (wm_client); + MBGeometry geom; + XserverRegion winborder; + + if (!client->picture) + return; + + mb_wm_client_get_coverage (wm_client, &geom); + + winborder = mb_wm_comp_mgr_client_border_size (client, geom.x, geom.y); + + /* Translucency only done for dialogs and overides */ + if ( !client->is_argb32 && + (ctype == MBWMClientTypeApp || + ctype == MBWMClientTypeDesktop || + ctype == MBWMClientTypeInput || + ctype == MBWMClientTypePanel || + mb_wm_comp_mgr_client_get_translucency (client) == -1)) + { + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, region); + + XFixesSubtractRegion (wm->xdpy, region, region, winborder); + + XRenderComposite (wm->xdpy, PictOpSrc, + client->picture, + None, priv->root_buffer, + 0, 0, 0, 0, + geom.x, geom.y, geom.width, geom.height); + } + + /* Render lowlight dialog modal for app */ + if (lowlight_type == 1 && + (ctype & (MBWMClientTypeApp | MBWMClientTypeDesktop))) + { + int title_offset = 0; + + if (ctype == MBWMClientTypeApp) + title_offset = mb_wm_client_title_height (wm_client); + + XRenderComposite (wm->xdpy, PictOpOver, priv->lowlight_picture, None, + priv->root_buffer, + 0, 0, 0, 0, geom.x, geom.y + title_offset, + geom.width, geom.height - title_offset); + } + + /* Render lowlight dialog modal for root - e.g lowlight everything */ + if (lowlight_type == 2 /* && client->win_modal_blocker == None */) + { + XRenderComposite (wm->xdpy, PictOpOver, priv->lowlight_picture, None, + priv->root_buffer, + 0, 0, 0, 0, geom.x, geom.y, + geom.width, geom.height); + } + + if (client->border_clip) + { + XFixesDestroyRegion (wm->xdpy, client->border_clip); + client->border_clip = None; + } + + client->border_clip = XFixesCreateRegion (wm->xdpy, 0, 0); + XFixesCopyRegion (wm->xdpy, client->border_clip, region); + + XFixesDestroyRegion (wm->xdpy, winborder); +} + +static void +mb_wm_comp_mgr_render_real (MBWMCompMgr *mgr) +{ + MBWMCompMgrPrivate * priv = mgr->priv; + + mb_wm_comp_mgr_render_region (mgr, priv->all_damage); + + if (priv->all_damage) + { + XDamageDestroy (mgr->wm->xdpy, priv->all_damage); + priv->all_damage = None; + } +} + +static void +mb_wm_comp_mgr_render_region (MBWMCompMgr *mgr, XserverRegion region) +{ + MBWindowManager * wm = mgr->wm; + MBWMCompMgrPrivate * priv = mgr->priv; + MBWindowManagerClient * wmc_top, * wmc_temp, * wmc_solid = NULL; + int lowlight = 0; + int destroy_region = 0; + Bool done; + Bool top_translucent = False; + + if (!region) + { + /* + * Fullscreen render + */ + XRectangle r; + + r.x = 0; + r.y = 0; + r.width = wm->xdpy_width; + r.height = wm->xdpy_height; + + region = XFixesCreateRegion (wm->xdpy, &r, 1); + destroy_region = 1; + } + + wmc_top = mb_wm_get_visible_main_client (wm); + + if (wmc_top) + top_translucent = + (mb_wm_comp_mgr_client_get_translucency (wmc_top->cm_client) == -1); + + if (!priv->root_buffer) + { + Pixmap rootPixmap = + XCreatePixmap (wm->xdpy, wm->root_win->xwindow, + wm->xdpy_width, wm->xdpy_height, + DefaultDepth (wm->xdpy, wm->xscreen)); + + priv->root_buffer = + XRenderCreatePicture (wm->xdpy, rootPixmap, + XRenderFindVisualFormat (wm->xdpy, + DefaultVisual (wm->xdpy, + wm->xscreen)), + 0, 0); + + XFreePixmap (wm->xdpy, rootPixmap); + } + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_picture, 0, 0, region); + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, region); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->black_picture, + None, priv->root_buffer, 0, 0, 0, 0, 0, 0, + wm->xdpy_width, wm->xdpy_height); + + /* + * Check initially to see what kind of lowlight todo ( if any ) + */ + mb_wm_stack_enumerate_reverse (wm, wmc_temp) + { + MBWMClientType type = MB_WM_CLIENT_CLIENT_TYPE (wmc_temp); + Bool is_modal = mb_wm_client_is_modal (wmc_temp); + + if (type == MBWMClientTypeDialog && is_modal) + { + lowlight = (/*(wmc_temp->win_modal_blocker) ? 2 : */1); + } + + if (wmc_temp == wmc_top) + break; + } + + /* Render top -> bottom */ + done = False; + mb_wm_stack_enumerate_reverse (wm, wmc_temp) + { + _render_a_client(wmc_temp->cm_client, region, lowlight); + + /* + * Render clients until we reach first client on/below the top + * which is not translucent. + */ + if (wmc_temp == wmc_top) + { + done = True; + } + + if (done && + !wmc_temp->cm_client->is_argb32 && + mb_wm_comp_mgr_client_get_translucency (wmc_temp->cm_client) == -1) + { + wmc_solid = wmc_temp; + break; + } + } + + if (!wmc_top) + { + /* Render block of boring black in case of no top app or desktop */ + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, region); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->black_picture, + None, priv->root_buffer, 0, 0, 0, 0, 0, 0, + wm->xdpy_width, wm->xdpy_height); + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, None); + + wmc_top = wm->stack_bottom; + } + + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, None); + + /* + * Now render shadows and any translucent clients but bottom -> top this + * time + * + * We start from the first solid client on the stack, so that any + * translucent windows on the top of the stack get correctly rendered. + */ + for (wmc_temp = wmc_solid ? wmc_solid : wmc_top; + wmc_temp; wmc_temp=wmc_temp->stacked_above) + { + MBWMClientType type = MB_WM_CLIENT_CLIENT_TYPE (wmc_temp); + MBWMCompMgrClient * c = wmc_temp->cm_client; + Bool is_translucent; + + if (!c || !c->picture) + continue; + + /* + * We have to process all dialogs and, if the top client is translucent, + * any translucent windows as well. + */ + is_translucent = (c->is_argb32 || + mb_wm_comp_mgr_client_get_translucency (c) != -1); + + if (mb_wm_client_is_mapped (wmc_temp) && + (type == MBWMClientTypeDialog || + (top_translucent && is_translucent))) + { + if (priv->shadow_style) + { + Picture shadow_pic; + MBGeometry geom; + + mb_wm_client_get_coverage (wmc_temp, &geom); + + if (priv->shadow_style == MBWM_COMP_MGR_SHADOW_SIMPLE) + { + XserverRegion shadow_region; + + /* Grab 'shape' region of window */ + shadow_region = + mb_wm_comp_mgr_client_border_size (c, geom.x, geom.y); + + /* Offset it. */ + XFixesTranslateRegion (wm->xdpy, shadow_region, + priv->shadow_dx, + priv->shadow_dy); + + /* Intersect it, so only border remains */ + XFixesIntersectRegion (wm->xdpy, shadow_region, + c->border_clip, + shadow_region ); + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, + 0, 0, shadow_region); + + /* now paint them */ + if (wmc_temp->cm_client->is_argb32) + { + XRenderComposite (wm->xdpy, PictOpOver, + priv->black_picture, + c->picture, + priv->root_buffer, + 0, 0, 0, 0, + geom.x + priv->shadow_dx, + geom.y + priv->shadow_dy, + geom.width + + priv->shadow_padding_width, + geom.height + + priv->shadow_padding_height); + + } + else + { + XRenderComposite (wm->xdpy, PictOpOver, + priv->black_picture, + None, + priv->root_buffer, + 0, 0, 0, 0, + geom.x + priv->shadow_dx, + geom.y + priv->shadow_dy, + geom.width + + priv->shadow_padding_width, + geom.height + + priv->shadow_padding_height); + } + + /* Paint any translucent window contents */ + if (is_translucent) + { + XFixesDestroyRegion (wm->xdpy, shadow_region); + + shadow_region = + mb_wm_comp_mgr_client_border_size (c, geom.x, geom.y); + + XFixesIntersectRegion (wm->xdpy, shadow_region, + c->border_clip, shadow_region ); + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, + 0, 0, shadow_region); + + if (c->is_argb32) + XRenderComposite (wm->xdpy, PictOpOver, + c->picture, None, + priv->root_buffer, 0, 0, 0, 0, + geom.x, geom.y, + geom.width, geom.height); + + else + XRenderComposite (wm->xdpy, PictOpOver, + c->picture, priv->trans_picture, + priv->root_buffer, 0, 0, 0, 0, + geom.x, geom.y, + geom.width, geom.height); + } + + XFixesDestroyRegion (wm->xdpy, shadow_region); + } + else /* GAUSSIAN */ + { + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, + 0, 0, c->border_clip); + + if (is_translucent) + { + /* No shadows currently for transparent windows */ + XRenderComposite (wm->xdpy, PictOpOver, + c->picture, priv->trans_picture, + priv->root_buffer, 0, 0, 0, 0, + geom.x, geom.y, + geom.width, geom.height); + } + else + { + /* Combine pregenerated shadow tiles */ + shadow_pic = + mb_wm_comp_mgr_shadow_gaussian_make_picture (mgr, + geom.width + priv->shadow_padding_width, + geom.height + priv->shadow_padding_height); + + XRenderComposite (wm->xdpy, PictOpOver, + priv->black_picture, + shadow_pic, + priv->root_buffer, + 0, 0, 0, 0, + geom.x + priv->shadow_dx, + geom.y + priv->shadow_dy, + geom.width + + priv->shadow_padding_width, + geom.height + + priv->shadow_padding_height); + + XRenderFreePicture (wm->xdpy, shadow_pic); + } + } + } + } + } + + XFixesSetPictureClipRegion (wm->xdpy, priv->root_buffer, 0, 0, None); + + XRenderComposite (wm->xdpy, PictOpSrc, priv->root_buffer, None, + priv->root_picture, + 0, 0, 0, 0, 0, 0, wm->xdpy_width, wm->xdpy_height); + + if (destroy_region) + XDamageDestroy (wm->xdpy, region); +} + +Bool +mb_wm_comp_mgr_enabled (MBWMCompMgr *mgr) +{ + if (!mgr) + return False; + + return (mgr->disabled != True); +} + +MBWMCompMgr * +mb_wm_comp_mgr_new (MBWindowManager *wm) +{ + MBWMObject *mgr; + + mgr = mb_wm_object_new (MB_WM_TYPE_COMP_MGR, MBWMObjectPropWm, wm, NULL); + + return MB_WM_COMP_MGR (mgr); +} + +void +mb_wm_comp_mgr_register_client (MBWMCompMgr * mgr, + MBWindowManagerClient * client) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->register_client != NULL); + klass->register_client (mgr, client); +} + +void +mb_wm_comp_mgr_unregister_client (MBWMCompMgr * mgr, + MBWindowManagerClient * client) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->unregister_client != NULL); + klass->unregister_client (mgr, client); +} + +void +mb_wm_comp_mgr_render (MBWMCompMgr *mgr) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->render != NULL); + klass->render (mgr); +} + +void +mb_wm_comp_mgr_turn_on (MBWMCompMgr *mgr) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->turn_on != NULL); + klass->turn_on (mgr); +} + +void +mb_wm_comp_mgr_turn_off (MBWMCompMgr *mgr) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->turn_off != NULL); + klass->turn_off (mgr); +} + +Bool +mb_wm_comp_mgr_handle_events (MBWMCompMgr * mgr, XEvent *ev) +{ + MBWMCompMgrClass *klass + = MB_WM_COMP_MGR_CLASS(MB_WM_OBJECT_GET_CLASS (mgr)); + + MBWM_ASSERT (klass->handle_events != NULL); + return klass->handle_events (mgr, ev); +} + diff --git a/src/comp-mgr/mb-wm-comp-mgr.h b/src/comp-mgr/mb-wm-comp-mgr.h new file mode 100644 index 0000000..c6a1fb5 --- /dev/null +++ b/src/comp-mgr/mb-wm-comp-mgr.h @@ -0,0 +1,110 @@ +/* + * Matchbox Window Manager - A lightweight window manager not for the + * desktop. + * + * Authored By Matthew Allum <mallum@o-hand.com> + * Tomas Frydrych <tf@o-hand.com> + * + * Copyright (c) 2002, 2004, 2007 OpenedHand Ltd - http://o-hand.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _HAVE_MB_WM_COMP_MGR_H +#define _HAVE_MB_WM_COMP_MGR_H + +#include <X11/extensions/Xdamage.h> + +#define MB_WM_COMP_MGR(c) ((MBWMCompMgr*)(c)) +#define MB_WM_COMP_MGR_CLASS(c) ((MBWMCompMgrClass*)(c)) +#define MB_WM_TYPE_COMP_MGR (mb_wm_comp_mgr_class_type ()) + +#define MB_WM_COMP_MGR_CLIENT(c) ((MBWMCompMgrClient*)(c)) +#define MB_WM_COMP_MGR_CLIENT_CLASS(c) ((MBWMCompMgrClientClass*)(c)) +#define MB_WM_TYPE_COMP_MGR_CLIENT (mb_wm_comp_mgr_client_class_type ()) + +struct MBWMCompMgr +{ + MBWMObject parent; + + MBWindowManager *wm; + Bool disabled; + + MBWMCompMgrPrivate *priv; +}; + +struct MBWMCompMgrClass +{ + MBWMObjectClass parent; + + void (*register_client) (MBWMCompMgr * mgr, MBWindowManagerClient *c); + void (*unregister_client) (MBWMCompMgr * mgr, MBWindowManagerClient *c); + void (*turn_on) (MBWMCompMgr * mgr); + void (*turn_off) (MBWMCompMgr * mgr); + void (*render) (MBWMCompMgr * mgr); + Bool (*handle_events) (MBWMCompMgr * mgr, XEvent *ev); +}; + +int +mb_wm_comp_mgr_class_type (); + +MBWMCompMgr* +mb_wm_comp_mgr_new (MBWindowManager *wm); + +void +mb_wm_comp_mgr_register_client (MBWMCompMgr * mgr, MBWindowManagerClient *c); + +void +mb_wm_comp_mgr_unregister_client (MBWMCompMgr * mgr, + MBWindowManagerClient *client); + +void +mb_wm_comp_mgr_turn_off (MBWMCompMgr *mgr); + +void +mb_wm_comp_mgr_turn_on (MBWMCompMgr *mgr); + +void +mb_wm_comp_mgr_render (MBWMCompMgr *mgr); + +Bool +mb_wm_comp_mgr_enabled (MBWMCompMgr *mgr); + +Bool +mb_wm_comp_mgr_handle_events (MBWMCompMgr * mgr, XEvent *ev); + +struct MBWMCompMgrClientClass +{ + MBWMObjectClass parent; + + void (*show) (MBWMCompMgrClient * client); + void (*hide) (MBWMCompMgrClient * client); + void (*repair) (MBWMCompMgrClient * client); + void (*configure) (MBWMCompMgrClient * client); +}; + +int +mb_wm_comp_mgr_client_class_type (); + +void +mb_wm_comp_mgr_client_show (MBWMCompMgrClient * client); + +void +mb_wm_comp_mgr_client_hide (MBWMCompMgrClient * client); + +void +mb_wm_comp_mgr_client_repair (MBWMCompMgrClient * client); + +void +mb_wm_comp_mgr_client_configure (MBWMCompMgrClient * client); + +#endif diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 723a1df..fa04f42 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -39,7 +39,6 @@ core_c = mb-wm-object.c \ xas.c libmatchbox_window_manager_2_core_a_SOURCES = $(core_h) $(core_c) -libmatchbox_window_manager_2_core_a_INCLUDES = @MBWM_INCS@ -libmatchbox_window_manager_2_core_a_CFLAGS = @MBWM_CFLAGS@ +libmatchbox_window_manager_2_core_a_CFLAGS = @MBWM_INCS@ @MBWM_CFLAGS@ -MAINTAINERCLEANFILES = config.h.in Makefile.in
\ No newline at end of file +MAINTAINERCLEANFILES = Makefile.in
\ No newline at end of file diff --git a/src/core/mb-window-manager.c b/src/core/mb-window-manager.c index e3897cc..e6edb57 100644 --- a/src/core/mb-window-manager.c +++ b/src/core/mb-window-manager.c @@ -6,6 +6,10 @@ #include "../client-types/mb-wm-client-input.h" #include "../theme-engines/mb-wm-theme.h" +#ifdef ENABLE_COMPOSITE +#include "mb-wm-comp-mgr.h" +#endif + #include <stdarg.h> #include <X11/Xmd.h> @@ -71,6 +75,14 @@ mb_wm_real_theme_new (MBWindowManager * wm, const char * path) return mb_wm_theme_new (wm, path); } +#ifdef ENABLE_COMPOSITE +static MBWMCompMgr * +mb_wm_real_comp_mgr_new (MBWindowManager *wm) +{ + return mb_wm_comp_mgr_new (wm); +} +#endif + static void mb_wm_class_init (MBWMObjectClass *klass) { @@ -84,6 +96,10 @@ mb_wm_class_init (MBWMObjectClass *klass) wm_class->client_new = mb_wm_client_new_func; wm_class->theme_new = mb_wm_real_theme_new; +#ifdef ENABLE_COMPOSITE + wm_class->comp_mgr_new = mb_wm_real_comp_mgr_new; +#endif + #ifdef MBWM_WANT_DEBUG klass->klass_name = "MBWindowManager"; #endif @@ -327,6 +343,13 @@ mb_wm_handle_property_notify (XPropertyEvent *xev, } static Bool +mb_wm_handle_config_notify (XConfigureEvent *xev, + void *userdata) +{ + /* FIXME */ +} + +static Bool mb_wm_handle_config_request (XConfigureRequestEvent *xev, void *userdata) { @@ -384,6 +407,13 @@ mb_wm_handle_config_request (XConfigureRequestEvent *xev, } +#ifdef ENABLE_COMPOSITE + if (mb_wm_comp_mgr_enabled (wm->comp_mgr)) + { + mb_wm_comp_mgr_client_configure (client->cm_client); + } +#endif + return True; } @@ -508,6 +538,11 @@ mb_wm_sync (MBWindowManager *wm) if (mb_wm_client_needs_sync (client)) mb_wm_client_display_sync (client); +#ifdef ENABLE_COMPOSITE + if (mb_wm_comp_mgr_enabled (wm->comp_mgr)) + mb_wm_comp_mgr_render (wm->comp_mgr); +#endif + /* FIXME: optimise wm sync flags so know if this needs calling */ /* FIXME: Can we restack an unmapped window ? - problem of new * clients mapping below existing ones. @@ -646,7 +681,10 @@ mb_wm_manage_client (MBWindowManager *wm, else if (MB_WM_IS_CLIENT_DESKTOP(client)) wm->desktop = client; - /* set flags to map - should this go elsewhere? */ +#ifdef ENABLE_COMPOSITE + if (mb_wm_comp_mgr_enabled (wm->comp_mgr)) + mb_wm_comp_mgr_register_client (wm->comp_mgr, client); +#endif if (activate) mb_wm_activate_client (wm, client); @@ -707,6 +745,11 @@ mb_wm_unmanage_client (MBWindowManager *wm, } } +#ifdef ENABLE_COMPOSITE + if (mb_wm_comp_mgr_enabled (wm->comp_mgr)) + mb_wm_comp_mgr_unregister_client (wm->comp_mgr, client); +#endif + if (wm->focused_client == client) mb_wm_unfocus_client (wm, client); @@ -742,6 +785,29 @@ mb_wm_managed_client_from_xwindow(MBWindowManager *wm, Window win) return NULL; } +MBWindowManagerClient* +mb_wm_managed_client_from_frame (MBWindowManager *wm, Window frame) +{ + MBWindowManagerClient *client = NULL; + MBWMList *l; + + if (frame == wm->root_win->xwindow) + return NULL; + + l = wm->clients; + while (l) + { + client = l->data; + + if (client->xwin_frame == frame) + return client; + + l = l->next; + } + + return NULL; +} + void mb_wm_main_loop(MBWindowManager *wm) { @@ -995,6 +1061,12 @@ mb_wm_init (MBWMObject *this, va_list vap) wm); mb_wm_main_context_x_event_handler_add (wm->main_ctx, + None, + ConfigureNotify, + (MBWMXEventFunc)mb_wm_handle_config_notify, + wm); + + mb_wm_main_context_x_event_handler_add (wm->main_ctx, None, PropertyNotify, (MBWMXEventFunc)mb_wm_handle_property_notify, @@ -1028,6 +1100,11 @@ mb_wm_init (MBWMObject *this, va_list vap) mb_wm_init_cursors (wm); +#ifdef ENABLE_COMPOSITE + if (wm_class->comp_mgr_new) + wm->comp_mgr = wm_class->comp_mgr_new (wm); +#endif + base_foo (); mb_wm_manage_preexistsing_wins (wm); @@ -1403,3 +1480,35 @@ mb_wm_set_cursor (MBWindowManager * wm, MBWindowManagerCursor cursor) wm->cursor = cursor; } +void +mb_wm_compositing_on (MBWindowManager * wm) +{ +#ifdef ENABLE_COMPOSITE + if (!wm->comp_mgr) + wm->comp_mgr = mb_wm_comp_mgr_new (wm); + + if (!mb_wm_comp_mgr_enabled (wm->comp_mgr)) + mb_wm_comp_mgr_turn_on (wm->comp_mgr); +#endif +} + + +void +mb_wm_compositing_off (MBWindowManager * wm) +{ +#ifdef ENABLE_COMPOSITE + if (wm->comp_mgr && mb_wm_comp_mgr_enabled (wm->comp_mgr)) + mb_wm_comp_mgr_turn_off (wm->comp_mgr); +#endif +} + +Bool +mb_wm_compositing_enabled (MBWindowManager * wm) +{ +#ifdef ENABLE_COMPOSITE + return mb_wm_comp_mgr_enabled (wm->comp_mgr); +#else + return False; +#endif +} + diff --git a/src/core/mb-window-manager.h b/src/core/mb-window-manager.h index 6355a9c..2fc5130 100644 --- a/src/core/mb-window-manager.h +++ b/src/core/mb-window-manager.h @@ -4,7 +4,7 @@ * * Authored By Matthew Allum <mallum@o-hand.com> * - * Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com + * Copyright (c) 2005, 2007 OpenedHand Ltd - http://o-hand.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,10 @@ #ifndef _HAVE_MB_WM_WINDOW_MANAGER_H #define _HAVE_MB_WM_WINDOW_MANAGER_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + typedef struct MBWindowManagerClass MBWindowManagerClass; typedef struct MBWindowManagerPriv MBWindowManagerPriv; @@ -78,6 +82,9 @@ struct MBWindowManager MBWMLayout *layout; MBWMMainContext *main_ctx; MBWindowManagerFlag flags; +#ifdef ENABLE_COMPOSITE + MBWMCompMgr *comp_mgr; +#endif MBWindowManagerCursor cursor; Cursor cursors[_MBWindowManagerCursorLast]; @@ -101,6 +108,10 @@ struct MBWindowManagerClass Bool (*client_hang) (MBWindowManager *wm, MBWindowManagerClient *c); MBWMTheme * (*theme_new) (MBWindowManager *wm, const char * path); + +#ifdef ENABLE_COMPOSITE + MBWMCompMgr * (*comp_mgr_new) (MBWindowManager *wm); +#endif }; MBWindowManager * @@ -119,7 +130,7 @@ MBWindowManagerClient* mb_wm_managed_client_from_xwindow(MBWindowManager *wm, Window win); MBWindowManagerClient* -mb_wm_iconized_client_from_xwindow(MBWindowManager *wm, Window win); +mb_wm_managed_client_from_frame (MBWindowManager *wm, Window frame); int mb_wm_register_client_type (void); @@ -174,4 +185,13 @@ mb_wm_set_theme_from_path (MBWindowManager *wm, const char *theme_path); void mb_wm_set_cursor (MBWindowManager * wm, MBWindowManagerCursor cursor); +void +mb_wm_compositing_on (MBWindowManager * wm); + +void +mb_wm_compositing_off (MBWindowManager * wm); + +Bool +mb_wm_compositing_enabled (MBWindowManager * wm); + #endif diff --git a/src/core/mb-wm-atoms.c b/src/core/mb-wm-atoms.c index 32d8d6d..033b42c 100644 --- a/src/core/mb-wm-atoms.c +++ b/src/core/mb-wm-atoms.c @@ -95,6 +95,7 @@ mb_wm_atoms_init(MBWindowManager *wm) "_MB_APP_WINDOW_LIST_STACKING", "_MB_THEME", "_MB_THEME_NAME", + "_MB_COMMAND", }; /* FIXME: Error Traps */ diff --git a/src/core/mb-wm-client-base.c b/src/core/mb-wm-client-base.c index e5c499d..a3f0faf 100644 --- a/src/core/mb-wm-client-base.c +++ b/src/core/mb-wm-client-base.c @@ -21,6 +21,10 @@ #include "mb-wm.h" #include <X11/Xmd.h> +#ifdef ENABLE_COMPOSITE +#include <X11/extensions/Xrender.h> +#endif + static void mb_wm_client_base_realize (MBWindowManagerClient *client); @@ -146,18 +150,53 @@ mb_wm_client_base_realize (MBWindowManagerClient *client) if (client->xwin_frame == None) { - client->xwin_frame - = XCreateWindow(wm->xdpy, wm->root_win->xwindow, - client->frame_geometry.x, - client->frame_geometry.y, - client->frame_geometry.width, - client->frame_geometry.height, - 0, - CopyFromParent, - CopyFromParent, - CopyFromParent, - CWOverrideRedirect|CWEventMask|CWBackPixel, - &attr); +#ifdef ENABLE_COMPOSITE + XRenderPictFormat *format; + Bool is_argb32 = False; + XSetWindowAttributes attr2; + + format = XRenderFindVisualFormat (wm->xdpy, client->window->visual); + + if (format && format->type == PictTypeDirect && + format->direct.alphaMask) + { + is_argb32 = True; + } + + if (is_argb32) + { + attr.colormap = client->window->colormap; + + client->xwin_frame + = XCreateWindow(wm->xdpy, wm->root_win->xwindow, + client->frame_geometry.x, + client->frame_geometry.y, + client->frame_geometry.width, + client->frame_geometry.height, + 0, + 32, + InputOutput, + client->window->visual, + CWOverrideRedirect|CWEventMask|CWBackPixel| + CWBorderPixel|CWColormap, + &attr); + } + else +#endif + { + client->xwin_frame + = XCreateWindow(wm->xdpy, wm->root_win->xwindow, + client->frame_geometry.x, + client->frame_geometry.y, + client->frame_geometry.width, + client->frame_geometry.height, + 0, + CopyFromParent, + CopyFromParent, + CopyFromParent, + CWOverrideRedirect|CWEventMask|CWBackPixel, + &attr); + } /* * Assume geometry sync will fix this up correctly togeather with diff --git a/src/core/mb-wm-client-window.c b/src/core/mb-wm-client-window.c index a844280..c9ab009 100644 --- a/src/core/mb-wm-client-window.c +++ b/src/core/mb-wm-client-window.c @@ -38,6 +38,8 @@ enum { COOKIE_WIN_ICON, COOKIE_WIN_ACTIONS, COOKIE_WIN_USER_TIME, + COOKIE_WIN_CM_TRANSLUCENCY, + COOKIE_WIN_NET_STATE, N_COOKIES }; @@ -215,6 +217,11 @@ mb_wm_client_window_sync_properties ( MBWMClientWindow *win, = mb_wm_property_atom_req(wm, xwin, wm->atoms[MBWM_ATOM_NET_WM_WINDOW_TYPE]); + if (props_req & MBWM_WINDOW_PROP_NET_STATE) + cookies[COOKIE_WIN_NET_STATE] + = mb_wm_property_atom_req(wm, xwin, + wm->atoms[MBWM_ATOM_NET_WM_STATE]); + if (props_req & MBWM_WINDOW_PROP_ATTR) cookies[COOKIE_WIN_ATTR] = mb_wm_xwin_get_attributes (wm, xwin); @@ -306,6 +313,14 @@ mb_wm_client_window_sync_properties ( MBWMClientWindow *win, wm->atoms[MBWM_ATOM_NET_WM_USER_TIME]); } + if (props_req & MBWM_WINDOW_PROP_CM_TRANSLUCENCY) + { + cookies[COOKIE_WIN_CM_TRANSLUCENCY] + = mb_wm_property_cardinal_req (wm, + xwin, + wm->atoms[MBWM_ATOM_CM_TRANSLUCENCY]); + } + /* bundle all pending requests to server and wait for replys */ XSync(wm->xdpy, False); @@ -343,18 +358,81 @@ mb_wm_client_window_sync_properties ( MBWMClientWindow *win, result_atom = NULL; } - if (props_req & MBWM_WINDOW_PROP_ATTR) + if (props_req & MBWM_WINDOW_PROP_NET_STATE) { - xwin_attr = mb_wm_xwin_get_attributes_reply (wm, - cookies[COOKIE_WIN_ATTR], - &x_error_code); + mb_wm_property_reply (wm, + cookies[COOKIE_WIN_NET_STATE], + &actual_type_return, + &actual_format_return, + &nitems_return, + &bytes_after_return, + (unsigned char **)&result_atom, + &x_error_code); - if (!xwin_attr || x_error_code) + if (x_error_code + || actual_type_return != XA_ATOM + || actual_format_return != 32 + || nitems_return <= 0 + || result_atom == NULL + ) { - MBWM_DBG("### Warning Get Attr Failed ( %i ) ###", x_error_code); - goto abort; + MBWM_DBG("### Warning net type state failed ###"); + } + else + { + int i; + win->ewmh_state = 0; + + for (i = 0; i < nitems_return; ++i) + { + if (result_atom[i] == wm->atoms[MBWM_ATOM_NET_WM_STATE_MODAL]) + win->ewmh_state |= MBWMClientWindowEWMHStateModal; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_STICKY]) + win->ewmh_state |= MBWMClientWindowEWMHStateSticky; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_MAXIMIZED_VERT]) + win->ewmh_state |= MBWMClientWindowEWMHStateMaximisedVert; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) + win->ewmh_state |= MBWMClientWindowEWMHStateMaximisedHorz; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_SHADED]) + win->ewmh_state |= MBWMClientWindowEWMHStateShaded; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_SKIP_TASKBAR]) + win->ewmh_state |= MBWMClientWindowEWMHStateSkipTaskbar; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_SKIP_PAGER]) + win->ewmh_state |= MBWMClientWindowEWMHStateSkipPager; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_HIDDEN]) + win->ewmh_state |= MBWMClientWindowEWMHStateHidden; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_FULLSCREEN]) + win->ewmh_state |= MBWMClientWindowEWMHStateFullscreen; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_ABOVE]) + win->ewmh_state |= MBWMClientWindowEWMHStateAbove; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_BELOW]) + win->ewmh_state |= MBWMClientWindowEWMHStateBelow; + else if (result_atom[i] == + wm->atoms[MBWM_ATOM_NET_WM_STATE_DEMANDS_ATTENTION]) + win->ewmh_state |= MBWMClientWindowEWMHStateDemandsAttention; + } } + changes |= MBWM_WINDOW_PROP_NET_STATE; + + if (result_atom) + XFree(result_atom); + + result_atom = NULL; + } + + if (props_req & MBWM_WINDOW_PROP_GEOMETRY) + { if (!mb_wm_xwin_get_geometry_reply (wm, cookies[COOKIE_WIN_GEOM], &win->geometry, @@ -362,16 +440,37 @@ mb_wm_client_window_sync_properties ( MBWMClientWindow *win, &win->depth, &x_error_code)) { - MBWM_DBG("### Warning Get Geometry Failed ( %i ) ###", x_error_code); - MBWM_DBG("### Cookie ID was %li ###", cookies[COOKIE_WIN_GEOM]); + MBWM_DBG("### Warning Get Geometry Failed ( %i ) ###", + x_error_code); + MBWM_DBG("### Cookie ID was %li ###", + cookies[COOKIE_WIN_GEOM]); goto abort; } MBWM_DBG("@@@ New Window Obj @@@"); MBWM_DBG("Win: %lx", win->xwindow); MBWM_DBG("Type: %lx",win->net_type); - MBWM_DBG("Geom: +%i+%i,%ix%i", win->geometry.x, win->geometry.y, - win->geometry.width, win->geometry.height); + MBWM_DBG("Geom: +%i+%i,%ix%i", + win->geometry.x, + win->geometry.y, + win->geometry.width, + win->geometry.height); + } + + if (props_req & MBWM_WINDOW_PROP_ATTR) + { + xwin_attr = mb_wm_xwin_get_attributes_reply (wm, + cookies[COOKIE_WIN_ATTR], + &x_error_code); + + if (!xwin_attr || x_error_code) + { + MBWM_DBG("### Warning Get Attr Failed ( %i ) ###", x_error_code); + goto abort; + } + + win->visual = xwin_attr->visual; + win->colormap = xwin_attr->colormap; } if (props_req & MBWM_WINDOW_PROP_NAME) @@ -609,6 +708,40 @@ mb_wm_client_window_sync_properties ( MBWMClientWindow *win, XFree(pid); } + if (props_req & MBWM_WINDOW_PROP_CM_TRANSLUCENCY) + { + int *translucency = NULL; + + mb_wm_property_reply (wm, + cookies[COOKIE_WIN_CM_TRANSLUCENCY], + &actual_type_return, + &actual_format_return, + &nitems_return, + &bytes_after_return, + (unsigned char **)&translucency, + &x_error_code); + + if (x_error_code + || actual_type_return != XA_CARDINAL + || actual_format_return != 32 + || translucency == NULL + ) + { + MBWM_DBG("### no CM_TRANSLUCENCY prop ###"); + win->translucency = -1; + } + else + { + win->translucency = *translucency; + MBWM_DBG("@@@ translucency %d @@@", win->translucency); + } + + changes |= MBWM_WINDOW_PROP_CM_TRANSLUCENCY; + + if (translucency) + XFree (translucency); + } + if (props_req & MBWM_WINDOW_PROP_NET_ICON) { unsigned long *icons = NULL; diff --git a/src/core/mb-wm-client-window.h b/src/core/mb-wm-client-window.h index 9eaefef..64e4a64 100644 --- a/src/core/mb-wm-client-window.h +++ b/src/core/mb-wm-client-window.h @@ -44,6 +44,7 @@ #define MBWM_WINDOW_PROP_CLIENT_MACHINE (1<<13) #define MBWM_WINDOW_PROP_ALLOWED_ACTIONS (1<<14) #define MBWM_WINDOW_PROP_NET_USER_TIME (1<<15) +#define MBWM_WINDOW_PROP_CM_TRANSLUCENCY (1<<17) #define MBWM_WINDOW_PROP_ALL (0xffffffff) @@ -116,6 +117,8 @@ struct MBWMClientWindow unsigned int depth; char *name; Window xwindow; + Visual *visual; + Colormap colormap; MBWindowManager *wm; Atom net_type; @@ -131,6 +134,7 @@ struct MBWMClientWindow MBWMClientWindowProtos protos; pid_t pid; + int translucency; char *machine; MBWMList *icons; diff --git a/src/core/mb-wm-client.c b/src/core/mb-wm-client.c index 13a5ebf..a901021 100644 --- a/src/core/mb-wm-client.c +++ b/src/core/mb-wm-client.c @@ -33,10 +33,11 @@ mb_wm_client_destroy (MBWMObject *obj) { MBWindowManagerClient * client = MB_WM_CLIENT(obj); MBWindowManagerClient * c; - MBWMList * l = client->decor; + MBWindowManager * wm = client->wmref; + MBWMList * l = client->decor; if (client->sig_theme_change_id) - mb_wm_object_signal_disconnect (MB_WM_OBJECT (client->wmref), + mb_wm_object_signal_disconnect (MB_WM_OBJECT (wm), client->sig_theme_change_id); client->sig_theme_change_id = 0; @@ -47,9 +48,16 @@ mb_wm_client_destroy (MBWMObject *obj) client->sig_prop_change_id = 0; if (client->ping_cb_id) - mb_wm_main_context_timeout_handler_remove (client->wmref->main_ctx, + mb_wm_main_context_timeout_handler_remove (wm->main_ctx, client->ping_cb_id); +#ifdef ENABLE_COMPOSITE + if (mb_wm_compositing_enabled (wm)) + { + mb_wm_comp_mgr_unregister_client (wm->comp_mgr, client); + } +#endif + mb_wm_object_unref (MB_WM_OBJECT (client->window)); while (l) @@ -70,7 +78,7 @@ mb_wm_client_destroy (MBWMObject *obj) while (l) { MBWindowManagerClient * c = l->data; - XUnmapWindow (client->wmref->xdpy, c->window->xwindow); + XUnmapWindow (wm->xdpy, c->window->xwindow); l = l->next; } #endif @@ -264,6 +272,14 @@ mb_wm_client_on_property_change (MBWMClientWindow *window, if (property & MBWM_WINDOW_PROP_GEOMETRY) mb_wm_client_geometry_mark_dirty (client); +#ifdef ENABLE_COMPOSITE + if ((property & MBWM_WINDOW_PROP_CM_TRANSLUCENCY) && + client->cm_client && mb_wm_comp_mgr_enabled (client->wmref->comp_mgr)) + { + mb_wm_comp_mgr_client_repair (client->cm_client); + } +#endif + return False; } @@ -434,6 +450,16 @@ mb_wm_client_display_sync (MBWindowManagerClient *client) klass->sync(client); +#ifdef ENABLE_COMPOSITE + if (client->cm_client) + { + if (client->priv->mapped) + mb_wm_comp_mgr_client_show (client->cm_client); + else + mb_wm_comp_mgr_client_hide (client->cm_client); + } +#endif + client->priv->sync_state = 0; } @@ -822,3 +848,32 @@ mb_wm_client_iconize (MBWindowManagerClient *client) MBWM_ATOM_NET_WM_STATE_HIDDEN, MBWMClientWindowStateChangeAdd); } + +int +mb_wm_client_title_height (MBWindowManagerClient *client) +{ + MBWMClientWindow * win = client->window; + MBWindowManager * wm = client->wmref; + int north; + + if (!wm->theme || + mb_wm_client_window_is_state_set (win, + MBWMClientWindowEWMHStateFullscreen)) + { + return 0; + } + + + mb_wm_theme_get_decor_dimensions (wm->theme, client, + &north, NULL, NULL, NULL); + + return north; +} + +Bool +mb_wm_client_is_modal (MBWindowManagerClient *client) +{ + return mb_wm_client_window_is_state_set (client->window, + MBWMClientWindowEWMHStateModal); +} + diff --git a/src/core/mb-wm-client.h b/src/core/mb-wm-client.h index 5a9f0dc..b29575b 100644 --- a/src/core/mb-wm-client.h +++ b/src/core/mb-wm-client.h @@ -21,6 +21,10 @@ #ifndef _HAVE_MB_CLIENT_H #define _HAVE_MB_CLIENT_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define MB_WM_CLIENT(c) ((MBWindowManagerClient*)(c)) #define MB_WM_CLIENT_CLASS(c) ((MBWindowManagerClientClass*)(c)) #define MB_WM_TYPE_CLIENT (mb_wm_client_class_type ()) @@ -161,6 +165,10 @@ struct MBWindowManagerClient unsigned long ping_cb_id; unsigned long sig_theme_change_id; int ping_timeout; + +#ifdef ENABLE_COMPOSITE + MBWMCompMgrClient *cm_client; +#endif }; #define mb_wm_client_frame_west_width(c) \ @@ -316,4 +324,10 @@ mb_wm_client_reset_iconizing (MBWindowManagerClient *client); void mb_wm_client_iconize (MBWindowManagerClient *client); +int +mb_wm_client_title_height (MBWindowManagerClient *client); + +Bool +mb_wm_client_is_modal (MBWindowManagerClient *client); + #endif diff --git a/src/core/mb-wm-main-context.c b/src/core/mb-wm-main-context.c index 26f8a02..3d046d3 100644 --- a/src/core/mb-wm-main-context.c +++ b/src/core/mb-wm-main-context.c @@ -373,6 +373,12 @@ mb_wm_main_context_handle_x_event (XEvent *xev, break; } +#ifdef ENABLE_COMPOSITE + if (mb_wm_comp_mgr_enabled (wm->comp_mgr)) + if (mb_wm_comp_mgr_handle_events (wm->comp_mgr, xev)) + return True; +#endif + return False; } diff --git a/src/core/mb-wm-object-props.h b/src/core/mb-wm-object-props.h index 3644a00..ce6c6a1 100644 --- a/src/core/mb-wm-object-props.h +++ b/src/core/mb-wm-object-props.h @@ -63,23 +63,27 @@ typedef enum MBWMObjectProp MBWMObjectPropArgc = _MKOPROP(3, int), MBWMObjectPropArgv = _MKOPROP(4, void*), MBWMObjectPropWm = _MKOPROP(5, void*), - MBWMObjectPropClientWindow = _MKOPROP(6, void*), + MBWMObjectPropClient = _MKOPROP(6, void*), + MBWMObjectPropClientWindow = _MKOPROP(7, void*), - MBWMObjectPropDecor = _MKOPROP(7, void*), - MBWMObjectPropDecorType = _MKOPROP(8, MBWMDecorType), - MBWMObjectPropDecorUserData = _MKOPROP(9, void*), - MBWMObjectPropDecorAbsolutePacking = _MKOPROP(10, int), + MBWMObjectPropDecor = _MKOPROP(8, void*), + MBWMObjectPropDecorType = _MKOPROP(9, MBWMDecorType), + MBWMObjectPropDecorUserData = _MKOPROP(10, void*), + MBWMObjectPropDecorAbsolutePacking = _MKOPROP(11, int), - MBWMObjectPropDecorButtonRepaintFunc = _MKOPROP(11, void*), - MBWMObjectPropDecorButtonPressedFunc = _MKOPROP(12, void*), - MBWMObjectPropDecorButtonReleasedFunc = _MKOPROP(13, void*), - MBWMObjectPropDecorButtonFlags = _MKOPROP(14, MBWMDecorButtonFlags), - MBWMObjectPropDecorButtonType = _MKOPROP(15, int), - MBWMObjectPropDecorButtonPack = _MKOPROP(16, int), + MBWMObjectPropDecorButtonRepaintFunc = _MKOPROP(12, void*), + MBWMObjectPropDecorButtonPressedFunc = _MKOPROP(13, void*), + MBWMObjectPropDecorButtonReleasedFunc = _MKOPROP(14, void*), + MBWMObjectPropDecorButtonFlags = _MKOPROP(15, MBWMDecorButtonFlags), + MBWMObjectPropDecorButtonType = _MKOPROP(16, int), + MBWMObjectPropDecorButtonPack = _MKOPROP(17, int), - MBWMObjectPropThemePath = _MKOPROP(17, void*), - MBWMObjectPropThemeImg = _MKOPROP(18, void*), - MBWMObjectPropThemeXmlClients = _MKOPROP(19, void*), + MBWMObjectPropThemePath = _MKOPROP(18, void*), + MBWMObjectPropThemeImg = _MKOPROP(19, void*), + MBWMObjectPropThemeXmlClients = _MKOPROP(20, void*), + MBWMObjectPropThemeColorLowlight = _MKOPROP(21, void*), + MBWMObjectPropThemeColorShadow = _MKOPROP(22, void*), + MBWMObjectPropThemeShadowType = _MKOPROP(23, int), _MBWMObjectPropLastGlobal = 0x00fffff0, } diff --git a/src/core/mb-wm-root-window.c b/src/core/mb-wm-root-window.c index b40a0ec..1044c77 100644 --- a/src/core/mb-wm-root-window.c +++ b/src/core/mb-wm-root-window.c @@ -370,6 +370,33 @@ mb_wm_root_window_handle_message(MBWMRootWindow *win, XClientMessageEvent *e) mb_wm_handle_show_desktop (wm, e->data.l[0]); return 1; } + else if (e->message_type == wm->atoms[MBWM_ATOM_MB_COMMAND]) + { + switch (e->data.l[0]) + { + case MB_CMD_EXIT: + exit(0); + case MB_CMD_NEXT: + mb_wm_cycle_apps (wm); + break; + case MB_CMD_DESKTOP: + mb_wm_toggle_desktop (wm); + break; +#ifdef ENABLE_COMPOSITE + case MB_CMD_COMPOSITE: + if (mb_wm_compositing_enabled (wm)) + mb_wm_compositing_off (wm); + else + mb_wm_compositing_on (wm->comp_mgr); + break; +#endif + default: + /*FIXME -- not implemented yet */ + case MB_CMD_PREV: + case MB_CMB_KEYS_RELOAD: + ; + } + } return 0; } diff --git a/src/core/mb-wm-types.h b/src/core/mb-wm-types.h index 1752aa9..4ef6a7d 100644 --- a/src/core/mb-wm-types.h +++ b/src/core/mb-wm-types.h @@ -98,7 +98,11 @@ typedef struct MBWMLayout MBWMLayout; typedef struct MBWMLayoutClass MBWMLayoutClass; typedef struct MBWMMainContext MBWMMainContext; typedef struct MBWMMainContextClass MBWMMainContextClass; - +typedef struct MBWMCompMgr MBWMCompMgr; +typedef struct MBWMCompMgrPrivate MBWMCompMgrPrivate; +typedef struct MBWMCompMgrClass MBWMCompMgrClass; +typedef struct MBWMCompMgrClient MBWMCompMgrClient; +typedef struct MBWMCompMgrClientClass MBWMCompMgrClientClass; typedef enum MBWMClientType { @@ -208,6 +212,7 @@ typedef enum MBWMAtom MBWM_ATOM_MB_APP_WINDOW_LIST_STACKING, MBWM_ATOM_MB_THEME, MBWM_ATOM_MB_THEME_NAME, + MBWM_ATOM_MB_COMMAND, /* FIXME: Custom/Unused to sort out * @@ -217,7 +222,6 @@ typedef enum MBWMAtom * _NET_WM_SYNC_REQUEST, * _MB_CURRENT_APP_WINDOW, * - * MB_COMMAND, * MB_CLIENT_EXEC_MAP, * MB_CLIENT_STARTUP_LIST, * MB_DOCK_TITLEBAR_SHOW_ON_DESKTOP, @@ -349,5 +353,31 @@ typedef enum MBWMSyncType MBWMSyncFullscreen = (1<<6), } MBWMSyncType; +typedef struct MBWMColor +{ + double r; + double g; + double b; + double a; + + Bool set; +}MBWMColor; + +typedef enum MBWMCompMgrShadowType +{ + MBWM_COMP_MGR_SHADOW_NONE = 0, + MBWM_COMP_MGR_SHADOW_SIMPLE, + MBWM_COMP_MGR_SHADOW_GAUSSIAN, +} MBWMCompMgrShadowType; + +/* mb remote commands */ +#define MB_CMD_SET_THEME 1 +#define MB_CMD_EXIT 2 +#define MB_CMD_DESKTOP 3 +#define MB_CMD_NEXT 4 +#define MB_CMD_PREV 5 +#define MB_CMD_MISC 7 /* spare, used for debugging */ +#define MB_CMD_COMPOSITE 8 +#define MB_CMB_KEYS_RELOAD 9 #endif diff --git a/src/managers/maemo/Makefile.am b/src/managers/maemo/Makefile.am index 6ca2ec3..f19db7c 100644 --- a/src/managers/maemo/Makefile.am +++ b/src/managers/maemo/Makefile.am @@ -12,27 +12,33 @@ CLIENT_LIBS = \ THEME_LIBS = @MBWM_THEME_LIBS@/libmb-theme.a +if ENABLE_COMPOSITE +COMPMGR_LIBS=@MBWM_COMPMGR_LIBS@/libmatchbox-window-manager-2-compmgr.a +endif + bin_PROGRAMS = matchbox-window-manager-2-maemo -matchbox_window_manager_2_maemo_SOURCES = \ - maemo-toolbar.c \ - maemo-input.c \ - maemo-window-manager.c \ +matchbox_window_manager_2_maemo_SOURCES = \ + maemo-toolbar.c \ + maemo-input.c \ + maemo-window-manager.c \ matchbox-window-manager-2-maemo.c -matchbox_window_manager_2_maemo_LDFLAGS = \ - $(MBWM_DEBUG_LDFLAGS) \ +matchbox_window_manager_2_maemo_LDFLAGS = \ + $(MBWM_DEBUG_LDFLAGS) \ $(LDFLAGS) -matchbox_window_manager_2_maemo_LDADD = \ - @MBWM_LIBS@ \ - @MBWM_CORE_LIB@ \ - $(THEME_LIBS) \ - $(CLIENT_LIBS) - -matchbox_window_manager_2_maemo_DEPENDENCIES = \ - @MBWM_CORE_LIB@ \ - $(THEME_LIBS) \ - $(CLIENT_LIBS) +matchbox_window_manager_2_maemo_LDADD = \ + @MBWM_LIBS@ \ + @MBWM_CORE_LIB@ \ + $(THEME_LIBS) \ + $(CLIENT_LIBS) \ + $(COMPMGR_LIBS) + +matchbox_window_manager_2_maemo_DEPENDENCIES = \ + @MBWM_CORE_LIB@ \ + $(THEME_LIBS) \ + $(CLIENT_LIBS) \ + $(COMPMGR_LIBS) MAINTAINERCLEANFILES = config.h.in Makefile.in
\ No newline at end of file diff --git a/src/managers/simple/Makefile.am b/src/managers/simple/Makefile.am index f25816f..f5ea4e3 100644 --- a/src/managers/simple/Makefile.am +++ b/src/managers/simple/Makefile.am @@ -9,27 +9,32 @@ CLIENT_LIBS = \ @MBWM_CLIENT_LIBS@/libmb-wm-client-input.a \ @MBWM_CLIENT_LIBS@/libmb-wm-client-desktop.a +if ENABLE_COMPOSITE +COMPMGR_LIBS=@MBWM_COMPMGR_LIBS@/libmatchbox-window-manager-2-compmgr.a +endif THEME_LIBS = @MBWM_THEME_LIBS@/libmb-theme.a bin_PROGRAMS = matchbox-window-manager-2-simple -matchbox_window_manager_2_simple_SOURCES = \ +matchbox_window_manager_2_simple_SOURCES = \ matchbox-window-manager-2-simple.c -matchbox_window_manager_2_simple_LDFLAGS = \ - $(MBWM_DEBUG_LDFLAGS) \ +matchbox_window_manager_2_simple_LDFLAGS = \ + $(MBWM_DEBUG_LDFLAGS) \ $(LDFLAGS) -matchbox_window_manager_2_simple_LDADD = \ - @MBWM_LIBS@ \ - @MBWM_CORE_LIB@ \ - $(THEME_LIBS) \ - $(CLIENT_LIBS) - -matchbox_window_manager_2_simple_DEPENDENCIES = \ - @MBWM_CORE_LIB@ \ - $(THEME_LIBS) \ - $(CLIENT_LIBS) +matchbox_window_manager_2_simple_LDADD = \ + @MBWM_LIBS@ \ + @MBWM_CORE_LIB@ \ + $(THEME_LIBS) \ + $(CLIENT_LIBS) \ + $(COMPMGR_LIBS) + +matchbox_window_manager_2_simple_DEPENDENCIES = \ + @MBWM_CORE_LIB@ \ + $(THEME_LIBS) \ + $(CLIENT_LIBS) \ + $(COMPMGR_LIBS) MAINTAINERCLEANFILES = config.h.in Makefile.in
\ No newline at end of file diff --git a/src/theme-engines/mb-wm-theme-cairo.c b/src/theme-engines/mb-wm-theme-cairo.c index f7d4cb0..b63e7f6 100644 --- a/src/theme-engines/mb-wm-theme-cairo.c +++ b/src/theme-engines/mb-wm-theme-cairo.c @@ -479,10 +479,10 @@ mb_wm_theme_cairo_paint_decor (MBWMTheme *theme, cairo_matrix_t matrix; cairo_t *cr; double x, y, w, h; - struct Clr clr_bg; - struct Clr clr_fg; - struct Clr clr_frame; - struct Clr clr_bg2; + MBWMColor clr_bg; + MBWMColor clr_fg; + MBWMColor clr_frame; + MBWMColor clr_bg2; MBWMClientType c_type; MBWMThemeCairo *c_theme = MB_WM_THEME_CAIRO (theme); MBWMXmlClient * c; @@ -678,8 +678,8 @@ mb_wm_theme_cairo_paint_button (MBWMTheme *theme, MBWMDecorButton *button) int xi, yi, wi, hi; double x, y, w, h; cairo_font_extents_t font_extents; - struct Clr clr_bg; - struct Clr clr_fg; + MBWMColor clr_bg; + MBWMColor clr_fg; MBWMClientType c_type; MBWMThemeCairo *c_theme = MB_WM_THEME_CAIRO (theme); MBWMXmlClient * c; diff --git a/src/theme-engines/mb-wm-theme-simple.c b/src/theme-engines/mb-wm-theme-simple.c index 4bb382e..93816a2 100644 --- a/src/theme-engines/mb-wm-theme-simple.c +++ b/src/theme-engines/mb-wm-theme-simple.c @@ -465,9 +465,9 @@ mb_wm_theme_simple_paint_decor (MBWMTheme *theme, MBWMDecor *decor) MBWindowManagerClient *client; Window xwin; MBWindowManager *wm = theme->wm; - struct Clr clr_bg; - struct Clr clr_fg; - struct Clr clr_frame; + MBWMColor clr_bg; + MBWMColor clr_fg; + MBWMColor clr_frame; MBWMClientType c_type; MBWMXmlClient *c = NULL; MBWMXmlDecor *d = NULL; @@ -616,8 +616,8 @@ mb_wm_theme_simple_paint_button (MBWMTheme *theme, MBWMDecorButton *button) Window xwin; MBWindowManager *wm = theme->wm; int x, y, w, h; - struct Clr clr_bg; - struct Clr clr_fg; + MBWMColor clr_bg; + MBWMColor clr_fg; MBWMClientType c_type; MBWMXmlClient *c = NULL; MBWMXmlDecor *d = NULL; diff --git a/src/theme-engines/mb-wm-theme-xml.c b/src/theme-engines/mb-wm-theme-xml.c index 31ea39d..75e4389 100644 --- a/src/theme-engines/mb-wm-theme-xml.c +++ b/src/theme-engines/mb-wm-theme-xml.c @@ -108,7 +108,7 @@ mb_wm_xml_client_free (MBWMXmlClient * c) } void -mb_wm_xml_clr_from_string (struct Clr * clr, const char *s) +mb_wm_xml_clr_from_string (MBWMColor * clr, const char *s) { int r, g, b; diff --git a/src/theme-engines/mb-wm-theme-xml.h b/src/theme-engines/mb-wm-theme-xml.h index 1cf0920..8632bea 100644 --- a/src/theme-engines/mb-wm-theme-xml.h +++ b/src/theme-engines/mb-wm-theme-xml.h @@ -6,22 +6,13 @@ /* * Helper structs for xml theme */ -typedef struct Clr -{ - double r; - double g; - double b; - - Bool set; -}MBWMXmlClr; - typedef struct Button { MBWMDecorButtonType type; MBWMDecorButtonPack packing; - struct Clr clr_fg; - struct Clr clr_bg; + MBWMColor clr_fg; + MBWMColor clr_bg; int x; int y; @@ -33,10 +24,10 @@ typedef struct Decor { MBWMDecorType type; - struct Clr clr_fg; - struct Clr clr_bg; - struct Clr clr_bg2; - struct Clr clr_frame; + MBWMColor clr_fg; + MBWMColor clr_bg; + MBWMColor clr_bg2; + MBWMColor clr_frame; int x; int y; @@ -89,6 +80,6 @@ MBWMXmlButton * mb_wm_xml_button_find_by_type (MBWMList *l, MBWMDecorButtonType type); void -mb_wm_xml_clr_from_string (MBWMXmlClr * clr, const char *s); +mb_wm_xml_clr_from_string (MBWMColor * clr, const char *s); #endif diff --git a/src/theme-engines/mb-wm-theme.c b/src/theme-engines/mb-wm-theme.c index 0ac0c5a..c5d8f07 100644 --- a/src/theme-engines/mb-wm-theme.c +++ b/src/theme-engines/mb-wm-theme.c @@ -62,6 +62,8 @@ mb_wm_theme_init (MBWMObject *obj, va_list vap) MBWMObjectProp prop; MBWMList *xml_clients = NULL; char *path = NULL; + MBWMColor *clr_lowlight = NULL; + MBWMColor *clr_shadow = NULL; prop = va_arg(vap, MBWMObjectProp); while (prop) @@ -77,6 +79,16 @@ mb_wm_theme_init (MBWMObject *obj, va_list vap) case MBWMObjectPropThemeXmlClients: xml_clients = va_arg(vap, MBWMList *); break; + case MBWMObjectPropThemeColorLowlight: + clr_lowlight = va_arg(vap, MBWMColor *); + break; + case MBWMObjectPropThemeColorShadow: + clr_shadow = va_arg(vap, MBWMColor *); + break; + case MBWMObjectPropThemeShadowType: + theme->shadow_type = va_arg(vap, int); + break; + default: MBWMO_PROP_EAT (vap, prop); } @@ -90,6 +102,36 @@ mb_wm_theme_init (MBWMObject *obj, va_list vap) if (path) theme->path = strdup (path); + if (clr_shadow && clr_shadow->set) + { + theme->color_shadow.r = clr_shadow->r; + theme->color_shadow.g = clr_shadow->g; + theme->color_shadow.b = clr_shadow->b; + theme->color_shadow.a = clr_shadow->a; + } + else + { + theme->color_shadow.r = 0.0; + theme->color_shadow.g = 0.0; + theme->color_shadow.b = 0.0; + theme->color_shadow.a = 0.95; + } + + if (clr_lowlight && clr_lowlight->set) + { + theme->color_lowlight.r = clr_lowlight->r; + theme->color_lowlight.g = clr_lowlight->g; + theme->color_lowlight.b = clr_lowlight->b; + theme->color_lowlight.a = clr_lowlight->a; + } + else + { + theme->color_lowlight.r = 0.0; + theme->color_lowlight.g = 0.0; + theme->color_lowlight.b = 0.0; + theme->color_lowlight.a = 0.55; + } + return 1; } @@ -200,6 +242,17 @@ mb_wm_theme_paint_decor (MBWMTheme *theme, MBWMDecor *decor) if (klass->paint_decor) klass->paint_decor (theme, decor); + +#ifdef ENABLE_COMPOSITE + { + MBWindowManagerClient *c = decor->parent_client; + + if (c->cm_client) + { + mb_wm_comp_mgr_client_repair (c->cm_client); + } + } +#endif } void @@ -214,6 +267,17 @@ mb_wm_theme_paint_button (MBWMTheme *theme, MBWMDecorButton *button) if (klass->paint_button) klass->paint_button (theme, button); + +#ifdef ENABLE_COMPOSITE + { + MBWindowManagerClient *c = button->decor->parent_client; + + if (c->cm_client) + { + mb_wm_comp_mgr_client_repair (c->cm_client); + } + } +#endif } Bool @@ -249,6 +313,9 @@ struct expat_data MBWMList *xml_clients; char *img; MBWMList *stack; + MBWMColor color_lowlight; + MBWMColor color_shadow; + MBWMCompMgrShadowType shadow_type; }; MBWMTheme * @@ -262,6 +329,9 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) FILE *file = NULL; MBWMList *xml_clients = NULL; char *img = NULL; + MBWMColor clr_lowlight; + MBWMColor clr_shadow; + MBWMCompMgrShadowType shadow_type; /* Attempt to parse the xml theme, if any, retrieving the theme type * @@ -368,6 +438,20 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) } } + clr_lowlight.r = udata.color_lowlight.r; + clr_lowlight.g = udata.color_lowlight.g; + clr_lowlight.b = udata.color_lowlight.b; + clr_lowlight.a = udata.color_lowlight.a; + clr_lowlight.set = udata.color_lowlight.set; + + clr_shadow.r = udata.color_shadow.r; + clr_shadow.g = udata.color_shadow.g; + clr_shadow.b = udata.color_shadow.b; + clr_shadow.a = udata.color_shadow.a; + clr_shadow.set = udata.color_shadow.set; + + shadow_type = udata.shadow_type; + xml_stack_free (udata.stack); } } @@ -376,11 +460,14 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) { theme = MB_WM_THEME (mb_wm_object_new (theme_type, - MBWMObjectPropWm, wm, - MBWMObjectPropThemePath, path, - MBWMObjectPropThemeImg, img, - MBWMObjectPropThemeXmlClients, xml_clients, - NULL)); + MBWMObjectPropWm, wm, + MBWMObjectPropThemePath, path, + MBWMObjectPropThemeImg, img, + MBWMObjectPropThemeXmlClients, xml_clients, + MBWMObjectPropThemeColorLowlight, &clr_lowlight, + MBWMObjectPropThemeColorShadow, &clr_shadow, + MBWMObjectPropThemeShadowType, shadow_type, + NULL)); } default_theme: @@ -389,13 +476,16 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) { theme = MB_WM_THEME (mb_wm_object_new ( #ifdef USE_CAIRO - MB_WM_TYPE_THEME_CAIRO, + MB_WM_TYPE_THEME_CAIRO, #else - MB_WM_TYPE_THEME_SIMPLE, + MB_WM_TYPE_THEME_SIMPLE, #endif - MBWMObjectPropWm, wm, - MBWMObjectPropThemeXmlClients, xml_clients, - NULL)); + MBWMObjectPropWm, wm, + MBWMObjectPropThemeXmlClients, xml_clients, + MBWMObjectPropThemeColorLowlight, &clr_lowlight, + MBWMObjectPropThemeColorShadow, &clr_shadow, + MBWMObjectPropThemeShadowType, shadow_type, + NULL)); } if (par) @@ -459,6 +549,94 @@ mb_wm_theme_get_client_geometry (MBWMTheme * theme, return True; } +/* + * Retrieves color to be used for lowlighting (16-bit rgba) + */ +void +mb_wm_theme_get_lowlight_color (MBWMTheme * theme, + unsigned int * red, + unsigned int * green, + unsigned int * blue, + unsigned int * alpha) +{ + if (theme) + { + if (red) + *red = (unsigned int)(theme->color_lowlight.r * (double)0xffff); + + if (green) + *green = (unsigned int)(theme->color_lowlight.g * (double)0xffff); + + if (blue) + *blue = (unsigned int)(theme->color_lowlight.b * (double)0xffff); + + if (alpha) + *alpha = (unsigned int)(theme->color_lowlight.a * (double)0xffff); + + return; + } + + if (red) + *red = 0; + + if (green) + *green = 0; + + if (blue) + *blue = 0; + + if (*alpha) + *alpha = 0x8d8d; +} + +/* + * Retrieves color to be used for lowlighting (16-bit rgba) + */ +void +mb_wm_theme_get_shadow_color (MBWMTheme * theme, + unsigned int * red, + unsigned int * green, + unsigned int * blue, + unsigned int * alpha) +{ + if (theme) + { + if (red) + *red = (unsigned int)(theme->color_shadow.r * (double)0xffff); + + if (green) + *green = (unsigned int)(theme->color_shadow.g * (double)0xffff); + + if (blue) + *blue = (unsigned int)(theme->color_shadow.b * (double)0xffff); + + if (alpha) + *alpha = (unsigned int)(theme->color_shadow.a * (double)0xffff); + + return; + } + + if (red) + *red = 0; + + if (green) + *green = 0; + + if (blue) + *blue = 0; + + if (*alpha) + *alpha = 0xff00; +} + +MBWMCompMgrShadowType +mb_wm_theme_get_shadow_type (MBWMTheme * theme) +{ + if (!theme) + return MBWM_COMP_MGR_SHADOW_NONE; + + return theme->shadow_type; +} /* * Expat callback stuff @@ -533,6 +711,7 @@ xml_element_start_cb (void *data, const char *tag, const char **expat_attr) if (!strcmp (tag, "theme")) { + MBWMColor clr; const char ** p = expat_attr; xml_stack_push (&exd->stack, XML_CTX_THEME); @@ -554,6 +733,31 @@ xml_element_start_cb (void *data, const char *tag, const char **expat_attr) exd->theme_type = MB_WM_TYPE_THEME_PNG; #endif } + else if (!strcmp (*p, "clr-shadow")) + { + mb_wm_xml_clr_from_string (&clr, *(p+1)); + exd->color_shadow.r = clr.r; + exd->color_shadow.g = clr.g; + exd->color_shadow.b = clr.b; + exd->color_shadow.a = clr.a; + exd->color_shadow.set = True; + } + else if (!strcmp (*p, "clr-lowlight")) + { + mb_wm_xml_clr_from_string (&clr, *(p+1)); + exd->color_lowlight.r = clr.r; + exd->color_lowlight.g = clr.g; + exd->color_lowlight.b = clr.b; + exd->color_lowlight.a = clr.a; + exd->color_lowlight.set = True; + } + else if (!strcmp (*p, "shadow-type")) + { + if (!strcmp (*(p+1), "simple")) + exd->shadow_type = MBWM_COMP_MGR_SHADOW_SIMPLE; + else if (!strcmp (*(p+1), "gaussian")) + exd->shadow_type = MBWM_COMP_MGR_SHADOW_GAUSSIAN; + } p += 2; } diff --git a/src/theme-engines/mb-wm-theme.h b/src/theme-engines/mb-wm-theme.h index b77dd98..6f69888 100644 --- a/src/theme-engines/mb-wm-theme.h +++ b/src/theme-engines/mb-wm-theme.h @@ -85,17 +85,20 @@ struct MBWMThemeClass MBWMDecor* (*create_decor) (MBWMTheme *theme, MBWindowManagerClient *client, MBWMDecorType type); - }; struct MBWMTheme { - MBWMObject parent; + MBWMObject parent; + + MBWindowManager *wm; + MBWMThemeCaps caps; + char *path; + MBWMList *xml_clients; - MBWindowManager *wm; - MBWMThemeCaps caps; - char *path; - MBWMList *xml_clients; + MBWMColor color_lowlight; + MBWMColor color_shadow; + MBWMCompMgrShadowType shadow_type; }; MBWMTheme * @@ -145,4 +148,22 @@ mb_wm_theme_get_client_geometry (MBWMTheme * theme, MBWindowManagerClient * client, MBGeometry * geom); +void +mb_wm_theme_get_lowlight_color (MBWMTheme * theme, + unsigned int * red, + unsigned int * green, + unsigned int * blue, + unsigned int * alpha); + +void +mb_wm_theme_get_shadow_color (MBWMTheme * theme, + unsigned int * red, + unsigned int * green, + unsigned int * blue, + unsigned int * alpha); + + +MBWMCompMgrShadowType +mb_wm_theme_get_shadow_type (MBWMTheme * theme); + #endif |