aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--matchbox/comp-mgr/Makefile.am9
-rw-r--r--matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c710
-rw-r--r--matchbox/comp-mgr/tidy/tidy-texture-frame.c641
-rw-r--r--matchbox/comp-mgr/tidy/tidy-texture-frame.h84
5 files changed, 825 insertions, 621 deletions
diff --git a/configure.ac b/configure.ac
index 81651bd..1f6a772 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ AC_SUBST(MBWM2_INCDIR)
MBWM2_PKGINCDIR=matchbox-wm-2/$MBWM2_API_VERSION/
AC_SUBST(MBWM2_PKGINCDIR)
-clutter_package=clutter-0.8
+clutter_package="clutter-1.0 >= 1.5.6"
AM_MAINTAINER_MODE
diff --git a/matchbox/comp-mgr/Makefile.am b/matchbox/comp-mgr/Makefile.am
index c4c062f..e0384a6 100644
--- a/matchbox/comp-mgr/Makefile.am
+++ b/matchbox/comp-mgr/Makefile.am
@@ -4,8 +4,13 @@ core_c = mb-wm-comp-mgr.c
if COMP_MGR_BACKEND
if ENABLE_CLUTTER_COMPOSITE_MANAGER
-clutter_h = mb-wm-comp-clutter.h
-clutter_c = mb-wm-comp-mgr-clutter.c
+clutter_h = mb-wm-comp-clutter.h \
+ tidy/tidy-texture-frame.h \
+ $(NULL)
+
+clutter_c = mb-wm-comp-mgr-clutter.c \
+ tidy/tidy-texture-frame.c \
+ $(NULL)
else
xrender_h = mb-wm-comp-mgr-xrender.h
xrender_c = mb-wm-comp-mgr-xrender.c
diff --git a/matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c b/matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c
index 0fd5472..551310c 100644
--- a/matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c
+++ b/matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c
@@ -23,6 +23,7 @@
#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>
@@ -44,13 +45,6 @@
#define WIDTH (3*MAX_TILE_SZ)
#define HEIGHT (3*MAX_TILE_SZ)
-static ClutterActor *
-tidy_texture_frame_new (ClutterTexture *texture,
- gint left,
- gint top,
- gint right,
- gint bottom);
-
static unsigned char *
mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile ();
@@ -370,92 +364,12 @@ mb_wm_comp_mgr_clutter_client_get_flags (MBWMCompMgrClutterClient *cclient)
}
-/*
- * 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;
- ClutterKnot knots[2];
- MBGeometry geom;
-
- if (!cclient->priv->actor)
- return NULL;
-
- timeline = clutter_timeline_new_for_duration (duration);
-
- if (!timeline)
- return NULL;
-
- alpha = clutter_alpha_new_full (timeline,
- CLUTTER_ALPHA_RAMP_INC, NULL, NULL);
-
- mb_wm_client_get_coverage (client->wm_client, &geom);
-
- switch (event)
- {
- case MBWMCompMgrClientEventMinimize:
- behaviour =
- clutter_behaviour_scale_newx (alpha, CFX_ONE, CFX_ONE, 0, 0);
- break;
- case MBWMCompMgrClientEventUnmap:
- behaviour = clutter_behaviour_opacity_new (alpha, 0xff, 0);
- break;
- case MBWMCompMgrClientEventMap:
- knots[0].x = -wm->xdpy_width;
- knots[0].y = geom.y;
- knots[1].x = geom.x;
- knots[1].y = geom.y;
- behaviour = clutter_behaviour_path_new (alpha, &knots[0], 2);
- 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
*/
@@ -1052,7 +966,7 @@ mb_wm_comp_mgr_clutter_map_notify_real (MBWMCompMgr *mgr,
data = mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile ();
- txt = g_object_new (CLUTTER_TYPE_TEXTURE, NULL);
+ txt = clutter_texture_new ();
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (txt),
data,
@@ -1077,7 +991,7 @@ mb_wm_comp_mgr_clutter_map_notify_real (MBWMCompMgr *mgr,
2*SHADOW_RADIUS, 2*SHADOW_RADIUS);
}
- clutter_actor_set_size (rect, geom.width, geom.height);
+ clutter_actor_set_size (rect, geom.width, geom.height);
clutter_actor_show (rect);
clutter_container_add (CLUTTER_CONTAINER (actor),
@@ -1101,49 +1015,44 @@ mb_wm_comp_mgr_clutter_map_notify_real (MBWMCompMgr *mgr,
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)
+mb_wm_comp_mgr_clutter_transtion_fade_out_cb (ClutterAnimation *anim,
+ MBWMCompMgrClutterClient *client)
{
- struct _fade_cb_data * d = data;
- ClutterActor * a1 = d->cclient1->priv->actor;
- ClutterActor * a2 = d->cclient2->priv->actor;
+ client->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning;
- 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);
+#if 0
+ /* FIXME -- see if we need this */
+ mb_wm_object_unref (MB_WM_OBJECT (client));
+#endif
}
static void
-_fade_apply_behaviour_to_client (MBWindowManagerClient * wc,
- ClutterBehaviour * b)
+_fade_apply_behaviour_to_client (MBWindowManagerClient *wc,
+ unsigned long duration)
{
MBWMList * l;
- ClutterActor * a = MB_WM_COMP_MGR_CLUTTER_CLIENT (wc->cm_client)->priv->actor;
+ ClutterActor *a = MB_WM_COMP_MGR_CLUTTER_CLIENT (wc->cm_client)->priv->actor;
+ ClutterAnimation *anim;
clutter_actor_set_opacity (a, 0);
- clutter_behaviour_apply (b, a);
+
+ anim = clutter_actor_animate (a,
+ CLUTTER_EASE_IN_SINE,
+ duration,
+ "opacity", 0xff,
+ wc->cm_client);
+
+ g_signal_connect_after (anim, "completed",
+ G_CALLBACK (mb_wm_comp_mgr_clutter_transtion_fade_out_cb),
+ NULL);
l = mb_wm_client_get_transients (wc);
while (l)
{
MBWindowManagerClient * c = l->data;
- _fade_apply_behaviour_to_client (c, b);
+ _fade_apply_behaviour_to_client (c, duration);
l = l->next;
}
}
@@ -1153,41 +1062,15 @@ mb_wm_comp_mgr_clutter_client_transition_fade (MBWMCompMgrClutterClient *cclient
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_for_duration (duration);
-
- alpha = clutter_alpha_new_full (timeline,
- CLUTTER_ALPHA_RAMP_DEC, NULL, NULL);
-
- 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);
+ _fade_apply_behaviour_to_client (MB_WM_COMP_MGR_CLIENT (cclient2)->wm_client,
+ duration);
}
static void
@@ -1206,41 +1089,32 @@ mb_wm_comp_mgr_clutter_client_transition_real (MBWMCompMgr * mgr,
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)
+mb_wm_comp_mgr_clutter_client_event_completed_hide_cb (ClutterAnimation *anim,
+ MBWMCompMgrClutterClient *client)
{
- 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;
- }
+ client->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning;
+ clutter_actor_hide (client->priv->actor);
+ clutter_actor_set_scale (client->priv->actor, 1.0, 1.0);
/*
* 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_object_unref (MB_WM_OBJECT (client));
+}
- mb_wm_comp_mgr_clutter_client_event_free (d->effect);
+static void
+mb_wm_comp_mgr_clutter_client_event_completed_cb (ClutterAnimation *anim,
+ MBWMCompMgrClutterClient *client)
+{
+ client->priv->flags &= ~MBWMCompMgrClutterClientEffectRunning;
- free (d);
+ /*
+ * Release the extra reference on the CM client that was added for the sake
+ * of the effect
+ */
+ mb_wm_object_unref (MB_WM_OBJECT (client));
}
static void
@@ -1248,96 +1122,62 @@ mb_wm_comp_mgr_clutter_client_event_real (MBWMCompMgr * mgr,
MBWindowManagerClient * client,
MBWMCompMgrClientEvent event)
{
- MBWMCompMgrClutterClientEventEffect * eff;
- MBWMCompMgrClutterClient * cclient =
+ MBWMCompMgrClutterClient * cclient =
MB_WM_COMP_MGR_CLUTTER_CLIENT (client->cm_client);
+ ClutterAnimation *anim = NULL;
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)
+ /* FIXME -- this is where the animation is applied */
+ switch (event)
{
- 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.
- */
-
- GSList * knots =
- clutter_behaviour_path_get_knots (
- CLUTTER_BEHAVIOUR_PATH (eff->behaviour));
-
- if (knots)
- {
- ClutterKnot * k = knots->data;
-
- clutter_actor_set_position (a, k->x, k->y);
-
- g_slist_free (knots);
- }
- }
-
- 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;
+ case MBWMCompMgrClientEventMinimize:
+ mb_wm_object_ref (MB_WM_OBJECT (cclient));
+ cclient->priv->flags |= MBWMCompMgrClutterClientEffectRunning;
+
+ anim = clutter_actor_animate (cclient->priv->actor,
+ CLUTTER_EASE_IN_SINE,
+ 200,
+ "scale-x", 0.0,
+ "scale-y", 0.0,
+ NULL);
+ g_signal_connect_after (anim, "completed",
+ G_CALLBACK (mb_wm_comp_mgr_clutter_client_event_completed_hide_cb ),
+ cclient);
+ break;
+ case MBWMCompMgrClientEventUnmap:
+ mb_wm_object_ref (MB_WM_OBJECT (cclient));
+ cclient->priv->flags |= MBWMCompMgrClutterClientEffectRunning;
+
+ anim = clutter_actor_animate (cclient->priv->actor,
+ CLUTTER_EASE_IN_SINE,
+ 200,
+ "scale-x", 0.0,
+ "scale-y", 0.0,
+ NULL);
+ g_signal_connect_after (anim, "completed",
+ G_CALLBACK (mb_wm_comp_mgr_clutter_client_event_completed_hide_cb ),
+ cclient);
+ break;
+ case MBWMCompMgrClientEventMap:
+ mb_wm_object_ref (MB_WM_OBJECT (cclient));
+ cclient->priv->flags |= MBWMCompMgrClutterClientEffectRunning;
- d->my_id = g_signal_connect (eff->timeline, "completed",
- G_CALLBACK (mb_wm_comp_mgr_clutter_client_event_completed_cb),
- d);
+ clutter_actor_set_scale (cclient->priv->actor, 0.0, 0.0);
+ clutter_actor_show (cclient->priv->actor);
- cclient->priv->flags |= MBWMCompMgrClutterClientEffectRunning;
- clutter_actor_show (a);
- clutter_timeline_start (eff->timeline);
- }
- else
- mb_wm_comp_mgr_clutter_client_event_free (eff);
+ anim = clutter_actor_animate (cclient->priv->actor,
+ CLUTTER_EASE_IN_SINE,
+ 200,
+ "scale-x", 1.0,
+ "scale-y", 1.0,
+ NULL);
+ g_signal_connect_after (anim, "completed",
+ G_CALLBACK (mb_wm_comp_mgr_clutter_client_event_completed_cb ),
+ cclient);
+ break;
+ default:;
}
}
@@ -1688,369 +1528,3 @@ mb_wm_comp_mgr_clutter_shadow_gaussian_make_tile ()
return data;
}
-/*
- * TidyTextureFrame copied from tidy
- */
-#include <cogl/cogl.h>
-
-#define TIDY_PARAM_READWRITE \
- (G_PARAM_READABLE | G_PARAM_WRITABLE | \
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
-
-#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
-{
- ClutterCloneTexture parent;
-
- /*< priv >*/
- TidyTextureFramePrivate *priv;
-};
-
-struct _TidyTextureFrameClass
-{
- ClutterCloneTextureClass parent_class;
-};
-
-enum
- {
- PROP_0,
- PROP_LEFT,
- PROP_TOP,
- PROP_RIGHT,
- PROP_BOTTOM
- };
-
-G_DEFINE_TYPE (TidyTextureFrame,
- tidy_texture_frame,
- CLUTTER_TYPE_CLONE_TEXTURE);
-
-#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate))
-
-struct _TidyTextureFramePrivate
-{
- gint left, top, right, bottom;
-};
-
-static void
-tidy_texture_frame_paint (ClutterActor *self)
-{
- TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
- ClutterCloneTexture *clone_texture = CLUTTER_CLONE_TEXTURE (self);
- ClutterTexture *parent_texture;
- guint width, height;
- guint tex_width, tex_height;
- guint ex, ey;
- ClutterFixed tx1, ty1, tx2, ty2;
- ClutterColor col = { 0xff, 0xff, 0xff, 0xff };
- CoglHandle cogl_texture;
-
- priv = TIDY_TEXTURE_FRAME (self)->priv;
-
- /* no need to paint stuff if we don't have a texture */
- parent_texture = clutter_clone_texture_get_parent_texture (clone_texture);
- if (!parent_texture)
- return;
-
- /* parent texture may have been hidden, so need to make sure it gets
- * realized
- */
- if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture))
- clutter_actor_realize (CLUTTER_ACTOR (parent_texture));
-
- cogl_texture = clutter_texture_get_cogl_texture (parent_texture);
- if (cogl_texture == COGL_INVALID_HANDLE)
- return;
-
- cogl_push_matrix ();
-
- tex_width = cogl_texture_get_width (cogl_texture);
- tex_height = cogl_texture_get_height (cogl_texture);
-
- clutter_actor_get_size (self, &width, &height);
-
- tx1 = CLUTTER_INT_TO_FIXED (priv->left) / tex_width;
- tx2 = CLUTTER_INT_TO_FIXED (tex_width - priv->right) / tex_width;
- ty1 = CLUTTER_INT_TO_FIXED (priv->top) / tex_height;
- ty2 = CLUTTER_INT_TO_FIXED (tex_height - priv->bottom) / tex_height;
-
- col.alpha = clutter_actor_get_paint_opacity (self);
- cogl_color (&col);
-
- ex = width - priv->right;
- if (ex < 0)
- ex = priv->right; /* FIXME ? */
-
- ey = height - priv->bottom;
- if (ey < 0)
- ey = priv->bottom; /* FIXME ? */
-
-#define FX(x) CLUTTER_INT_TO_FIXED(x)
-
- /* top left corner */
- cogl_texture_rectangle (cogl_texture,
- 0,
- 0,
- FX(priv->left), /* FIXME: clip if smaller */
- FX(priv->top),
- 0,
- 0,
- tx1,
- ty1);
-
- /* top middle */
- cogl_texture_rectangle (cogl_texture,
- FX(priv->left),
- FX(priv->top),
- FX(ex),
- 0,
- tx1,
- 0,
- tx2,
- ty1);
-
- /* top right */
- cogl_texture_rectangle (cogl_texture,
- FX(ex),
- 0,
- FX(width),
- FX(priv->top),
- tx2,
- 0,
- CFX_ONE,
- ty1);
-
- /* mid left */
- cogl_texture_rectangle (cogl_texture,
- 0,
- FX(priv->top),
- FX(priv->left),
- FX(ey),
- 0,
- ty1,
- tx1,
- ty2);
-
- /* center */
- cogl_texture_rectangle (cogl_texture,
- FX(priv->left),
- FX(priv->top),
- FX(ex),
- FX(ey),
- tx1,
- ty1,
- tx2,
- ty2);
-
- /* mid right */
- cogl_texture_rectangle (cogl_texture,
- FX(ex),
- FX(priv->top),
- FX(width),
- FX(ey),
- tx2,
- ty1,
- CFX_ONE,
- ty2);
-
- /* bottom left */
- cogl_texture_rectangle (cogl_texture,
- 0,
- FX(ey),
- FX(priv->left),
- FX(height),
- 0,
- ty2,
- tx1,
- CFX_ONE);
-
- /* bottom center */
- cogl_texture_rectangle (cogl_texture,
- FX(priv->left),
- FX(ey),
- FX(ex),
- FX(height),
- tx1,
- ty2,
- tx2,
- CFX_ONE);
-
- /* bottom right */
- cogl_texture_rectangle (cogl_texture,
- FX(ex),
- FX(ey),
- FX(width),
- FX(height),
- tx2,
- ty2,
- CFX_ONE,
- CFX_ONE);
-
-
- cogl_pop_matrix ();
-#undef FX
-}
-
-
-static void
-tidy_texture_frame_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object);
- TidyTextureFramePrivate *priv = ctexture->priv;
-
- switch (prop_id)
- {
- case PROP_LEFT:
- priv->left = g_value_get_int (value);
- break;
- case PROP_TOP:
- priv->top = g_value_get_int (value);
- break;
- case PROP_RIGHT:
- priv->right = g_value_get_int (value);
- break;
- case PROP_BOTTOM:
- priv->bottom = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-tidy_texture_frame_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object);
- TidyTextureFramePrivate *priv = ctexture->priv;
-
- switch (prop_id)
- {
- case PROP_LEFT:
- g_value_set_int (value, priv->left);
- break;
- case PROP_TOP:
- g_value_set_int (value, priv->top);
- break;
- case PROP_RIGHT:
- g_value_set_int (value, priv->right);
- break;
- case PROP_BOTTOM:
- g_value_set_int (value, priv->bottom);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-tidy_texture_frame_class_init (TidyTextureFrameClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- 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;
-
- g_object_class_install_property
- (gobject_class,
- PROP_LEFT,
- g_param_spec_int ("left",
- "left",
- "",
- 0, G_MAXINT,
- 0,
- TIDY_PARAM_READWRITE));
-
- g_object_class_install_property
- (gobject_class,
- PROP_TOP,
- g_param_spec_int ("top",
- "top",
- "",
- 0, G_MAXINT,
- 0,
- TIDY_PARAM_READWRITE));
-
- g_object_class_install_property
- (gobject_class,
- PROP_BOTTOM,
- g_param_spec_int ("bottom",
- "bottom",
- "",
- 0, G_MAXINT,
- 0,
- TIDY_PARAM_READWRITE));
-
- g_object_class_install_property
- (gobject_class,
- PROP_RIGHT,
- g_param_spec_int ("right",
- "right",
- "",
- 0, G_MAXINT,
- 0,
- TIDY_PARAM_READWRITE));
-
- g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate));
-}
-
-static void
-tidy_texture_frame_init (TidyTextureFrame *self)
-{
- TidyTextureFramePrivate *priv;
-
- self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self);
-}
-
-static ClutterActor*
-tidy_texture_frame_new (ClutterTexture *texture,
- gint left,
- gint top,
- gint right,
- gint 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);
-}
diff --git a/matchbox/comp-mgr/tidy/tidy-texture-frame.c b/matchbox/comp-mgr/tidy/tidy-texture-frame.c
new file mode 100644
index 0000000..7ba4671
--- /dev/null
+++ b/matchbox/comp-mgr/tidy/tidy-texture-frame.c
@@ -0,0 +1,641 @@
+/* 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/comp-mgr/tidy/tidy-texture-frame.h b/matchbox/comp-mgr/tidy/tidy-texture-frame.h
new file mode 100644
index 0000000..71dd40c
--- /dev/null
+++ b/matchbox/comp-mgr/tidy/tidy-texture-frame.h
@@ -0,0 +1,84 @@
+/* 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 */