diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | matchbox/comp-mgr/Makefile.am | 9 | ||||
-rw-r--r-- | matchbox/comp-mgr/mb-wm-comp-mgr-clutter.c | 710 | ||||
-rw-r--r-- | matchbox/comp-mgr/tidy/tidy-texture-frame.c | 641 | ||||
-rw-r--r-- | matchbox/comp-mgr/tidy/tidy-texture-frame.h | 84 |
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 */ |