aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--configure.ac25
-rw-r--r--data/themes/Default/theme.xml3
-rw-r--r--src/Makefile.am8
-rw-r--r--src/comp-mgr/Makefile.am9
-rw-r--r--src/comp-mgr/mb-wm-comp-mgr.c1929
-rw-r--r--src/comp-mgr/mb-wm-comp-mgr.h110
-rw-r--r--src/core/Makefile.am5
-rw-r--r--src/core/mb-window-manager.c111
-rw-r--r--src/core/mb-window-manager.h24
-rw-r--r--src/core/mb-wm-atoms.c1
-rw-r--r--src/core/mb-wm-client-base.c63
-rw-r--r--src/core/mb-wm-client-window.c155
-rw-r--r--src/core/mb-wm-client-window.h4
-rw-r--r--src/core/mb-wm-client.c63
-rw-r--r--src/core/mb-wm-client.h14
-rw-r--r--src/core/mb-wm-main-context.c6
-rw-r--r--src/core/mb-wm-object-props.h32
-rw-r--r--src/core/mb-wm-root-window.c27
-rw-r--r--src/core/mb-wm-types.h34
-rw-r--r--src/managers/maemo/Makefile.am38
-rw-r--r--src/managers/simple/Makefile.am31
-rw-r--r--src/theme-engines/mb-wm-theme-cairo.c12
-rw-r--r--src/theme-engines/mb-wm-theme-simple.c10
-rw-r--r--src/theme-engines/mb-wm-theme-xml.c2
-rw-r--r--src/theme-engines/mb-wm-theme-xml.h23
-rw-r--r--src/theme-engines/mb-wm-theme.c224
-rw-r--r--src/theme-engines/mb-wm-theme.h33
28 files changed, 2908 insertions, 128 deletions
diff --git a/ChangeLog b/ChangeLog
index 80f7308..f2baac7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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