diff options
Diffstat (limited to 'matchbox')
-rw-r--r-- | matchbox/Makefile.am | 12 | ||||
-rw-r--r-- | matchbox/mb-window-manager.c | 78 | ||||
-rw-r--r-- | matchbox/mb-window-manager.h | 7 | ||||
-rw-r--r-- | matchbox/mb-wm-comp-mgr-clutter.c | 1679 | ||||
-rw-r--r-- | matchbox/mb-wm-comp-mgr-clutter.h | 108 | ||||
-rw-r--r-- | matchbox/mb-wm-comp-mgr.c | 2 | ||||
-rw-r--r-- | matchbox/tidy/tidy-texture-frame.c | 641 | ||||
-rw-r--r-- | matchbox/tidy/tidy-texture-frame.h | 84 |
8 files changed, 40 insertions, 2571 deletions
diff --git a/matchbox/Makefile.am b/matchbox/Makefile.am index f864097..acc64f3 100644 --- a/matchbox/Makefile.am +++ b/matchbox/Makefile.am @@ -66,18 +66,6 @@ source += \ if ENABLE_COMPOSITE source += mb-wm-comp-mgr.h source += mb-wm-comp-mgr.c - -if COMP_MGR_BACKEND -if ENABLE_CLUTTER_COMPOSITE_MANAGER -source += mb-wm-comp-mgr-clutter.h -source += mb-wm-comp-mgr-clutter.c -source += tidy/tidy-texture-frame.h tidy/tidy-texture-frame.c -else -source += mb-wm-comp-mgr-xrender.h -source += mb-wm-comp-mgr-xrender.c -endif -endif - endif #ENABLE_COMPOSITE # Theming... diff --git a/matchbox/mb-window-manager.c b/matchbox/mb-window-manager.c index 7d1a201..fcc2bee 100644 --- a/matchbox/mb-window-manager.c +++ b/matchbox/mb-window-manager.c @@ -30,18 +30,17 @@ #if ENABLE_COMPOSITE # include "mb-wm-comp-mgr.h" -# if ENABLE_CLUTTER_COMPOSITE_MANAGER -# include <clutter/x11/clutter-x11.h> -# include "mb-wm-comp-mgr-clutter.h" -# else -# include "mb-wm-comp-mgr-xrender.h" -# endif # include "mb-wm-client-override.h" # include <X11/extensions/Xdamage.h> # include <X11/extensions/Xrender.h> # include <X11/extensions/Xcomposite.h> #endif +/* FIXME: libmatchbox shouldn't know anything about clutter */ +#ifdef MANAGER_CLUTTER +#include <clutter/x11/clutter-x11.h> +#endif + #if USE_GTK # include <gdk/gdk.h> #endif @@ -156,18 +155,6 @@ mb_wm_real_theme_new (MBWindowManager * wm, const char * path) return mb_wm_theme_new (wm, path); } -#if ENABLE_COMPOSITE && COMP_MGR_BACKEND -static MBWMCompMgr * -mb_wm_real_comp_mgr_new (MBWindowManager *wm) -{ -#if ENABLE_CLUTTER_COMPOSITE_MANAGER - return mb_wm_comp_mgr_clutter_new (wm); -#else - return mb_wm_comp_mgr_xrender_new (wm); -#endif -} -#endif - static MBWMLayout * mb_wm_layout_new_real (MBWindowManager *wm) { @@ -195,7 +182,8 @@ mb_wm_gdk_xevent_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) } #endif -#if ENABLE_CLUTTER_COMPOSITE_MANAGER +/* FIXME: libmatchbox shouldn't know anything about clutter! */ +#ifdef MANAGER_CLUTTER #if USE_GTK static GdkFilterReturn mb_wm_clutter_gdk_xevent_filter (GdkXEvent *xevent, GdkEvent *event, @@ -230,14 +218,14 @@ mb_wm_clutter_xevent_filter (XEvent *xev, ClutterEvent *cev, gpointer data) #endif #endif -#if ENABLE_CLUTTER_COMPOSITE_MANAGER || USE_GTK +#if MANAGER_CLUTTER || USE_GTK static void mb_wm_main_real (MBWindowManager *wm) { #if USE_GTK gdk_window_add_filter (NULL, mb_wm_gdk_xevent_filter, wm); -#if ENABLE_CLUTTER_COMPOSITE_MANAGER +#if MANAGER_CLUTTER gdk_window_add_filter (NULL, mb_wm_clutter_gdk_xevent_filter, NULL); #endif gtk_main (); @@ -264,14 +252,10 @@ mb_wm_class_init (MBWMObjectClass *klass) wm_class->layout_new = mb_wm_layout_new_real; wm_class->get_desktop_geometry = mb_wm_real_get_desktop_geometry; -#if ENABLE_CLUTTER_COMPOSITE_MANAGER +#if MANAGER_CLUTTER wm_class->main = mb_wm_main_real; #endif -#if ENABLE_COMPOSITE && COMP_MGR_BACKEND - wm_class->comp_mgr_new = mb_wm_real_comp_mgr_new; -#endif - #if MBWM_WANT_DEBUG klass->klass_name = "MBWindowManager"; #endif @@ -1255,7 +1239,7 @@ mb_wm_main_loop(MBWindowManager *wm) MBWindowManagerClass * wm_class = MB_WINDOW_MANAGER_CLASS (MB_WM_OBJECT_GET_CLASS (wm)); -#if !ENABLE_CLUTTER_COMPOSITE_MANAGER +#if !MANAGER_CLUTTER if (!wm_class->main) { GMainLoop * loop = g_main_loop_new (NULL, FALSE); @@ -1517,8 +1501,8 @@ mb_wm_init_comp_extensions (MBWindowManager *wm) * This function must be called before the MBWindowManager object can be * used. */ -void -mb_wm_init (MBWindowManager * wm) +static void +_mb_wm_init (MBWindowManager * wm, MBWMCompMgr *compositor) { MBWindowManagerClass *wm_class; @@ -1531,8 +1515,13 @@ mb_wm_init (MBWindowManager * wm) mb_wm_set_layout (wm, wm_class->layout_new (wm)); #if ENABLE_COMPOSITE - if (wm_class->comp_mgr_new && mb_wm_theme_use_compositing_mgr (wm->theme)) - mb_wm_compositing_on (wm); + if (compositor) + { + wm->comp_mgr = mb_wm_object_ref (MB_WM_OBJECT (compositor)); + + if (mb_wm_theme_use_compositing_mgr (wm->theme)) + mb_wm_compositing_on (wm); + } #endif mb_wm_manage_preexistsing_wins (wm); @@ -1547,6 +1536,19 @@ mb_wm_init (MBWindowManager * wm) wm->sync_type |= MBWMSyncStacking; } +void +mb_wm_init (MBWindowManager *window_manager) +{ + _mb_wm_init (window_manager, NULL); +} + +void +mb_wm_init_with_compositor (MBWindowManager *window_manager, + MBWMCompMgr *compositor) +{ + _mb_wm_init (window_manager, compositor); +} + static int mb_window_manager_init (MBWMObject *this, va_list vap) @@ -2158,24 +2160,14 @@ mb_wm_set_cursor (MBWindowManager * wm, MBWindowManagerCursor cursor) } void -mb_wm_compositing_on (MBWindowManager * wm) +mb_wm_compositing_on (MBWindowManager *wm) { #if ENABLE_COMPOSITE - MBWindowManagerClass *wm_class = - MB_WINDOW_MANAGER_CLASS (MB_WM_OBJECT_GET_CLASS (wm)); - - if (!wm->comp_mgr && wm_class->comp_mgr_new) - wm->comp_mgr = wm_class->comp_mgr_new (wm); - if (wm->comp_mgr && !mb_wm_comp_mgr_enabled (wm->comp_mgr)) - { - mb_wm_comp_mgr_turn_on (wm->comp_mgr); - XSync (wm->xdpy, False); - } + mb_wm_comp_mgr_turn_on (wm->comp_mgr); #endif } - void mb_wm_compositing_off (MBWindowManager * wm) { diff --git a/matchbox/mb-window-manager.h b/matchbox/mb-window-manager.h index 5c72845..da9ddde 100644 --- a/matchbox/mb-window-manager.h +++ b/matchbox/mb-window-manager.h @@ -135,10 +135,6 @@ struct MBWindowManagerClass MBWMTheme * (*theme_new) (MBWindowManager *wm, const char * path); -#if ENABLE_COMPOSITE - MBWMCompMgr * (*comp_mgr_new) (MBWindowManager *wm); -#endif - void (*get_desktop_geometry) (MBWindowManager *wm, MBGeometry *geom); void (*main) (MBWindowManager *wm); @@ -164,6 +160,9 @@ void mb_wm_init (MBWindowManager * wm); void +mb_wm_init_with_compositor (MBWindowManager * wm, MBWMCompMgr *compositor); + +void mb_wm_set_layout (MBWindowManager *wm, MBWMLayout *layout); int diff --git a/matchbox/mb-wm-comp-mgr-clutter.c b/matchbox/mb-wm-comp-mgr-clutter.c deleted file mode 100644 index eea78ce..0000000 --- a/matchbox/mb-wm-comp-mgr-clutter.c +++ /dev/null @@ -1,1679 +0,0 @@ -/* - * Matchbox Window Manager - A lightweight window manager not for the - * desktop. - * - * Authored By Tomas Frydrych <tf@o-hand.com> - * - * Copyright (c) 2008 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 "matchbox.h" -#include "mb-wm-client.h" -#include "mb-wm-comp-mgr.h" -#include "mb-wm-comp-mgr-clutter.h" -#include "mb-wm-theme.h" -#include "tidy/tidy-texture-frame.h" - -#include <clutter/clutter.h> -#include <clutter/x11/clutter-x11.h> -#if HAVE_CLUTTER_GLX -#include <clutter/glx/clutter-glx-texture-pixmap.h> -#endif -#include <X11/Xresource.h> -#include <X11/extensions/shape.h> -#include <X11/extensions/Xcomposite.h> - -#include <math.h> - -#define SHADOW_RADIUS 4 -#define SHADOW_OPACITY 0.9 -#define SHADOW_OFFSET_X (-SHADOW_RADIUS) -#define SHADOW_OFFSET_Y (-SHADOW_RADIUS) - -#define MAX_TILE_SZ 16 /* make sure size/2 < MAX_TILE_SZ */ -#define WIDTH (3*MAX_TILE_SZ) -#define HEIGHT (3*MAX_TILE_SZ) - -static unsigned char * -mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile (); - -static void -mb_wm_comp_mgr_clutter_add_actor (MBWMCompMgrClutter *, - MBWMCompMgrClutterClient *); - -/* - * A helper object to store manager's per-client data - */ -struct _MBWMCompMgrClutterClientPrivate -{ - ClutterActor * actor; /* Overall actor */ - ClutterActor * texture; /* The texture part of our actor */ - Pixmap pixmap; - int pxm_width; - int pxm_height; - int pxm_depth; - unsigned int flags; - Damage damage; -}; - -static void -mb_wm_comp_mgr_clutter_client_show_real (MBWMCompMgrClient * client); - -static void -mb_wm_comp_mgr_clutter_client_hide_real (MBWMCompMgrClient * client); - -static void -mb_wm_comp_mgr_clutter_client_repair_real (MBWMCompMgrClient * client); - -static void -mb_wm_comp_mgr_clutter_client_configure_real (MBWMCompMgrClient * client); - -static void -mb_wm_comp_mgr_clutter_client_class_init (MBWMObjectClass *klass) -{ - MBWMCompMgrClientClass *c_klass = MB_WM_COMP_MGR_CLIENT_CLASS (klass); - - c_klass->show = mb_wm_comp_mgr_clutter_client_show_real; - c_klass->hide = mb_wm_comp_mgr_clutter_client_hide_real; - c_klass->repair = mb_wm_comp_mgr_clutter_client_repair_real; - c_klass->configure = mb_wm_comp_mgr_clutter_client_configure_real; - -#if MBWM_WANT_DEBUG - klass->klass_name = "MBWMCompMgrClutterClient"; -#endif -} - -/* - * Fetch the entire texture for our client - */ -static void -mb_wm_comp_mgr_clutter_fetch_texture (MBWMCompMgrClient *client) -{ - MBWMCompMgrClutterClient *cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT(client); - MBWindowManagerClient *wm_client = client->wm_client; - MBWindowManager *wm = client->wm; - MBGeometry geom; - Window xwin; - Window root; - int x, y, w, h, bw, depth; -#ifdef HAVE_XEXT - /* Stuff we need for shaped windows */ - XRectangle *shp_rect; - int shp_order; - int shp_count; - int i; - - /* - * This is square of 32-bit comletely transparent values we use to - * clear bits of the texture from shaped windows; the size is a compromise - * between how much memory we want to allocate and how much tiling we are - * happy with. - * - * Make this power of 2 for efficient operation - */ -#define SHP_CLEAR_SIZE 4 - static int clear_init = 0; - static guint32 clear_data[SHP_CLEAR_SIZE * SHP_CLEAR_SIZE]; - - if (!clear_init) - { - memset (&clear_data, 0, sizeof (clear_data)); - clear_init = 1; - } -#endif - - if (!(cclient->priv->flags & MBWMCompMgrClutterClientMapped)) - return; - - xwin = - wm_client->xwin_frame ? wm_client->xwin_frame : wm_client->window->xwindow; - - if (cclient->priv->pixmap) - XFreePixmap (wm->xdpy, cclient->priv->pixmap); - - cclient->priv->pixmap = XCompositeNameWindowPixmap (wm->xdpy, xwin); - - if (!cclient->priv->pixmap) - return; - - XGetGeometry (wm->xdpy, cclient->priv->pixmap, &root, - &x, &y, &w, &h, &bw, &depth); - - mb_wm_client_get_coverage (wm_client, &geom); - - cclient->priv->pxm_width = w; - cclient->priv->pxm_height = h; - cclient->priv->pxm_depth = depth; - - clutter_actor_set_position (cclient->priv->actor, geom.x, geom.y); - clutter_actor_set_size (cclient->priv->texture, geom.width, geom.height); - - clutter_x11_texture_pixmap_set_pixmap ( - CLUTTER_X11_TEXTURE_PIXMAP (cclient->priv->texture), - cclient->priv->pixmap); - -#ifdef HAVE_XEXT - /* - * If the client is shaped, we have to manually clear any pixels in our - * texture in the non-visible areas. - */ - if (mb_wm_theme_is_client_shaped (wm->theme, wm_client)) - { - shp_rect = XShapeGetRectangles (wm->xdpy, xwin, - ShapeBounding, &shp_count, &shp_order); - - if (shp_rect && shp_count) - { - XserverRegion clear_rgn; - XRectangle rect; - XRectangle * clear_rect; - int clear_count; - - XRectangle *r0, r1; - int c; - - rect.x = 0; - rect.y = 0; - rect.width = geom.width; - rect.height = geom.height; - - clear_rgn = XFixesCreateRegion (wm->xdpy, shp_rect, shp_count); - - XFixesInvertRegion (wm->xdpy, clear_rgn, &rect, clear_rgn); - - clear_rect = XFixesFetchRegion (wm->xdpy, clear_rgn, &clear_count); - - for (i = 0; i < clear_count; ++i) - { - int k, l; - - for (k = 0; k < clear_rect[i].width; k += SHP_CLEAR_SIZE) - for (l = 0; l < clear_rect[i].height; l += SHP_CLEAR_SIZE) - { - int w1 = clear_rect[i].width - k; - int h1 = clear_rect[i].height - l; - - if (w1 > SHP_CLEAR_SIZE) - w1 = SHP_CLEAR_SIZE; - - if (h1 > SHP_CLEAR_SIZE) - h1 = SHP_CLEAR_SIZE; - - clutter_texture_set_area_from_rgb_data ( - CLUTTER_TEXTURE (cclient->priv->texture), - (const guchar *)&clear_data, - TRUE, - clear_rect[i].x + k, - clear_rect[i].y + l, - w1, h1, - SHP_CLEAR_SIZE * 4, - 4, - CLUTTER_TEXTURE_RGB_FLAG_BGR, - NULL); - } - } - - XFixesDestroyRegion (wm->xdpy, clear_rgn); - - XFree (shp_rect); - - if (clear_rect) - XFree (clear_rect); - } - } - -#endif -} - -static int -mb_wm_comp_mgr_clutter_client_init (MBWMObject *obj, va_list vap) -{ - MBWMCompMgrClutterClient *cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (obj); - - cclient->priv = - mb_wm_util_malloc0 (sizeof (MBWMCompMgrClutterClientPrivate)); - - return 1; -} - -static void -mb_wm_comp_mgr_clutter_client_destroy (MBWMObject* obj) -{ - MBWMCompMgrClient * c = MB_WM_COMP_MGR_CLIENT (obj); - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (obj); - MBWindowManager * wm = c->wm; - MBWMCompMgrClutter * mgr = MB_WM_COMP_MGR_CLUTTER (wm->comp_mgr); - int i; - - if (cclient->priv->actor) - clutter_actor_destroy (cclient->priv->actor); - - if (cclient->priv->pixmap) - XFreePixmap (wm->xdpy, cclient->priv->pixmap); - - if (cclient->priv->damage) - XDamageDestroy (wm->xdpy, cclient->priv->damage); - - free (cclient->priv); -} - -int -mb_wm_comp_mgr_clutter_client_class_type () -{ - static int type = 0; - - if (UNLIKELY(type == 0)) - { - static MBWMObjectClassInfo info = { - sizeof (MBWMCompMgrClutterClientClass), - sizeof (MBWMCompMgrClutterClient), - mb_wm_comp_mgr_clutter_client_init, - mb_wm_comp_mgr_clutter_client_destroy, - mb_wm_comp_mgr_clutter_client_class_init - }; - - type = - mb_wm_object_register_class (&info, MB_WM_TYPE_COMP_MGR_CLIENT, 0); - } - - return type; -} - -/* - * This is a private method, hence static (all instances of this class are - * created automatically by the composite manager). - */ -static MBWMCompMgrClient * -mb_wm_comp_mgr_clutter_client_new (MBWindowManagerClient * client) -{ - MBWMObject *c; - - c = mb_wm_object_new (MB_WM_TYPE_COMP_MGR_CLUTTER_CLIENT, - MBWMObjectPropClient, client, - NULL); - - return MB_WM_COMP_MGR_CLIENT (c); -} - -static void -mb_wm_comp_mgr_clutter_client_hide_real (MBWMCompMgrClient * client) -{ - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (client); - - /* - * Do not hide the actor if effect is in progress - */ - if (cclient->priv->flags & MBWMCompMgrClutterClientEffectRunning) - return; - - clutter_actor_hide (cclient->priv->actor); -} - -static void -mb_wm_comp_mgr_clutter_client_show_real (MBWMCompMgrClient * client) -{ - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (client); - - if (!cclient->priv->actor) - { - /* - * This can happen if show() is called on our client before it is - * actually mapped (we only alocate the actor in response to map - * notification. - */ - return; - } - - /* - * Clear the don't update flag, if set - */ - cclient->priv->flags &= ~MBWMCompMgrClutterClientDontUpdate; - clutter_actor_show_all (cclient->priv->actor); -} - -void -mb_wm_comp_mgr_clutter_client_set_flags (MBWMCompMgrClutterClient *cclient, - MBWMCompMgrClutterClientFlags flags) -{ - cclient->priv->flags |= flags; -} - - -void -mb_wm_comp_mgr_clutter_client_unset_flags (MBWMCompMgrClutterClient *cclient, - MBWMCompMgrClutterClientFlags flags) -{ - cclient->priv->flags &= ~flags; -} - -MBWMCompMgrClutterClientFlags -mb_wm_comp_mgr_clutter_client_get_flags (MBWMCompMgrClutterClient *cclient) -{ - return (MBWMCompMgrClutterClientFlags) cclient->priv->flags; -} - - -/* - * MBWMCompMgrClutterClientEventEffect - */ -typedef struct MBWMCompMgrClutterClientEventEffect -{ - ClutterTimeline *timeline; - ClutterBehaviour *behaviour; /* can be either behaviour or effect */ -} MBWMCompMgrClutterClientEventEffect; - -static void -mb_wm_comp_mgr_clutter_client_event_free (MBWMCompMgrClutterClientEventEffect * effect) -{ - g_object_unref (effect->timeline); - g_object_unref (effect->behaviour); - - free (effect); -} - -struct completed_cb_data -{ - gulong my_id; - MBWMCompMgrClutterClient * cclient; - MBWMCompMgrClientEvent event; - MBWMCompMgrClutterClientEventEffect * effect; -}; - -ClutterActor * -mb_wm_comp_mgr_clutter_client_get_actor (MBWMCompMgrClutterClient *cclient) -{ - return g_object_ref(MB_WM_OBJECT (cclient->priv->actor)); -} - -static MBWMCompMgrClutterClientEventEffect * -mb_wm_comp_mgr_clutter_client_event_new (MBWMCompMgrClient *client, - MBWMCompMgrClientEvent event, - unsigned long duration) -{ - MBWMCompMgrClutterClientEventEffect * eff; - ClutterTimeline * timeline; - ClutterBehaviour * behaviour; - ClutterAlpha * alpha; - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (client); - MBWindowManager * wm = client->wm; - ClutterPath * path; - MBGeometry geom; - - if (!cclient->priv->actor) - return NULL; - - timeline = clutter_timeline_new (duration); - - if (!timeline) - return NULL; - - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - - mb_wm_client_get_coverage (client->wm_client, &geom); - - switch (event) - { - case MBWMCompMgrClientEventMinimize: - behaviour = - clutter_behaviour_scale_new (alpha, 1.0, 1.0, 0, 0); - break; - case MBWMCompMgrClientEventUnmap: - behaviour = clutter_behaviour_opacity_new (alpha, 0xff, 0); - break; - case MBWMCompMgrClientEventMap: - path = clutter_path_new (); - clutter_path_add_move_to (path, -wm->xdpy_width, geom.y); - clutter_path_add_line_to (path, geom.x, geom.y); - behaviour = clutter_behaviour_path_new (alpha, path); - break; - } - - eff = mb_wm_util_malloc0 (sizeof (MBWMCompMgrClutterClientEventEffect)); - eff->timeline = timeline; - eff->behaviour = behaviour; - - clutter_behaviour_apply (behaviour, cclient->priv->actor); - - return eff; -} - -/* - * Implementation of MBWMCompMgrClutter - */ -struct _MBWMCompMgrClutterPrivate -{ - ClutterActor * arena; - MBWMList * desktops; - ClutterActor * shadow; - - Window overlay_window; -}; - -static void -mb_wm_comp_mgr_clutter_private_free (MBWMCompMgrClutter *mgr) -{ - MBWMCompMgrClutterPrivate * priv = mgr->priv; - - if (priv->shadow) - clutter_actor_destroy (priv->shadow); - - free (priv); -} - -static void -mb_wm_comp_mgr_clutter_register_client_real (MBWMCompMgr * mgr, - MBWindowManagerClient * c) -{ - MBWMCompMgrClient *cclient; - MBWMCompMgrClutter *cmgr = MB_WM_COMP_MGR_CLUTTER (mgr); - MBWMCompMgrClutterClass *klass - = MB_WM_COMP_MGR_CLUTTER_CLASS (MB_WM_OBJECT_GET_CLASS (mgr)); - - if (c->cm_client) - return; - - cclient = klass->client_new (c); - c->cm_client = cclient; -} - -static void -mb_wm_comp_mgr_clutter_turn_on_real (MBWMCompMgr *mgr); - -static void -mb_wm_comp_mgr_clutter_turn_off_real (MBWMCompMgr *mgr); - -static void -mb_wm_comp_mgr_clutter_map_notify_real (MBWMCompMgr *mgr, - MBWindowManagerClient *c); - -static void -mb_wm_comp_mgr_clutter_client_transition_real (MBWMCompMgr * mgr, - MBWindowManagerClient *c1, - MBWindowManagerClient *c2, - Bool reverse); - -static void -mb_wm_comp_mgr_clutter_client_event_real (MBWMCompMgr * mgr, - MBWindowManagerClient * client, - MBWMCompMgrClientEvent event); - -static void -mb_wm_comp_mgr_clutter_restack_real (MBWMCompMgr *mgr); - -static Bool -mb_wm_comp_mgr_is_my_window_real (MBWMCompMgr * mgr, Window xwin); - -static void -mb_wm_comp_mgr_clutter_select_desktop (MBWMCompMgr * mgr, - int desktop, int old_desktop); - -static Bool -mb_wm_comp_mgr_clutter_handle_damage (XDamageNotifyEvent * de, - MBWMCompMgr * mgr); - -static void -mb_wm_comp_mgr_clutter_class_init (MBWMObjectClass *klass) -{ - MBWMCompMgrClass *cm_klass = MB_WM_COMP_MGR_CLASS (klass); - MBWMCompMgrClutterClass *clutter_klass = - MB_WM_COMP_MGR_CLUTTER_CLASS (klass); - -#if MBWM_WANT_DEBUG - klass->klass_name = "MBWMCompMgrClutter"; -#endif - - /* - * NB -- we do not need render() implementation, since that is taken care of - * automatically by clutter stage. - */ - cm_klass->register_client = mb_wm_comp_mgr_clutter_register_client_real; - cm_klass->turn_on = mb_wm_comp_mgr_clutter_turn_on_real; - cm_klass->turn_off = mb_wm_comp_mgr_clutter_turn_off_real; - cm_klass->map_notify = mb_wm_comp_mgr_clutter_map_notify_real; - cm_klass->my_window = mb_wm_comp_mgr_is_my_window_real; - cm_klass->client_transition = mb_wm_comp_mgr_clutter_client_transition_real; - cm_klass->client_event = mb_wm_comp_mgr_clutter_client_event_real; - cm_klass->restack = mb_wm_comp_mgr_clutter_restack_real; - cm_klass->select_desktop = mb_wm_comp_mgr_clutter_select_desktop; - cm_klass->handle_damage = mb_wm_comp_mgr_clutter_handle_damage; - - clutter_klass->client_new = mb_wm_comp_mgr_clutter_client_new; -} - -static int -mb_wm_comp_mgr_clutter_init (MBWMObject *obj, va_list vap) -{ - MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); - MBWMCompMgrClutter * cmgr = MB_WM_COMP_MGR_CLUTTER (obj); - MBWMCompMgrClutterPrivate * priv; - MBWindowManager * wm = mgr->wm; - ClutterActor * desktop, * arena; - - priv = mb_wm_util_malloc0 (sizeof (MBWMCompMgrClutterPrivate)); - cmgr->priv = priv; - - XCompositeRedirectSubwindows (wm->xdpy, wm->root_win->xwindow, - CompositeRedirectManual); - - priv->arena = arena = clutter_group_new (); - clutter_container_add_actor (CLUTTER_CONTAINER (clutter_stage_get_default()), - arena); - clutter_actor_show (arena); - - desktop = clutter_group_new (); - clutter_actor_show (desktop); - clutter_container_add_actor (CLUTTER_CONTAINER (arena), desktop); - priv->desktops = mb_wm_util_list_append (priv->desktops, desktop); - - return 1; -} - -static void -mb_wm_comp_mgr_clutter_destroy (MBWMObject * obj) -{ - MBWMCompMgr * mgr = MB_WM_COMP_MGR (obj); - MBWMCompMgrClutter * cmgr = MB_WM_COMP_MGR_CLUTTER (obj); - - mb_wm_comp_mgr_turn_off (mgr); - mb_wm_comp_mgr_clutter_private_free (cmgr); -} - -int -mb_wm_comp_mgr_clutter_class_type () -{ - static int type = 0; - - if (UNLIKELY(type == 0)) - { - static MBWMObjectClassInfo info = { - sizeof (MBWMCompMgrClutterClass), - sizeof (MBWMCompMgrClutter), - mb_wm_comp_mgr_clutter_init, - mb_wm_comp_mgr_clutter_destroy, - mb_wm_comp_mgr_clutter_class_init - }; - - type = mb_wm_object_register_class (&info, MB_WM_TYPE_COMP_MGR, 0); - } - - return type; -} - -/* Shuts the compositing down */ -static void -mb_wm_comp_mgr_clutter_turn_off_real (MBWMCompMgr *mgr) -{ - MBWindowManager * wm = mgr->wm; - MBWMCompMgrClutterPrivate * priv; - - if (!mgr) - return; - - priv = MB_WM_COMP_MGR_CLUTTER (mgr)->priv; - - if (mgr->disabled) - return; - - if (!mb_wm_stack_empty (wm)) - { - MBWindowManagerClient * c; - - mb_wm_stack_enumerate (wm, c) - { - mb_wm_comp_mgr_unregister_client (mgr, c); - } - } - - XCompositeReleaseOverlayWindow (wm->xdpy, wm->root_win->xwindow); - priv->overlay_window = None; - - mgr->disabled = True; -} - -static void -mb_wm_comp_mgr_clutter_turn_on_real (MBWMCompMgr *mgr) -{ - MBWindowManager * wm; - MBWMCompMgrClutterPrivate * priv; - - if (!mgr || !mgr->disabled) - return; - - priv = MB_WM_COMP_MGR_CLUTTER (mgr)->priv; - wm = mgr->wm; - - mgr->disabled = False; - - if (priv->overlay_window == None) - { - ClutterActor * stage = clutter_stage_get_default (); - ClutterColor clr = {0, 0, 0, 0xff }; - Window xwin; - XserverRegion region; - - /* - * Fetch the overlay window - */ - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); - - priv->overlay_window = - XCompositeGetOverlayWindow (wm->xdpy, wm->root_win->xwindow); - - /* - * Reparent the stage window to the overlay window, this makes it - * magically work :) - */ - XReparentWindow (wm->xdpy, xwin, priv->overlay_window, 0, 0); - - /* - * Use xfixes shape to make events pass through the overlay window - * - * TODO -- this has certain drawbacks, notably when our client is - * tranformed (rotated, scaled, etc), the events will not be landing in - * the right place. The answer to that is event forwarding with - * translation. - */ - region = XFixesCreateRegion (wm->xdpy, NULL, 0); - - XFixesSetWindowShapeRegion (wm->xdpy, priv->overlay_window, - ShapeBounding, 0, 0, 0); - XFixesSetWindowShapeRegion (wm->xdpy, priv->overlay_window, - ShapeInput, 0, 0, region); - - XFixesDestroyRegion (wm->xdpy, region); - - clutter_actor_set_size (stage, wm->xdpy_width, wm->xdpy_height); - clutter_stage_set_color (CLUTTER_STAGE (stage), &clr); - - clutter_actor_show (stage); - } -} - -static void -mb_wm_comp_mgr_clutter_client_repair_real (MBWMCompMgrClient * client) -{ - MBWindowManagerClient * wm_client = client->wm_client; - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (client); - MBWindowManager * wm = client->wm; - XserverRegion parts; - int i, r_count; - XRectangle * r_damage; - XRectangle r_bounds; - - MBWM_NOTE (COMPOSITOR, "REPAIRING %x", wm_client->window->xwindow); - - if (!cclient->priv->actor) - return; - - if (!cclient->priv->pixmap) - { - /* - * First time we have been called since creation/configure, - * fetch the whole texture. - */ - MBWM_NOTE (DAMAGE, "Full screen repair."); - XDamageSubtract (wm->xdpy, cclient->priv->damage, None, None); - mb_wm_comp_mgr_clutter_fetch_texture (client); - return; - } - - /* - * Retrieve the damaged region and break it down into individual - * rectangles so we do not have to update the whole shebang. - */ - parts = XFixesCreateRegion (wm->xdpy, 0, 0); - XDamageSubtract (wm->xdpy, cclient->priv->damage, None, parts); - - r_damage = XFixesFetchRegionAndBounds (wm->xdpy, parts, - &r_count, - &r_bounds); - - if (r_damage) - { - for (i = 0; i < r_count; ++i) - { - MBWM_NOTE (DAMAGE, "Repairing %d,%d;%dx%d", - r_damage[i].x, - r_damage[i].y, - r_damage[i].width, - r_damage[i].height); - - clutter_x11_texture_pixmap_update_area ( - CLUTTER_X11_TEXTURE_PIXMAP (cclient->priv->texture), - r_damage[i].x, - r_damage[i].y, - r_damage[i].width, - r_damage[i].height); - } - - XFree (r_damage); - } - - XFixesDestroyRegion (wm->xdpy, parts); -} - -static void -mb_wm_comp_mgr_clutter_client_configure_real (MBWMCompMgrClient * client) -{ - MBWindowManagerClient * wm_client = client->wm_client; - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT (client); - - MBWM_NOTE (COMPOSITOR, "CONFIGURE request"); - - /* - * Release the backing pixmap; we will recreate it next time we get damage - * notification for this window. - */ - if (cclient->priv->pixmap) - { - XFreePixmap (client->wm->xdpy, cclient->priv->pixmap); - cclient->priv->pixmap = None; - } -} - -static Bool -mb_wm_comp_mgr_clutter_handle_damage (XDamageNotifyEvent * de, - MBWMCompMgr * mgr) -{ - MBWMCompMgrClutterPrivate * priv = MB_WM_COMP_MGR_CLUTTER (mgr)->priv; - MBWindowManager * wm = mgr->wm; - MBWindowManagerClient * c; - - c = mb_wm_managed_client_from_frame (wm, de->drawable); - - if (c && c->cm_client) - { - MBWMCompMgrClutterClient *cclient = - MB_WM_COMP_MGR_CLUTTER_CLIENT (c->cm_client); - - if (!cclient->priv->actor || - (cclient->priv->flags & MBWMCompMgrClutterClientDontUpdate)) - return False; - - MBWM_NOTE (COMPOSITOR, - "Reparing window %x, geometry %d,%d;%dx%d; more %d\n", - de->drawable, - de->geometry.x, - de->geometry.y, - de->geometry.width, - de->geometry.height, - de->more); - - mb_wm_comp_mgr_clutter_client_repair_real (c->cm_client); - } - else - { - MBWM_NOTE (COMPOSITOR, "Failed to find client for window %x\n", - de->drawable); - } - - return False; -} - -static void -mb_wm_comp_mgr_clutter_restack_real (MBWMCompMgr *mgr) -{ - MBWindowManager * wm = mgr->wm; - MBWMCompMgrClutter * cmgr = MB_WM_COMP_MGR_CLUTTER (mgr); - MBWMList * l; - int i = 0; - - l = cmgr->priv->desktops; - - if (!mb_wm_stack_empty (wm)) - { - MBWindowManagerClient * c; - - while (l) - { - ClutterActor *desktop = l->data; - ClutterActor * prev = NULL; - - mb_wm_stack_enumerate (wm, c) - { - MBWMCompMgrClutterClient * cc; - ClutterActor * a; - - if (mb_wm_client_get_desktop (c) != i) - continue; - - cc = MB_WM_COMP_MGR_CLUTTER_CLIENT (c->cm_client); - - a = cc->priv->actor; - - if (!a || clutter_actor_get_parent (a) != desktop) - continue; - - clutter_actor_raise (a, prev); - - prev = a; - } - - l = l->next; - ++i; - } - } -} - -MBWMList * -mb_wm_comp_mgr_clutter_get_desktops (MBWMCompMgrClutter *cmgr) -{ - return cmgr->priv->desktops; -} - -/* - * Gets the n-th desktop from our desktop list; if we do not have that many - * desktops, just append new ones. - */ -ClutterActor * -mb_wm_comp_mgr_clutter_get_nth_desktop (MBWMCompMgrClutter * cmgr, int desktop) -{ - MBWMCompMgrClutterPrivate * priv = cmgr->priv; - MBWMList * l = priv->desktops; - int i = 0; - - while (l && i != desktop) - { - ++i; - - if (l->next) - l = l->next; - else - { - /* End of the line -- append new desktop */ - ClutterActor * d = clutter_group_new (); - priv->desktops = mb_wm_util_list_append (priv->desktops, d); - clutter_container_add_actor (CLUTTER_CONTAINER (priv->arena), d); - - l = l->next; - } - } - - return CLUTTER_ACTOR (l->data); -} - -/* - * Returns the arena; this is an intermediate group which contains all the - * other actors the CM uses. The caller of this function holds a reference - * to the returned ClutterActor and must release it once no longer needed. - */ -ClutterActor * -mb_wm_comp_mgr_clutter_get_arena (MBWMCompMgrClutter *cmgr) -{ - MBWMCompMgrClutterPrivate * priv = cmgr->priv; - - return g_object_ref (priv->arena); -} - - -static void -mb_wm_comp_mgr_clutter_select_desktop (MBWMCompMgr * mgr, - int desktop, - int old_desktop) -{ - MBWMCompMgrClutter * cmgr = MB_WM_COMP_MGR_CLUTTER (mgr); - ClutterActor * d; - MBWMList * l; - - d = mb_wm_comp_mgr_clutter_get_nth_desktop (cmgr, desktop); - - l = cmgr->priv->desktops; - - while (l) - { - ClutterActor * a = l->data; - - if (a == d) - clutter_actor_show (a); - else - clutter_actor_hide (a); - - l = l->next; - } -} - -static void -mb_wm_comp_mgr_clutter_map_notify_real (MBWMCompMgr *mgr, - MBWindowManagerClient *c) -{ - MBWMCompMgrClutter * cmgr = MB_WM_COMP_MGR_CLUTTER (mgr); - MBWMCompMgrClient * client = c->cm_client; - MBWMCompMgrClutterClient * cclient = MB_WM_COMP_MGR_CLUTTER_CLIENT(client); - MBWindowManager * wm = client->wm; - ClutterActor * actor; - ClutterActor * texture; - ClutterActor * rect; - MBGeometry geom; - const MBWMList * l; - unsigned int shadow_clr[4]; - ClutterColor shadow_cclr; - MBWMCompMgrShadowType shadow_type; - MBWMClientType ctype = MB_WM_CLIENT_CLIENT_TYPE (c); - - if (mb_wm_client_is_hiding_from_desktop (c)) - { - /* - * We already have the resources, except we have to get a new - * backing pixmap - */ - Window xwin = c->xwin_frame ? c->xwin_frame : c->window->xwindow; - - /* - * FIXME -- Must rebind the pixmap to the texture -- this is not ideal - * since our texture already contains the correct data, but without - * this it will not update. Perhaps we some extension to the clutter - * API is needed here. - */ - mb_wm_comp_mgr_clutter_fetch_texture (client); - - clutter_actor_show (cclient->priv->actor); - return; - } - - /* - * We get called for windows as well as their children, so once we are - * mapped do nothing. - */ - if (cclient->priv->flags & MBWMCompMgrClutterClientMapped) - return; - - cclient->priv->flags |= MBWMCompMgrClutterClientMapped; - - cclient->priv->damage = XDamageCreate (wm->xdpy, - c->xwin_frame ? - c->xwin_frame : - c->window->xwindow, - XDamageReportNonEmpty); - - mb_wm_client_get_coverage (c, &geom); - - actor = g_object_ref (clutter_group_new ()); -#if HAVE_CLUTTER_GLX - texture = clutter_glx_texture_pixmap_new (); -#else - texture = clutter_x11_texture_pixmap_new (); -#endif - clutter_actor_show (texture); - - if (ctype == MBWMClientTypeDialog || - ctype == MBWMClientTypeMenu || - ctype == MBWMClientTypeNote || - ctype == MBWMClientTypeOverride) - { - shadow_type = mb_wm_theme_get_shadow_type (wm->theme); - - if (shadow_type == MBWM_COMP_MGR_SHADOW_NONE) - { - clutter_container_add (CLUTTER_CONTAINER (actor), texture, NULL); - } - else - { - if (shadow_type == MBWM_COMP_MGR_SHADOW_SIMPLE) - { - mb_wm_theme_get_shadow_color (wm->theme, - &shadow_clr[0], - &shadow_clr[1], - &shadow_clr[2], - &shadow_clr[3]); - - shadow_cclr.red = 0xff * shadow_clr[0] / 0xffff; - shadow_cclr.green = 0xff * shadow_clr[1] / 0xffff; - shadow_cclr.blue = 0xff * shadow_clr[2] / 0xffff; - shadow_cclr.alpha = 0xff * shadow_clr[3] / 0xffff; - - rect = clutter_rectangle_new_with_color (&shadow_cclr); - clutter_actor_set_position (rect, 4, 4); - } - else - { - ClutterActor * txt = cmgr->priv->shadow; - if (!txt) - { - unsigned char * data; - - data = mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile (); - - txt = g_object_new (CLUTTER_TYPE_TEXTURE, NULL); - - clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (txt), - data, - TRUE, - WIDTH, - HEIGHT, - WIDTH*4, - 4, - 0, - NULL); - free (data); - - cmgr->priv->shadow = txt; - } - - rect = tidy_texture_frame_new (CLUTTER_TEXTURE (txt), - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ, - MAX_TILE_SZ); - clutter_actor_set_position (rect, - 2*SHADOW_RADIUS, 2*SHADOW_RADIUS); - } - - clutter_actor_set_size (rect, geom.width, geom.height); - clutter_actor_show (rect); - - clutter_container_add (CLUTTER_CONTAINER (actor), - rect, texture, NULL); - } - } - else - { - clutter_container_add (CLUTTER_CONTAINER (actor), texture, NULL); - } - - - cclient->priv->actor = actor; - cclient->priv->texture = texture; - - g_object_set_data (G_OBJECT (actor), "MBWMCompMgrClutterClient", cclient); - - clutter_actor_set_position (actor, geom.x, geom.y); - clutter_actor_set_size (texture, geom.width, geom.height); - - mb_wm_comp_mgr_clutter_add_actor (cmgr, cclient); -} - -struct _fade_cb_data -{ - MBWMCompMgrClutterClient *cclient1; - MBWMCompMgrClutterClient *cclient2; - ClutterTimeline * timeline; - ClutterBehaviour * beh; -}; - -static void -mb_wm_comp_mgr_clutter_transtion_fade_cb (ClutterTimeline * t, void * data) -{ - struct _fade_cb_data * d = data; - ClutterActor * a1 = d->cclient1->priv->actor; - ClutterActor * a2 = d->cclient2->priv->actor; - - clutter_actor_set_opacity (a1, 0xff); - - d->cclient1->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning; - d->cclient2->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning; - - mb_wm_object_unref (MB_WM_OBJECT (d->cclient1)); - mb_wm_object_unref (MB_WM_OBJECT (d->cclient2)); - - g_object_unref (d->timeline); - g_object_unref (d->beh); -} - -static void -_fade_apply_behaviour_to_client (MBWindowManagerClient * wc, - ClutterBehaviour * b) -{ - MBWMList * l; - ClutterActor * a = MB_WM_COMP_MGR_CLUTTER_CLIENT (wc->cm_client)->priv->actor; - - clutter_actor_set_opacity (a, 0); - clutter_behaviour_apply (b, a); - - l = mb_wm_client_get_transients (wc); - while (l) - { - MBWindowManagerClient * c = l->data; - - _fade_apply_behaviour_to_client (c, b); - l = l->next; - } -} - -static void -mb_wm_comp_mgr_clutter_client_transition_fade (MBWMCompMgrClutterClient *cclient1, - MBWMCompMgrClutterClient *cclient2, - unsigned long duration) -{ - ClutterTimeline * timeline; - ClutterAlpha * alpha; - static struct _fade_cb_data cb_data; - ClutterBehaviour * b; - - /* - * Fade is simple -- we only need to animate the second actor and its - * children, as the stacking order automatically takes care of the - * actor appearing to fade out from the first one - */ - timeline = clutter_timeline_new (duration); - - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - - b = clutter_behaviour_opacity_new (alpha, 0xff, 0); - - cb_data.cclient1 = mb_wm_object_ref (MB_WM_OBJECT (cclient1)); - cb_data.cclient2 = mb_wm_object_ref (MB_WM_OBJECT (cclient2)); - cb_data.timeline = timeline; - cb_data.beh = b; - - _fade_apply_behaviour_to_client (MB_WM_COMP_MGR_CLIENT (cclient2)->wm_client, b); - - /* - * Must restore the opacity on the 'from' actor - */ - g_signal_connect (timeline, "completed", - G_CALLBACK (mb_wm_comp_mgr_clutter_transtion_fade_cb), - &cb_data); - - cclient1->priv->flags |= MBWMCompMgrClutterClientEffectRunning; - cclient2->priv->flags |= MBWMCompMgrClutterClientEffectRunning; - - clutter_timeline_start (timeline); -} - -static void -mb_wm_comp_mgr_clutter_client_transition_real (MBWMCompMgr * mgr, - MBWindowManagerClient *c1, - MBWindowManagerClient *c2, - Bool reverse) -{ - MBWMCompMgrClutterClient * cclient1 = - MB_WM_COMP_MGR_CLUTTER_CLIENT (c1->cm_client); - MBWMCompMgrClutterClient * cclient2 = - MB_WM_COMP_MGR_CLUTTER_CLIENT (c2->cm_client); - - mb_wm_comp_mgr_clutter_client_transition_fade (cclient1, - cclient2, - 100); -} - -/* - * Callback for ClutterTimeline::completed signal. - * - * One-off; get connected when the timeline is started, and disconnected - * again when it finishes. - */ -static void -mb_wm_comp_mgr_clutter_client_event_completed_cb (ClutterTimeline * t, void * data) -{ - struct completed_cb_data * d = data; - - d->cclient->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning; - - g_signal_handler_disconnect (t, d->my_id); - - switch (d->event) - { - case MBWMCompMgrClientEventUnmap: - case MBWMCompMgrClientEventMinimize: - clutter_actor_hide (d->cclient->priv->actor); - break; - - default: - break; - } - - /* - * Release the extra reference on the CM client that was added for the sake - * of the effect - */ - mb_wm_object_unref (MB_WM_OBJECT (d->cclient)); - - mb_wm_comp_mgr_clutter_client_event_free (d->effect); - - free (d); -} - -static void -mb_wm_comp_mgr_clutter_client_event_real (MBWMCompMgr * mgr, - MBWindowManagerClient * client, - MBWMCompMgrClientEvent event) -{ - MBWMCompMgrClutterClientEventEffect * eff; - MBWMCompMgrClutterClient * cclient = - MB_WM_COMP_MGR_CLUTTER_CLIENT (client->cm_client); - - if (MB_WM_CLIENT_CLIENT_TYPE (client) != MBWMClientTypeApp) - return; - - eff = mb_wm_comp_mgr_clutter_client_event_new (client->cm_client, - event, 600); - - if (eff) - { - ClutterActor *a; - Bool dont_run = False; - - a = cclient->priv->actor; - - if (CLUTTER_IS_BEHAVIOUR_PATH (eff->behaviour)) - { - /* - * At this stage, if the actor is not yet visible, move it to - * the starting point of the path (this is mostly because of - * 'map' effects, where the clutter_actor_show () is delayed - * until this point, so that the actor can be positioned in the - * correct location without visible artefacts). - * - * FIXME -- this is very clumsy; we need clutter API to query - * the first knot of the path to avoid messing about with copies - * of the list. - */ - - ClutterPath *path = - clutter_behaviour_path_get_path ( - CLUTTER_BEHAVIOUR_PATH (eff->behaviour)); - if (path) - { - ClutterKnot k; - clutter_path_get_position (path, 0, &k); - clutter_actor_set_position (a, k.x, k.y); - } - } - - if (event == MBWMCompMgrClientEventUnmap) - { - cclient->priv->flags |= MBWMCompMgrClutterClientDontUpdate; - - if (cclient->priv->flags & MBWMCompMgrClutterClientDone) - dont_run = True; - else - cclient->priv->flags |= MBWMCompMgrClutterClientDone; - } - else if (event == MBWMCompMgrClientEventMinimize) - { - /* - * This is tied specifically to the unmap scale effect (the - * themable version of effects allowed to handle this is a nice - * generic fashion. :-( - */ - clutter_actor_move_anchor_point_from_gravity (a, - CLUTTER_GRAVITY_SOUTH_EAST); - } - - /* - * Make sure the actor is showing (for example with 'map' effects, - * the show() is delayed until the effect had chance to - * set up the actor postion). - */ - if (!dont_run) - { - struct completed_cb_data * d; - - d = mb_wm_util_malloc0 (sizeof (struct completed_cb_data)); - - d->cclient = mb_wm_object_ref (MB_WM_OBJECT (cclient)); - d->event = event; - d->effect = eff; - - d->my_id = g_signal_connect (eff->timeline, "completed", - G_CALLBACK (mb_wm_comp_mgr_clutter_client_event_completed_cb), - d); - - cclient->priv->flags |= MBWMCompMgrClutterClientEffectRunning; - clutter_actor_show (a); - clutter_timeline_start (eff->timeline); - } - else - mb_wm_comp_mgr_clutter_client_event_free (eff); - } -} - -/* - * Our windows which we need the WM to ingore are the overlay and the stage - * window. - */ -static Bool -mb_wm_comp_mgr_is_my_window_real (MBWMCompMgr * mgr, Window xwin) -{ - MBWMCompMgrClutterPrivate * priv = MB_WM_COMP_MGR_CLUTTER (mgr)->priv; - ClutterActor * stage; - - if (priv->overlay_window == xwin) - return True; - - stage = clutter_stage_get_default (); - - if (xwin == clutter_x11_get_stage_window (CLUTTER_STAGE (stage))) - return True; - - return False; -} - -static void -mb_wm_comp_mgr_clutter_add_actor (MBWMCompMgrClutter * cmgr, - MBWMCompMgrClutterClient * cclient) -{ - MBWindowManagerClient * c = MB_WM_COMP_MGR_CLIENT (cclient)->wm_client; - ClutterActor * d; - int desktop = mb_wm_client_get_desktop (c); - - /* - * Sanity check; if the desktop is unset, add to desktop 0. - */ - if (desktop < 0) - desktop = 0; - - d = mb_wm_comp_mgr_clutter_get_nth_desktop (cmgr, desktop); - - clutter_container_add_actor (CLUTTER_CONTAINER (d), cclient->priv->actor); -} - -MBWMCompMgr * -mb_wm_comp_mgr_clutter_new (MBWindowManager *wm) -{ - MBWMObject *mgr; - - mgr = mb_wm_object_new (MB_WM_TYPE_COMP_MGR_CLUTTER, - MBWMObjectPropWm, wm, - NULL); - - return MB_WM_COMP_MGR (mgr); -} - -/* ------------------------------- */ -/* Shadow Generation */ - -typedef struct MBGaussianMap -{ - int size; - double * data; -} MBGaussianMap; - -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_clutter_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_clutter_sum_gaussian (MBGaussianMap * map, double opacity, - int x, int y, int width, int height) -{ - 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; - unsigned int r; - - /* - * 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; - - v *= (opacity * 255.0); - - r = (unsigned int) v; - - return (unsigned char) r; -} - -static unsigned char * -mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile () -{ - unsigned char * data; - int size; - int center; - int x, y; - unsigned char d; - int pwidth, pheight; - double opacity = SHADOW_OPACITY; - static MBGaussianMap * gaussian_map = NULL; - - struct _mypixel - { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - } * _d; - - - if (!gaussian_map) - gaussian_map = - mb_wm_comp_mgr_clutter_make_gaussian_map (SHADOW_RADIUS); - - size = gaussian_map->size; - center = size / 2; - - /* Top & bottom */ - - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - data = mb_wm_util_malloc0 (4 * WIDTH * HEIGHT); - - _d = (struct _mypixel*) data; - - /* N */ - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - center, y - center, - WIDTH, HEIGHT); - for (x = 0; x < pwidth; x++) - { - _d[y*3*pwidth + x + pwidth].r = 0; - _d[y*3*pwidth + x + pwidth].g = 0; - _d[y*3*pwidth + x + pwidth].b = 0; - _d[y*3*pwidth + x + pwidth].a = d; - } - - } - - /* S */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - center, y - center, - WIDTH, HEIGHT); - for (x = 0; x < pwidth; x++) - { - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].a = d; - } - - } - - - /* w */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (x = 0; x < pwidth; x++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x - center, center, - WIDTH, HEIGHT); - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + x].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x].a = d; - } - - } - - /* E */ - for (x = 0; x < pwidth; x++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x - center, center, - WIDTH, HEIGHT); - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].a = d; - } - - } - - /* NW */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x-center, y-center, - WIDTH, HEIGHT); - - _d[y*3*pwidth + x].r = 0; - _d[y*3*pwidth + x].g = 0; - _d[y*3*pwidth + x].b = 0; - _d[y*3*pwidth + x].a = d; - } - - /* SW */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x-center, y-center, - WIDTH, HEIGHT); - - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].a = d; - } - - /* SE */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x-center, y-center, - WIDTH, HEIGHT); - - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].r = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].g = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].b = 0; - _d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) + - 2*pwidth].a = d; - } - - /* NE */ - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - x-center, y-center, WIDTH, HEIGHT); - - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].r = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].g = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].b = 0; - _d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].a = d; - } - - /* center */ - pwidth = MAX_TILE_SZ; - pheight = MAX_TILE_SZ; - - d = mb_wm_comp_mgr_clutter_sum_gaussian (gaussian_map, opacity, - center, center, WIDTH, HEIGHT); - - for (x = 0; x < pwidth; x++) - for (y = 0; y < pheight; y++) - { - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].r = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].g = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].b = 0; - _d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].a = d; - } - - return data; -} - - diff --git a/matchbox/mb-wm-comp-mgr-clutter.h b/matchbox/mb-wm-comp-mgr-clutter.h deleted file mode 100644 index f67f46c..0000000 --- a/matchbox/mb-wm-comp-mgr-clutter.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Matchbox Window Manager - A lightweight window manager not for the - * desktop. - * - * Authored By Tomas Frydrych <tf@o-hand.com> - * - * Copyright (c) 2008 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_CLUTTER_H -#define _HAVE_MB_WM_COMP_MGR_CLUTTER_H - -#include <matchbox/mb-wm-config.h> -#include <clutter/clutter.h> - -#define MB_WM_COMP_MGR_CLUTTER(c) ((MBWMCompMgrClutter*)(c)) -#define MB_WM_COMP_MGR_CLUTTER_CLASS(c) ((MBWMCompMgrClutterClass*)(c)) -#define MB_WM_TYPE_COMP_MGR_CLUTTER (mb_wm_comp_mgr_clutter_class_type ()) - -#define MB_WM_COMP_MGR_CLUTTER_CLIENT(c) ((MBWMCompMgrClutterClient*)(c)) -#define MB_WM_COMP_MGR_CLUTTER_CLIENT_CLASS(c) ((MBWMCompMgrClutterClientClass*)(c)) -#define MB_WM_TYPE_COMP_MGR_CLUTTER_CLIENT (mb_wm_comp_mgr_clutter_client_class_type ()) - -typedef struct _MBWMCompMgrClutter MBWMCompMgrClutter; -typedef struct _MBWMCompMgrClutterClass MBWMCompMgrClutterClass; -typedef struct _MBWMCompMgrClutterPrivate MBWMCompMgrClutterPrivate; - -typedef struct _MBWMCompMgrClutterClient MBWMCompMgrClutterClient; -typedef struct _MBWMCompMgrClutterClientClass MBWMCompMgrClutterClientClass; -typedef struct _MBWMCompMgrClutterClientPrivate MBWMCompMgrClutterClientPrivate; - -typedef enum -{ - MBWMCompMgrClutterClientMapped = (1<<0), - MBWMCompMgrClutterClientDontUpdate = (1<<1), - MBWMCompMgrClutterClientDone = (1<<2), - MBWMCompMgrClutterClientEffectRunning = (1<<3), -} MBWMCompMgrClutterClientFlags; - -struct _MBWMCompMgrClutter -{ - MBWMCompMgr parent; - MBWMCompMgrClutterPrivate *priv; -}; - -struct _MBWMCompMgrClutterClass -{ - MBWMCompMgrClass parent; - - MBWMCompMgrClient * (*client_new) (MBWindowManagerClient * client); -}; - -int -mb_wm_comp_mgr_clutter_class_type (); - -MBWMCompMgr* -mb_wm_comp_mgr_clutter_new (MBWindowManager *wm); - -struct _MBWMCompMgrClutterClient -{ - MBWMCompMgrClient parent; - - MBWMCompMgrClutterClientPrivate *priv; -}; - -struct _MBWMCompMgrClutterClientClass -{ - MBWMCompMgrClientClass parent; -}; - -int -mb_wm_comp_mgr_clutter_client_class_type (); - -ClutterActor * -mb_wm_comp_mgr_clutter_client_get_actor (MBWMCompMgrClutterClient *cclient); - -void -mb_wm_comp_mgr_clutter_client_set_flags (MBWMCompMgrClutterClient *cclient, - MBWMCompMgrClutterClientFlags flags); - -void -mb_wm_comp_mgr_clutter_client_unset_flags (MBWMCompMgrClutterClient *cclient, - MBWMCompMgrClutterClientFlags flags); - -MBWMCompMgrClutterClientFlags -mb_wm_comp_mgr_clutter_client_get_flags (MBWMCompMgrClutterClient *cclient); - -MBWMList * -mb_wm_comp_mgr_clutter_get_desktops (MBWMCompMgrClutter *cmgr); - -ClutterActor * -mb_wm_comp_mgr_clutter_get_nth_desktop (MBWMCompMgrClutter *cmgr, int desktop); - -ClutterActor * -mb_wm_comp_mgr_clutter_get_arena (MBWMCompMgrClutter *cmgr); - -#endif diff --git a/matchbox/mb-wm-comp-mgr.c b/matchbox/mb-wm-comp-mgr.c index 5aa6d6b..fe5afcc 100644 --- a/matchbox/mb-wm-comp-mgr.c +++ b/matchbox/mb-wm-comp-mgr.c @@ -444,6 +444,8 @@ mb_wm_comp_mgr_turn_on (MBWMCompMgr *mgr) wm->damage_event_base + XDamageNotify, (MBWMXEventFunc)klass->handle_damage, mgr); + + XSync (wm->xdpy, False); } void diff --git a/matchbox/tidy/tidy-texture-frame.c b/matchbox/tidy/tidy-texture-frame.c deleted file mode 100644 index 7ba4671..0000000 --- a/matchbox/tidy/tidy-texture-frame.c +++ /dev/null @@ -1,641 +0,0 @@ -/* tidy-texture-frame.h: Expandible texture actor - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:tidy-texture-frame - * @short_description: Stretch a texture to fit the entire allocation - * - * #TidyTextureFrame - * - */ - -#include <cogl/cogl.h> - -#include "tidy-texture-frame.h" - -#define TIDY_PARAM_READABLE \ - (G_PARAM_READABLE | \ - G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) - -#define TIDY_PARAM_READWRITE \ - (G_PARAM_READABLE | G_PARAM_WRITABLE | \ - G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) - -enum -{ - PROP_0, - - PROP_PARENT_TEXTURE, - - PROP_LEFT, - PROP_TOP, - PROP_RIGHT, - PROP_BOTTOM -}; - -G_DEFINE_TYPE (TidyTextureFrame, tidy_texture_frame, CLUTTER_TYPE_ACTOR); - -#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate)) - -struct _TidyTextureFramePrivate -{ - ClutterTexture *parent_texture; - - gfloat left; - gfloat top; - gfloat right; - gfloat bottom; - - CoglHandle material; - - guint needs_paint : 1; -}; - -static void -tidy_texture_frame_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - - if (G_UNLIKELY (priv->parent_texture == NULL)) - { - if (min_width_p) - *min_width_p = 0; - - if (natural_width_p) - *natural_width_p = 0; - } - else - { - ClutterActorClass *klass; - - /* by directly querying the parent texture's class implementation - * we are going around any override mechanism the parent texture - * might have in place, and we ask directly for the original - * preferred width - */ - klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture); - klass->get_preferred_width (CLUTTER_ACTOR (priv->parent_texture), - for_height, - min_width_p, - natural_width_p); - } -} - -static void -tidy_texture_frame_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - - if (G_UNLIKELY (priv->parent_texture == NULL)) - { - if (min_height_p) - *min_height_p = 0; - - if (natural_height_p) - *natural_height_p = 0; - } - else - { - ClutterActorClass *klass; - - /* by directly querying the parent texture's class implementation - * we are going around any override mechanism the parent texture - * might have in place, and we ask directly for the original - * preferred height - */ - klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture); - klass->get_preferred_height (CLUTTER_ACTOR (priv->parent_texture), - for_width, - min_height_p, - natural_height_p); - } -} - -static void -tidy_texture_frame_realize (ClutterActor *self) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - - if (priv->material != COGL_INVALID_HANDLE) - return; - - priv->material = cogl_material_new (); - - CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED); -} - -static void -tidy_texture_frame_unrealize (ClutterActor *self) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - - if (priv->material == COGL_INVALID_HANDLE) - return; - - cogl_handle_unref (priv->material); - priv->material = COGL_INVALID_HANDLE; - - CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED); -} - -static void -tidy_texture_frame_paint (ClutterActor *self) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - CoglHandle cogl_texture = COGL_INVALID_HANDLE; - ClutterActorBox box = { 0, }; - gfloat width, height; - gfloat tex_width, tex_height; - gfloat ex, ey; - gfloat tx1, ty1, tx2, ty2; - guint8 opacity; - - /* no need to paint stuff if we don't have a texture */ - if (G_UNLIKELY (priv->parent_texture == NULL)) - return; - - if (!priv->needs_paint) - return; - - /* parent texture may have been hidden, so need to make sure it gets - * realized - */ - if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture)) - clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture)); - - cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture); - if (cogl_texture == COGL_INVALID_HANDLE) - return; - - tex_width = cogl_texture_get_width (cogl_texture); - tex_height = cogl_texture_get_height (cogl_texture); - - clutter_actor_get_allocation_box (self, &box); - width = box.x2 - box.x1; - height = box.y2 - box.y1; - - tx1 = priv->left / tex_width; - tx2 = (tex_width - priv->right) / tex_width; - ty1 = priv->top / tex_height; - ty2 = (tex_height - priv->bottom) / tex_height; - - ex = width - priv->right; - if (ex < 0) - ex = priv->right; /* FIXME ? */ - - ey = height - priv->bottom; - if (ey < 0) - ey = priv->bottom; /* FIXME ? */ - - opacity = clutter_actor_get_paint_opacity (self); - - g_assert (priv->material != COGL_INVALID_HANDLE); - - /* set the source material using the parent texture's COGL handle */ - cogl_material_set_color4ub (priv->material, opacity, opacity, opacity, opacity); - cogl_material_set_layer (priv->material, 0, cogl_texture); - cogl_set_source (priv->material); - - /* top left corner */ - cogl_rectangle_with_texture_coords (0, 0, priv->left, priv->top, - 0.0, 0.0, - tx1, ty1); - - /* top middle */ - cogl_rectangle_with_texture_coords (priv->left, 0, ex, priv->top, - tx1, 0.0, - tx2, ty1); - - /* top right */ - cogl_rectangle_with_texture_coords (ex, 0, width, priv->top, - tx2, 0.0, - 1.0, ty1); - - /* mid left */ - cogl_rectangle_with_texture_coords (0, priv->top, priv->left, ey, - 0.0, ty1, - tx1, ty2); - - /* center */ - cogl_rectangle_with_texture_coords (priv->left, priv->top, ex, ey, - tx1, ty1, - tx2, ty2); - - /* mid right */ - cogl_rectangle_with_texture_coords (ex, priv->top, width, ey, - tx2, ty1, - 1.0, ty2); - - /* bottom left */ - cogl_rectangle_with_texture_coords (0, ey, priv->left, height, - 0.0, ty2, - tx1, 1.0); - - /* bottom center */ - cogl_rectangle_with_texture_coords (priv->left, ey, ex, height, - tx1, ty2, - tx2, 1.0); - - /* bottom right */ - cogl_rectangle_with_texture_coords (ex, ey, width, height, - tx2, ty2, - 1.0, 1.0); -} - -static inline void -tidy_texture_frame_set_frame_internal (TidyTextureFrame *frame, - gfloat left, - gfloat top, - gfloat right, - gfloat bottom) -{ - TidyTextureFramePrivate *priv = frame->priv; - GObject *gobject = G_OBJECT (frame); - gboolean changed = FALSE; - - g_object_freeze_notify (gobject); - - if (priv->top != top) - { - priv->top = top; - g_object_notify (gobject, "top"); - changed = TRUE; - } - - if (priv->right != right) - { - priv->right = right; - g_object_notify (gobject, "right"); - changed = TRUE; - } - - if (priv->bottom != bottom) - { - priv->bottom = bottom; - g_object_notify (gobject, "bottom"); - changed = TRUE; - } - - if (priv->left != left) - { - priv->left = left; - g_object_notify (gobject, "left"); - changed = TRUE; - } - - if (changed && CLUTTER_ACTOR_IS_VISIBLE (frame)) - clutter_actor_queue_redraw (CLUTTER_ACTOR (frame)); - - g_object_thaw_notify (gobject); -} - -static void -tidy_texture_frame_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TidyTextureFrame *frame = TIDY_TEXTURE_FRAME (gobject); - TidyTextureFramePrivate *priv = frame->priv; - - switch (prop_id) - { - case PROP_PARENT_TEXTURE: - tidy_texture_frame_set_parent_texture (frame, - g_value_get_object (value)); - break; - - case PROP_TOP: - tidy_texture_frame_set_frame_internal (frame, - priv->left, - g_value_get_float (value), - priv->right, - priv->bottom); - break; - - case PROP_RIGHT: - tidy_texture_frame_set_frame_internal (frame, - priv->top, - g_value_get_float (value), - priv->bottom, - priv->left); - break; - - case PROP_BOTTOM: - tidy_texture_frame_set_frame_internal (frame, - priv->top, - priv->right, - g_value_get_float (value), - priv->left); - break; - - case PROP_LEFT: - tidy_texture_frame_set_frame_internal (frame, - priv->top, - priv->right, - priv->bottom, - g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -tidy_texture_frame_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv; - - switch (prop_id) - { - case PROP_PARENT_TEXTURE: - g_value_set_object (value, priv->parent_texture); - break; - - case PROP_LEFT: - g_value_set_float (value, priv->left); - break; - - case PROP_TOP: - g_value_set_float (value, priv->top); - break; - - case PROP_RIGHT: - g_value_set_float (value, priv->right); - break; - - case PROP_BOTTOM: - g_value_set_float (value, priv->bottom); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -tidy_texture_frame_dispose (GObject *gobject) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv; - - if (priv->parent_texture) - { - g_object_unref (priv->parent_texture); - priv->parent_texture = NULL; - } - - if (priv->material) - { - cogl_handle_unref (priv->material); - priv->material = COGL_INVALID_HANDLE; - } - - G_OBJECT_CLASS (tidy_texture_frame_parent_class)->dispose (gobject); -} - -static void -tidy_texture_frame_class_init (TidyTextureFrameClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate)); - - actor_class->get_preferred_width = - tidy_texture_frame_get_preferred_width; - actor_class->get_preferred_height = - tidy_texture_frame_get_preferred_height; - actor_class->realize = tidy_texture_frame_realize; - actor_class->unrealize = tidy_texture_frame_unrealize; - actor_class->paint = tidy_texture_frame_paint; - - gobject_class->set_property = tidy_texture_frame_set_property; - gobject_class->get_property = tidy_texture_frame_get_property; - gobject_class->dispose = tidy_texture_frame_dispose; - - pspec = g_param_spec_object ("parent-texture", - "Parent Texture", - "The parent ClutterTexture", - CLUTTER_TYPE_TEXTURE, - TIDY_PARAM_READWRITE | - G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_PARENT_TEXTURE, pspec); - - pspec = g_param_spec_float ("left", - "Left", - "Left offset", - 0, G_MAXFLOAT, - 0, - TIDY_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_LEFT, pspec); - - pspec = g_param_spec_float ("top", - "Top", - "Top offset", - 0, G_MAXFLOAT, - 0, - TIDY_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_TOP, pspec); - - pspec = g_param_spec_float ("bottom", - "Bottom", - "Bottom offset", - 0, G_MAXFLOAT, - 0, - TIDY_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_BOTTOM, pspec); - - pspec = g_param_spec_float ("right", - "Right", - "Right offset", - 0, G_MAXFLOAT, - 0, - TIDY_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_RIGHT, pspec); -} - -static void -tidy_texture_frame_init (TidyTextureFrame *self) -{ - TidyTextureFramePrivate *priv; - - self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self); - - priv->material = COGL_INVALID_HANDLE; -} - -/** - * tidy_texture_frame_new: - * @texture: a #ClutterTexture or %NULL - * @left: left margin preserving its content - * @top: top margin preserving its content - * @right: right margin preserving its content - * @bottom: bottom margin preserving its content - * - * A #TidyTextureFrame is a specialized texture that efficiently clones - * an area of the given @texture while keeping preserving portions of the - * same texture. - * - * A #TidyTextureFrame can be used to make a rectangular texture fit a - * given size without stretching its borders. - * - * Return value: the newly created #TidyTextureFrame - */ -ClutterActor* -tidy_texture_frame_new (ClutterTexture *texture, - gfloat left, - gfloat top, - gfloat right, - gfloat bottom) -{ - g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL); - - return g_object_new (TIDY_TYPE_TEXTURE_FRAME, - "parent-texture", texture, - "left", left, - "top", top, - "right", right, - "bottom", bottom, - NULL); -} - -ClutterTexture * -tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame) -{ - g_return_val_if_fail (TIDY_IS_TEXTURE_FRAME (frame), NULL); - - return frame->priv->parent_texture; -} - -void -tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame, - ClutterTexture *texture) -{ - TidyTextureFramePrivate *priv; - gboolean was_visible; - - g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame)); - g_return_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture)); - - priv = frame->priv; - - was_visible = CLUTTER_ACTOR_IS_VISIBLE (frame); - - if (priv->parent_texture == texture) - return; - - if (priv->parent_texture) - { - g_object_unref (priv->parent_texture); - priv->parent_texture = NULL; - - if (was_visible) - clutter_actor_hide (CLUTTER_ACTOR (frame)); - } - - if (texture) - { - priv->parent_texture = g_object_ref (texture); - - if (was_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture)) - clutter_actor_show (CLUTTER_ACTOR (frame)); - } - - clutter_actor_queue_relayout (CLUTTER_ACTOR (frame)); - - g_object_notify (G_OBJECT (frame), "parent-texture"); -} - -void -tidy_texture_frame_set_frame (TidyTextureFrame *frame, - gfloat top, - gfloat right, - gfloat bottom, - gfloat left) -{ - g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame)); - - tidy_texture_frame_set_frame_internal (frame, top, right, bottom, left); -} - -void -tidy_texture_frame_get_frame (TidyTextureFrame *frame, - gfloat *top, - gfloat *right, - gfloat *bottom, - gfloat *left) -{ - TidyTextureFramePrivate *priv; - - g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame)); - - priv = frame->priv; - - if (top) - *top = priv->top; - - if (right) - *right = priv->right; - - if (bottom) - *bottom = priv->bottom; - - if (left) - *left = priv->left; -} - -/** - * tidy_texture_frame_set_needs_paint: - * @frame: a #TidyTextureframe - * @needs_paint: if %FALSE, the paint will be skipped - * - * Provides a hint to the texture frame that it is totally obscured - * and doesn't need to be painted. This would typically be called - * by a parent container if it detects the condition prior to - * painting its children and then unset afterwards. - * - * Since it is not supposed to have any effect on display, it does - * not queue a repaint. - */ -void -tidy_texture_frame_set_needs_paint (TidyTextureFrame *frame, - gboolean needs_paint) -{ - TidyTextureFramePrivate *priv; - - g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame)); - - priv = frame->priv; - - priv->needs_paint = needs_paint; -} diff --git a/matchbox/tidy/tidy-texture-frame.h b/matchbox/tidy/tidy-texture-frame.h deleted file mode 100644 index 71dd40c..0000000 --- a/matchbox/tidy/tidy-texture-frame.h +++ /dev/null @@ -1,84 +0,0 @@ -/* tidy-texture-frame.h: Expandible texture actor - * - * Copyright (C) 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _HAVE_TIDY_TEXTURE_FRAME_H -#define _HAVE_TIDY_TEXTURE_FRAME_H - -#include <clutter/clutter.h> - -G_BEGIN_DECLS - -#define TIDY_TYPE_TEXTURE_FRAME (tidy_texture_frame_get_type ()) -#define TIDY_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrame)) -#define TIDY_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) -#define TIDY_IS_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_TEXTURE_FRAME)) -#define TIDY_IS_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_TEXTURE_FRAME)) -#define TIDY_TEXTURE_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) - -typedef struct _TidyTextureFrame TidyTextureFrame; -typedef struct _TidyTextureFramePrivate TidyTextureFramePrivate; -typedef struct _TidyTextureFrameClass TidyTextureFrameClass; - -struct _TidyTextureFrame -{ - /*< private >*/ - ClutterActor parent_instance; - - TidyTextureFramePrivate *priv; -}; - -struct _TidyTextureFrameClass -{ - ClutterActorClass parent_class; - - /* padding for future expansion */ - void (*_clutter_box_1) (void); - void (*_clutter_box_2) (void); - void (*_clutter_box_3) (void); - void (*_clutter_box_4) (void); -}; - -GType tidy_texture_frame_get_type (void) G_GNUC_CONST; -ClutterActor * tidy_texture_frame_new (ClutterTexture *texture, - gfloat top, - gfloat right, - gfloat bottom, - gfloat left); -void tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame, - ClutterTexture *texture); -ClutterTexture *tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame); -void tidy_texture_frame_set_frame (TidyTextureFrame *frame, - gfloat top, - gfloat right, - gfloat bottom, - gfloat left); -void tidy_texture_frame_get_frame (TidyTextureFrame *frame, - gfloat *top, - gfloat *right, - gfloat *bottom, - gfloat *left); - -void tidy_texture_frame_set_needs_paint (TidyTextureFrame *frame, - gboolean needs_paint); - -G_END_DECLS - -#endif /* _HAVE_TIDY_TEXTURE_FRAME_H */ |