diff --git a/.gitignore b/.gitignore index c3d05ec40..53c61b6e8 100644 --- a/.gitignore +++ b/.gitignore @@ -153,6 +153,21 @@ stamp-h1 /tests/conform/test-rectangle-opacity /tests/conform/test-backface-culling /tests/conform/test-binding-pool +/tests/conform/test-text-append-some +/tests/conform/test-text-cache +/tests/conform/test-text-cursor +/tests/conform/test-text-delete-chars +/tests/conform/test-text-delete-text +/tests/conform/test-text-empty +/tests/conform/test-text-event +/tests/conform/test-text-get-chars +/tests/conform/test-text-insert +/tests/conform/test-text-password-char +/tests/conform/test-text-prepend-some +/tests/conform/test-text-set-empty +/tests/conform/test-text-set-text +/tests/conform/test-text-utf8-validation +/tests/micro-bench/test-glyph-perf /tests/micro-bench/test-text /tests/tools/disable-npots.sh /clutter/x11/clutter-x11-enum-types.[ch] diff --git a/clutter/Makefile.am b/clutter/Makefile.am index faa9480cc..ecb3e777f 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -47,6 +47,7 @@ BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES) source_h = \ $(srcdir)/clutter-actor.h \ $(srcdir)/clutter-alpha.h \ + $(srcdir)/clutter-animatable.h \ $(srcdir)/clutter-animation.h \ $(srcdir)/clutter-backend.h \ $(srcdir)/clutter-behaviour.h \ @@ -63,7 +64,6 @@ source_h = \ $(srcdir)/clutter-color.h \ $(srcdir)/clutter-container.h \ $(srcdir)/clutter-deprecated.h \ - $(srcdir)/clutter-effect.h \ $(srcdir)/clutter-event.h \ $(srcdir)/clutter-feature.h \ $(srcdir)/clutter-fixed.h \ @@ -137,6 +137,7 @@ CLEANFILES = $(STAMPFILES) source_c = \ clutter-actor.c \ clutter-alpha.c \ + clutter-animatable.c \ clutter-animation.c \ clutter-backend.c \ clutter-behaviour.c \ @@ -153,7 +154,6 @@ source_c = \ clutter-clone-texture.c \ clutter-color.c \ clutter-container.c \ - clutter-effect.c \ clutter-enum-types.c \ clutter-event.c \ clutter-feature.c \ diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 7d616266e..2f39c4f0c 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -1013,7 +1013,8 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, ClutterVertex *vertex) { ClutterFixed v[4]; - ClutterFixed x, y, z, w; + ClutterUnit x, y, z, w; + fixed_vertex_t tmp; g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor)); @@ -1026,8 +1027,7 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, w = COGL_FIXED_1; /* First we tranform the point using the OpenGL modelview matrix */ - clutter_actor_transform_point_relative (self, ancestor, - &x, &y, &z, &w); + clutter_actor_transform_point_relative (self, ancestor, &x, &y, &z, &w); cogl_get_viewport (v); @@ -1035,12 +1035,12 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, * The w[3] parameter should always be 1.0 here, so we ignore it; otherwise * we would have to divide the original verts with it. */ - vertex->x = - CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((x + COGL_FIXED_0_5), v[2])); - vertex->y = - CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((COGL_FIXED_0_5 - y), v[3])); - vertex->z = - CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((z + COGL_FIXED_0_5), v[2])); + tmp.x = COGL_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (x) + COGL_FIXED_0_5, v[2]); + tmp.y = COGL_FIXED_MUL (COGL_FIXED_0_5 - CLUTTER_UNITS_TO_FIXED (y), v[3]); + tmp.z = COGL_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (z) + COGL_FIXED_0_5, v[2]); + tmp.w = 0; + + fixed_vertex_to_units (&tmp, vertex); } /** @@ -1060,6 +1060,7 @@ clutter_actor_apply_transform_to_point (ClutterActor *self, const ClutterVertex *point, ClutterVertex *vertex) { + ClutterUnit x, y, z, w; ClutterFixed mtx_p[16]; ClutterFixed v[4]; fixed_vertex_t tmp = { 0, }; @@ -1068,13 +1069,18 @@ clutter_actor_apply_transform_to_point (ClutterActor *self, g_return_if_fail (point != NULL); g_return_if_fail (vertex != NULL); - tmp.x = CLUTTER_UNITS_TO_FIXED (vertex->x); - tmp.y = CLUTTER_UNITS_TO_FIXED (vertex->y); - tmp.z = CLUTTER_UNITS_TO_FIXED (vertex->z); - tmp.w = COGL_FIXED_1; + x = point->x; + y = point->y; + z = point->z; + w = CLUTTER_UNITS_FROM_INT (1); /* First we tranform the point using the OpenGL modelview matrix */ - clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &tmp.w); + clutter_actor_transform_point (self, &x, &y, &z, &w); + + tmp.x = CLUTTER_UNITS_TO_FIXED (x); + tmp.y = CLUTTER_UNITS_TO_FIXED (y); + tmp.z = CLUTTER_UNITS_TO_FIXED (z); + tmp.w = CLUTTER_UNITS_TO_FIXED (w); cogl_get_projection_matrix (mtx_p); cogl_get_viewport (v); @@ -3244,8 +3250,9 @@ clutter_actor_get_preferred_width (ClutterActor *self, if (natural_width < min_width) { - g_warning ("Actor of type %s reported a natural width of %d (%d px) " - "lower than min width %d (%d px)", + g_warning ("Actor of type %s reported a natural width " + "of %" CLUTTER_UNITS_FORMAT " (%d px) lower " + "than min width %" CLUTTER_UNITS_FORMAT " (%d px)", G_OBJECT_TYPE_NAME (self), natural_width, CLUTTER_UNITS_TO_DEVICE (natural_width), min_width, CLUTTER_UNITS_TO_DEVICE (min_width)); @@ -3314,8 +3321,9 @@ clutter_actor_get_preferred_height (ClutterActor *self, if (natural_height < min_height) { - g_warning ("Actor of type %s reported a natural height of %d " - "(%d px) lower than min height %d (%d px)", + g_warning ("Actor of type %s reported a natural height " + "of %" CLUTTER_UNITS_FORMAT " (%d px) lower than " + "min height %" CLUTTER_UNITS_FORMAT " (%d px)", G_OBJECT_TYPE_NAME (self), natural_height, CLUTTER_UNITS_TO_DEVICE (natural_height), min_height, CLUTTER_UNITS_TO_DEVICE (min_height)); diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index af962caf1..f6d889982 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -74,10 +74,10 @@ G_BEGIN_DECLS */ #define CLUTTER_ACTOR_UNSET_FLAGS(a,f) (((ClutterActor*)(a))->flags &= ~(f)) -#define CLUTTER_ACTOR_IS_MAPPED(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_MAPPED) -#define CLUTTER_ACTOR_IS_REALIZED(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REALIZED) +#define CLUTTER_ACTOR_IS_MAPPED(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_MAPPED) != FALSE) +#define CLUTTER_ACTOR_IS_REALIZED(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REALIZED) != FALSE) #define CLUTTER_ACTOR_IS_VISIBLE(e) (CLUTTER_ACTOR_IS_MAPPED (e) && CLUTTER_ACTOR_IS_REALIZED (e)) -#define CLUTTER_ACTOR_IS_REACTIVE(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REACTIVE) +#define CLUTTER_ACTOR_IS_REACTIVE(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE) typedef struct _ClutterActorClass ClutterActorClass; typedef struct _ClutterActorBox ClutterActorBox; diff --git a/clutter/clutter-animatable.c b/clutter/clutter-animatable.c new file mode 100644 index 000000000..fb2b88b19 --- /dev/null +++ b/clutter/clutter-animatable.c @@ -0,0 +1,117 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:clutter-animatable + * @short_description: Interface for animatable classes + * + * #ClutterAnimatable is an interface that allows a #GObject class + * to control how a #ClutterAnimation will animate a property. + * + * Each #ClutterAnimatable should implement the animate_property() + * virtual function of the interface to compute the animation state + * between two values of an interval depending on a progress factor, + * expressed as a floating point value. + * + * If a #ClutterAnimatable is animated by a #ClutterAnimation + * instance, the #ClutterAnimation will call + * clutter_animatable_animate_property() passing the name of the + * currently animated property; the initial and final values of + * the animation interval; the progress factor. The #ClutterAnimatable + * implementation should return the computed value for the animated + * property. + * + * #ClutterAnimatable is available since Clutter 1.0 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "clutter-animatable.h" +#include "clutter-debug.h" +#include "clutter-private.h" + +GType +clutter_animatable_get_type (void) +{ + static GType a_type = 0; + + if (G_UNLIKELY (a_type == 0)) + a_type = g_type_register_static_simple (G_TYPE_INTERFACE, + I_("ClutterAnimatable"), + sizeof (ClutterAnimatableIface), + NULL, 0, NULL, 0); + + return a_type; +} + +/** + * clutter_animatable_animate_property: + * @animatable: a #ClutterAnimatable + * @animation: a #ClutterAnimation + * @property_name: the name of the animated property + * @initial_value: the initial value of the animation interval + * @final_value: the final value of the animation interval + * @progress: the progress factor + * @value: return location for the animation value + * + * Calls the animate_property() virtual function for @animatable. + * + * The @initial_value and @final_value #GValues must contain + * the same type; @value must have been initialized to the same + * type of @initial_value and @final_value. + * + * All implementation of the #ClutterAnimatable interface must + * implement this function. + * + * Since: 1.0 + */ +void +clutter_animatable_animate_property (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value) +{ + g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); + g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); + g_return_if_fail (property_name != NULL); + g_return_if_fail (initial_value != NULL && final_value != NULL); + g_return_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID); + g_return_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID); + g_return_if_fail (value != NULL); + g_return_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) && + G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value)); + + CLUTTER_ANIMATABLE_GET_IFACE (animatable)->animate_property (animatable, + animation, + property_name, + initial_value, + final_value, + progress, + value); +} diff --git a/clutter/clutter-animatable.h b/clutter/clutter-animatable.h new file mode 100644 index 000000000..aee717ac4 --- /dev/null +++ b/clutter/clutter-animatable.h @@ -0,0 +1,80 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __CLUTTER_ANIMATABLE_H__ +#define __CLUTTER_ANIMATABLE_H__ + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) +#define CLUTTER_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatable)) +#define CLUTTER_IS_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATABLE)) +#define CLUTTER_ANIMATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatableIface)) + +typedef struct _ClutterAnimatable ClutterAnimatable; /* dummy typedef */ +typedef struct _ClutterAnimatableIface ClutterAnimatableIface; + +/** + * ClutterAnimatableIface: + * @animate_property: virtual function for animating a property + * + * Base interface for #GObjects that can be animated by a + * a #ClutterAnimation. + * + * Since: 1.0 + */ +struct _ClutterAnimatableIface +{ + /*< private >*/ + GTypeInterface parent_iface; + + /*< public >*/ + void (* animate_property) (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); +}; + +GType clutter_animatable_get_type (void) G_GNUC_CONST; + +void clutter_animatable_animate_property (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); + +G_END_DECLS + +#endif /* __CLUTTER_ANIMATABLE_H__ */ diff --git a/clutter/clutter-animation.c b/clutter/clutter-animation.c index eae81250d..fb5f3c48d 100644 --- a/clutter/clutter-animation.c +++ b/clutter/clutter-animation.c @@ -27,12 +27,12 @@ * @short_description: Simple implicit animations * * #ClutterAnimation is an object providing simple, implicit animations - * for #ClutterActors. + * for #GObjects. * * #ClutterAnimation instances will bind a #GObject property belonging - * to a #ClutterActor to a #ClutterInterval, and will then use a - * #ClutterTimeline to interpolate the property between the initial - * and final values of the interval. + * to a #GObject to a #ClutterInterval, and will then use a #ClutterTimeline + * to interpolate the property between the initial and final values of the + * interval. * * For convenience, it is possible to use the clutter_actor_animate() * function call which will take care of setting up and tearing down @@ -50,6 +50,7 @@ #include #include "clutter-alpha.h" +#include "clutter-animatable.h" #include "clutter-animation.h" #include "clutter-debug.h" #include "clutter-enum-types.h" @@ -60,7 +61,7 @@ enum { PROP_0, - PROP_ACTOR, + PROP_OBJECT, PROP_MODE, PROP_DURATION, PROP_LOOP, @@ -79,7 +80,7 @@ enum struct _ClutterAnimationPrivate { - ClutterActor *actor; + GObject *object; GHashTable *properties; @@ -96,7 +97,7 @@ struct _ClutterAnimationPrivate static guint animation_signals[LAST_SIGNAL] = { 0, }; -static GQuark quark_actor_animation = 0; +static GQuark quark_object_animation = 0; G_DEFINE_TYPE (ClutterAnimation, clutter_animation, G_TYPE_INITIALLY_UNOWNED); @@ -118,16 +119,14 @@ clutter_animation_dispose (GObject *gobject) { ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv; - if (priv->actor) + if (priv->object) { g_object_weak_unref (G_OBJECT (gobject), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, - NULL); - g_object_unref (priv->actor); - priv->actor = NULL; + priv->object); + g_object_set_qdata (priv->object, quark_object_animation, NULL); + g_object_unref (priv->object); + priv->object = NULL; } if (priv->timeline) @@ -168,8 +167,8 @@ clutter_animation_set_property (GObject *gobject, switch (prop_id) { - case PROP_ACTOR: - clutter_animation_set_actor (animation, g_value_get_object (value)); + case PROP_OBJECT: + clutter_animation_set_object (animation, g_value_get_object (value)); break; case PROP_MODE: @@ -208,8 +207,8 @@ clutter_animation_get_property (GObject *gobject, switch (prop_id) { - case PROP_ACTOR: - g_value_set_object (value, priv->actor); + case PROP_OBJECT: + g_value_set_object (value, priv->object); break; case PROP_MODE: @@ -253,7 +252,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - quark_actor_animation = + quark_object_animation = g_quark_from_static_string ("clutter-actor-animation"); g_type_class_add_private (klass, sizeof (ClutterAnimationPrivate)); @@ -266,18 +265,18 @@ clutter_animation_class_init (ClutterAnimationClass *klass) gobject_class->finalize = clutter_animation_finalize; /** - * ClutterAnimation:actor: + * ClutterAnimation:objct: * - * The actor to which the animation applies. + * The #GObject to which the animation applies. * * Since: 1.0 */ - pspec = g_param_spec_object ("actor", - "Actor", - "Actor to which the animation applies", - CLUTTER_TYPE_ACTOR, + pspec = g_param_spec_object ("object", + "Object", + "Object to which the animation applies", + G_TYPE_OBJECT, CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_ACTOR, pspec); + g_object_class_install_property (gobject_class, PROP_OBJECT, pspec); /** * ClutterAnimation:mode: @@ -427,7 +426,7 @@ clutter_animation_update_property_internal (ClutterAnimation *animation, * @property_name: the property to control * @interval: a #ClutterInterval * - * Binds @interval to the @property_name of the #ClutterActor + * Binds @interval to the @property_name of the #GObject * attached to @animation. The #ClutterAnimation will take * ownership of the passed #ClutterInterval. * @@ -451,10 +450,10 @@ clutter_animation_bind_property (ClutterAnimation *animation, priv = animation->priv; - if (G_UNLIKELY (!priv->actor)) + if (G_UNLIKELY (!priv->object)) { g_warning ("Cannot bind property `%s': the animation has no " - "actor set. You need to call clutter_animation_set_actor() " + "object set. You need to call clutter_animation_set_object() " "first to be able to bind a property", property_name); return; @@ -468,14 +467,14 @@ clutter_animation_bind_property (ClutterAnimation *animation, return; } - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' have " + g_warning ("Cannot bind property `%s': objects of type `%s' have " "no such property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); return; } @@ -592,14 +591,14 @@ clutter_animation_update_property (ClutterAnimation *animation, return; } - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' have " + g_warning ("Cannot bind property `%s': objects of type `%s' have " "no such property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); return; } @@ -664,10 +663,18 @@ on_alpha_notify (GObject *gobject, ClutterAnimationPrivate *priv = animation->priv; GList *properties, *p; guint32 alpha_value; + gboolean is_animatable = FALSE; + ClutterAnimatable *animatable = NULL; alpha_value = clutter_alpha_get_alpha (CLUTTER_ALPHA (gobject)); - g_object_freeze_notify (G_OBJECT (priv->actor)); + if (CLUTTER_IS_ANIMATABLE (priv->object)) + { + animatable = CLUTTER_ANIMATABLE (priv->object); + is_animatable = TRUE; + } + + g_object_freeze_notify (priv->object); properties = g_hash_table_get_keys (priv->properties); for (p = properties; p != NULL; p = p->next) @@ -683,16 +690,37 @@ on_alpha_notify (GObject *gobject, g_value_init (&value, clutter_interval_get_value_type (interval)); factor = (gdouble) alpha_value / CLUTTER_ALPHA_MAX_ALPHA; - clutter_interval_compute_value (interval, factor, &value); - g_object_set_property (G_OBJECT (priv->actor), p_name, &value); + if (is_animatable) + { + const GValue *initial, *final; + + initial = clutter_interval_peek_initial_value (interval); + final = clutter_interval_peek_final_value (interval); + + CLUTTER_NOTE (ANIMATION, "Animatable property `%s'", p_name); + clutter_animatable_animate_property (animatable, animation, + p_name, + initial, final, + factor, + &value); + + g_object_set_property (priv->object, p_name, &value); + } + else + { + CLUTTER_NOTE (ANIMATION, "Standard property `%s'", p_name); + + if (clutter_interval_compute_value (interval, factor, &value)) + g_object_set_property (priv->object, p_name, &value); + } g_value_unset (&value); } g_list_free (properties); - g_object_thaw_notify (G_OBJECT (priv->actor)); + g_object_thaw_notify (priv->object); } /* @@ -709,7 +737,7 @@ on_animation_weak_notify (gpointer data, clutter_actor_get_gid (CLUTTER_ACTOR (actor)), actor); - g_object_set_qdata (actor, quark_actor_animation, NULL); + g_object_set_qdata (actor, quark_object_animation, NULL); } ClutterAnimation * @@ -719,66 +747,64 @@ clutter_animation_new (void) } /** - * clutter_animation_set_actor: + * clutter_animation_set_object: * @animation: a #ClutterAnimation - * @actor: a #ClutterActor + * @object: a #GObject * - * Attaches @animation to @actor. The #ClutterAnimation will take a - * reference on @actor. + * Attaches @animation to @object. The #ClutterAnimation will take a + * reference on @object. * * Since: 1.0 */ void -clutter_animation_set_actor (ClutterAnimation *animation, - ClutterActor *actor) +clutter_animation_set_object (ClutterAnimation *animation, + GObject *object) { ClutterAnimationPrivate *priv; g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (G_IS_OBJECT (object)); priv = animation->priv; - g_object_ref (actor); + g_object_ref (object); - if (priv->actor) + if (priv->object) { g_object_weak_unref (G_OBJECT (animation), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, - NULL); - g_object_unref (priv->actor); + priv->object); + g_object_set_qdata (priv->object, quark_object_animation, NULL); + g_object_unref (priv->object); } - priv->actor = actor; + priv->object = object; g_object_weak_ref (G_OBJECT (animation), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, + priv->object); + g_object_set_qdata (G_OBJECT (priv->object), + quark_object_animation, animation); - g_object_notify (G_OBJECT (animation), "actor"); + g_object_notify (G_OBJECT (animation), "object"); } /** - * clutter_animation_get_actor: + * clutter_animation_get_object: * @animation: a #ClutterAnimation * - * Retrieves the #ClutterActor attached to @animation. + * Retrieves the #GObject attached to @animation. * - * Return value: a #ClutterActor + * Return value: a #GObject * * Since: 1.0 */ -ClutterActor * -clutter_animation_get_actor (ClutterAnimation *animation) +GObject * +clutter_animation_get_object (ClutterAnimation *animation) { g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - return animation->priv->actor; + return animation->priv->object; } static inline void @@ -1125,7 +1151,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, GObjectClass *klass; const gchar *property_name; - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); property_name = first_property_name; while (property_name != NULL) @@ -1145,10 +1171,10 @@ clutter_animation_setup_valist (ClutterAnimation *animation, pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' do " + g_warning ("Cannot bind property `%s': objects of type `%s' do " "not have this property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); break; } @@ -1178,9 +1204,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, GValue initial = { 0, }; g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (G_OBJECT (priv->actor), - property_name, - &initial); + g_object_get_property (priv->object, property_name, &initial); interval = clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec), @@ -1199,7 +1223,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, g_value_unset (&initial); } else - g_object_set_property (G_OBJECT (priv->actor), property_name, &final); + g_object_set_property (priv->object, property_name, &final); g_value_unset (&final); @@ -1254,7 +1278,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, return NULL; } - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { animation = clutter_animation_new (); @@ -1265,7 +1289,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, clutter_animation_set_timeline (animation, timeline); clutter_animation_set_alpha (animation, alpha); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); va_start (args, first_property_name); clutter_animation_setup_valist (animation, first_property_name, args); @@ -1311,7 +1335,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); g_return_val_if_fail (first_property_name != NULL, NULL); - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { animation = clutter_animation_new (); @@ -1323,7 +1347,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, clutter_animation_set_timeline (animation, timeline); clutter_animation_set_alpha (animation, NULL); clutter_animation_set_mode (animation, mode); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); va_start (args, first_property_name); clutter_animation_setup_valist (animation, first_property_name, args); @@ -1406,7 +1430,7 @@ clutter_actor_animate (ClutterActor *actor, g_return_val_if_fail (duration > 0, NULL); g_return_val_if_fail (first_property_name != NULL, NULL); - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { /* if there is no animation already attached to the actor, @@ -1416,7 +1440,7 @@ clutter_actor_animate (ClutterActor *actor, animation = clutter_animation_new (); clutter_animation_set_timeline (animation, NULL); clutter_animation_set_alpha (animation, NULL); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); CLUTTER_NOTE (ANIMATION, "Created new Animation [%p]", animation); } diff --git a/clutter/clutter-animation.h b/clutter/clutter-animation.h index 115e0a0b5..061d4e439 100644 --- a/clutter/clutter-animation.h +++ b/clutter/clutter-animation.h @@ -97,9 +97,9 @@ GType clutter_animation_get_type (void) G_GNUC_CONST; ClutterAnimation * clutter_animation_new (void); -void clutter_animation_set_actor (ClutterAnimation *animation, - ClutterActor *actor); -ClutterActor * clutter_animation_get_actor (ClutterAnimation *animation); +void clutter_animation_set_object (ClutterAnimation *animation, + GObject *object); +GObject * clutter_animation_get_object (ClutterAnimation *animation); void clutter_animation_set_mode (ClutterAnimation *animation, ClutterAnimationMode mode); ClutterAnimationMode clutter_animation_get_mode (ClutterAnimation *animation); diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 4c60d40ff..efeeac185 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -251,9 +251,6 @@ _clutter_backend_ensure_context (ClutterBackend *backend, * potential issue of GL calls with no context) */ current_context_stage = stage; - - if (stage) - CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } else CLUTTER_NOTE (MULTISTAGE, "Stage is the same"); diff --git a/clutter/clutter-binding-pool.c b/clutter/clutter-binding-pool.c index 78a483f72..73398a58d 100644 --- a/clutter/clutter-binding-pool.c +++ b/clutter/clutter-binding-pool.c @@ -104,6 +104,10 @@ #include "clutter-marshal.h" #include "clutter-private.h" +#define CLUTTER_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass)) +#define CLUTTER_IS_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_BINDING_POOL)) +#define CLUTTER_BINDING_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass)) + #define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \ CLUTTER_CONTROL_MASK | \ CLUTTER_MOD1_MASK | \ @@ -111,19 +115,27 @@ CLUTTER_HYPER_MASK | \ CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK) -typedef struct _ClutterBindingEntry ClutterBindingEntry; +typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass; +typedef struct _ClutterBindingEntry ClutterBindingEntry; -static GSList *binding_pools = NULL; +static GSList *clutter_binding_pools = NULL; static GQuark key_class_bindings = 0; struct _ClutterBindingPool { + GObject parent_instance; + gchar *name; /* interned string, do not free */ GSList *entries; GHashTable *entries_hash; }; +struct _ClutterBindingPoolClass +{ + GObjectClass parent_class; +}; + struct _ClutterBindingEntry { gchar *name; /* interned string, do not free */ @@ -136,6 +148,15 @@ struct _ClutterBindingEntry guint is_blocked : 1; }; +enum +{ + PROP_0, + + PROP_NAME +}; + +G_DEFINE_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT); + static guint binding_entry_hash (gconstpointer v) { @@ -204,24 +225,112 @@ binding_entry_free (gpointer data) } static void -binding_pool_free (gpointer data) +clutter_binding_pool_finalize (GObject *gobject) { - if (G_LIKELY (data)) + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + /* remove from the pools */ + clutter_binding_pools = g_slist_remove (clutter_binding_pools, pool); + + g_hash_table_destroy (pool->entries_hash); + + g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL); + g_slist_free (pool->entries); + + G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); +} + +static void +clutter_binding_pool_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + switch (prop_id) { - ClutterBindingPool *pool = data; + case PROP_NAME: + pool->name = (gchar *) g_intern_string (g_value_get_string (value)); + break; - /* remove from the pools */ - binding_pools = g_slist_remove (binding_pools, pool); - - g_hash_table_destroy (pool->entries_hash); - - g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL); - g_slist_free (pool->entries); - - g_slice_free (ClutterBindingPool, pool); + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; } } +static void +clutter_binding_pool_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, pool->name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +clutter_binding_pool_constructed (GObject *gobject) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + /* bad monkey! bad, bad monkey! */ + if (G_UNLIKELY (pool->name == NULL)) + g_critical ("No name set for ClutterBindingPool %p", pool); + + if (G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed) + G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed (gobject); +} + +static void +clutter_binding_pool_class_init (ClutterBindingPoolClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec = NULL; + + gobject_class->constructed = clutter_binding_pool_constructed; + gobject_class->set_property = clutter_binding_pool_set_property; + gobject_class->get_property = clutter_binding_pool_get_property; + gobject_class->finalize = clutter_binding_pool_finalize; + + /** + * ClutterBindingPool:name: + * + * The unique name of the #ClutterBindingPool. + * + * Since: 1.0 + */ + pspec = g_param_spec_string ("name", + "Name", + "The unique name of the binding pool", + NULL, + CLUTTER_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (gobject_class, PROP_NAME, pspec); +} + +static void +clutter_binding_pool_init (ClutterBindingPool *pool) +{ + pool->name = NULL; + pool->entries = NULL; + pool->entries_hash = g_hash_table_new (binding_entry_hash, + binding_entry_compare); + + clutter_binding_pools = g_slist_prepend (clutter_binding_pools, pool); +} + /** * clutter_binding_pool_new: * @name: the name of the binding pool @@ -232,8 +341,7 @@ binding_pool_free (gpointer data) * be able to return the correct binding pool. * * Return value: the newly created binding pool with the given - * name. The binding pool is owned by Clutter and should not - * be freed directly + * name. Use g_object_unref() when done. * * Since: 1.0 */ @@ -253,15 +361,7 @@ clutter_binding_pool_new (const gchar *name) return NULL; } - pool = g_slice_new (ClutterBindingPool); - pool->name = (gchar *) g_intern_string (name); - pool->entries = NULL; - pool->entries_hash = g_hash_table_new (binding_entry_hash, - binding_entry_compare); - - binding_pools = g_slist_prepend (binding_pools, pool); - - return pool; + return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL); } /** @@ -306,7 +406,7 @@ clutter_binding_pool_get_for_class (gpointer klass) pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass)); g_dataset_id_set_data_full (klass, key_class_bindings, pool, - binding_pool_free); + g_object_unref); return pool; } @@ -328,7 +428,7 @@ clutter_binding_pool_find (const gchar *name) g_return_val_if_fail (name != NULL, NULL); - for (l = binding_pools; l != NULL; l = l->next) + for (l = clutter_binding_pools; l != NULL; l = l->next) { ClutterBindingPool *pool = l->data; diff --git a/clutter/clutter-binding-pool.h b/clutter/clutter-binding-pool.h index 55b5273c8..fd85f2664 100644 --- a/clutter/clutter-binding-pool.h +++ b/clutter/clutter-binding-pool.h @@ -33,6 +33,18 @@ G_BEGIN_DECLS +#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ()) +#define CLUTTER_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPool)) +#define CLUTTER_IS_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BINDING_POOL)) + +/** + * ClutterBindingPool: + * + * Container of key bindings. The #ClutterBindingPool struct is + * private. + * + * Since: 1.0 + */ typedef struct _ClutterBindingPool ClutterBindingPool; /** @@ -56,6 +68,8 @@ typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject, guint key_val, ClutterModifierType modifiers); +GType clutter_binding_pool_get_type (void) G_GNUC_CONST; + ClutterBindingPool * clutter_binding_pool_new (const gchar *name); ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); ClutterBindingPool * clutter_binding_pool_find (const gchar *name); diff --git a/clutter/clutter-cairo-texture.h b/clutter/clutter-cairo-texture.h index a5cca866c..b7816fef6 100644 --- a/clutter/clutter-cairo-texture.h +++ b/clutter/clutter-cairo-texture.h @@ -49,6 +49,13 @@ typedef struct _ClutterCairoTexture ClutterCairoTexture; typedef struct _ClutterCairoTextureClass ClutterCairoTextureClass; typedef struct _ClutterCairoTexturePrivate ClutterCairoTexturePrivate; +/** + * ClutterCairoTexture: + * + * The #ClutterCairoTexture struct contains only private data. + * + * Since: 1.0 + */ struct _ClutterCairoTexture { /*< private >*/ @@ -57,6 +64,13 @@ struct _ClutterCairoTexture ClutterCairoTexturePrivate *priv; }; +/** + * ClutterCairoTextureClass: + * + * The #ClutterCairoTextureClass struct contains only private data. + * + * Since: 1.0 + */ struct _ClutterCairoTextureClass { /*< private >*/ diff --git a/clutter/clutter-effect.c b/clutter/clutter-effect.c deleted file mode 100644 index 64fd25b4a..000000000 --- a/clutter/clutter-effect.c +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 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:clutter-effect - * @short_description: Utility Class for basic visual effects - * - * The #ClutterEffectTemplate class provides a simple API for applying - * pre-defined effects to a single actor. It works as a wrapper around - * the #ClutterBehaviour objects - * - * Since: 0.4 - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "clutter-alpha.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-debug.h" -#include "clutter-behaviour-depth.h" -#include "clutter-behaviour-ellipse.h" -#include "clutter-behaviour-opacity.h" -#include "clutter-behaviour-path.h" -#include "clutter-behaviour-rotate.h" -#include "clutter-behaviour-scale.h" - -#include "clutter-effect.h" - -typedef struct ClutterEffectClosure -{ - ClutterActor *actor; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *behave; - - gulong signal_id; - - ClutterEffectCompleteFunc completed_func; - gpointer completed_data; - ClutterEffectTemplate *template; -} -ClutterEffectClosure; - -G_DEFINE_TYPE (ClutterEffectTemplate, clutter_effect_template, G_TYPE_OBJECT); - -#define EFFECT_TEMPLATE_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, \ - ClutterEffectTemplatePrivate)) - -struct _ClutterEffectTemplatePrivate -{ - ClutterTimeline *timeline; - - guint do_clone : 1; - guint dirty : 1; - - ClutterAlphaFunc alpha_func; - gpointer alpha_data; - GDestroyNotify alpha_notify; -}; - -enum -{ - PROP_0, - - PROP_TIMELINE, - PROP_DO_CLONE -}; - -static void -clutter_effect_template_finalize (GObject *gobject) -{ - ClutterEffectTemplate *template = CLUTTER_EFFECT_TEMPLATE (gobject); - ClutterEffectTemplatePrivate *priv = template->priv; - - if (priv->alpha_notify) - { - priv->alpha_notify (priv->alpha_data); - priv->alpha_notify = NULL; - } - - priv->alpha_data = NULL; - priv->alpha_func = NULL; - - G_OBJECT_CLASS (clutter_effect_template_parent_class)->finalize (gobject); -} - -static void -clutter_effect_template_dispose (GObject *object) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - if (priv->timeline) - { - g_object_unref (priv->timeline); - priv->timeline = NULL; - } - - G_OBJECT_CLASS (clutter_effect_template_parent_class)->dispose (object); -} - -static void -clutter_effect_template_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - switch (prop_id) - { - case PROP_TIMELINE: - priv->timeline = g_value_dup_object (value); - break; - case PROP_DO_CLONE: - clutter_effect_template_set_timeline_clone (template, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_effect_template_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - switch (prop_id) - { - case PROP_TIMELINE: - g_value_set_object (value, priv->timeline); - break; - case PROP_DO_CLONE: - g_value_set_boolean (value, priv->do_clone); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_effect_template_class_init (ClutterEffectTemplateClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (ClutterEffectTemplatePrivate)); - - object_class->finalize = clutter_effect_template_finalize; - object_class->dispose = clutter_effect_template_dispose; - object_class->set_property = clutter_effect_template_set_property; - object_class->get_property = clutter_effect_template_get_property; - - /** - * ClutterEffectTemplate:timeline: - * - * #ClutterTimeline to be used by the template - * - * Since: 0.4 - */ - g_object_class_install_property - (object_class, - PROP_TIMELINE, - g_param_spec_object ("timeline", - "Timeline", - "Timeline to use as a reference for the Template", - CLUTTER_TYPE_TIMELINE, - G_PARAM_CONSTRUCT_ONLY | - CLUTTER_PARAM_READWRITE)); - - /** - * ClutterEffectTemplate:clone: - * - * Controls if effects should clone or reference the templated timeline - * - * Since: 0.6 - */ - g_object_class_install_property - (object_class, - PROP_DO_CLONE, - g_param_spec_boolean ("clone", - "Clone", - "controls if effects should clone or reference the templated timeline", - TRUE, - CLUTTER_PARAM_READWRITE)); - -} - -static void -clutter_effect_template_init (ClutterEffectTemplate *self) -{ - self->priv = EFFECT_TEMPLATE_PRIVATE (self); - - self->priv->do_clone = TRUE; - self->priv->dirty = TRUE; -} - -static void -clutter_effect_template_set_alpha_func (ClutterEffectTemplate *self, - ClutterAlphaFunc alpha_func, - gpointer alpha_data, - GDestroyNotify alpha_notify) -{ - ClutterEffectTemplatePrivate *priv; - - priv = self->priv; - - if (priv->alpha_notify) - { - priv->alpha_notify (priv->alpha_data); - priv->alpha_notify = NULL; - } - - priv->alpha_data = alpha_data; - priv->alpha_notify = alpha_notify; - priv->alpha_func = alpha_func; - - priv->dirty = FALSE; -} - -/** - * clutter_effect_template_set_timeline_clone: - * @template_: A #ClutterEffectTemplate - * @setting: A boolean indicating if effects should clone the timeline. - * - * Sets if effects using this template should make a copy of the - * templates timeline (default) or reference the effects timeline. - * - * Since: 0.6 - */ -void -clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_, - gboolean setting) -{ - g_return_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_)); - - if (template_->priv->do_clone != setting) - { - template_->priv->do_clone = setting; - - g_object_notify (G_OBJECT (template_), "clone"); - } -} - -/** - * clutter_effect_template_get_timeline_clone: - * @template_: A #ClutterEffectTemplate - * - * Gets whether timelines should be cloned when creating a new - * effect or just referenced. - * - * Return value: %TRUE if the templates timeline is to be cloned. - * - * Since: 0.6 - */ -gboolean -clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_) -{ - g_return_val_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_), FALSE); - - return template_->priv->do_clone; -} - - -/** - * clutter_effect_template_new: - * @timeline: A #ClutterTimeline for the template (will be cloned) - * @alpha_func: An alpha func to use for the template. - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * Return value: a #ClutterEffectTemplate - * - * Since: 0.4 - */ -ClutterEffectTemplate* -clutter_effect_template_new (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func) -{ - ClutterEffectTemplate *retval; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - retval = g_object_new (CLUTTER_TYPE_EFFECT_TEMPLATE, - "timeline", timeline, - NULL); - - clutter_effect_template_set_alpha_func (retval, alpha_func, NULL, NULL); - - return retval; -} - -/** - * clutter_effect_template_new_full: - * @timeline: a #ClutterTimeline - * @alpha_func: an alpha function to use for the template - * @user_data: data to be passed to the alpha function, or %NULL - * @notify: function to be called when disposing the alpha function's use - * data, or %NULL - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * This function is intended for language bindings only: if @notify is - * not %NULL it will be called to dispose of @user_data. - * - * Return value: the newly created #ClutterEffectTemplate object - * - * Since: 0.4 - */ -ClutterEffectTemplate * -clutter_effect_template_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterEffectTemplate *retval; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - retval = g_object_new (CLUTTER_TYPE_EFFECT_TEMPLATE, - "timeline", timeline, - NULL); - - clutter_effect_template_set_alpha_func (retval, - alpha_func, - user_data, notify); - - return retval; -} - -/** - * clutter_effect_template_new_for_duration: - * @msecs: the duration of the effects, in milliseconds - * @alpha_func: an alpha function to use for the template - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * This function creates a #ClutterTimeline with a duration of @msecs - * milliseconds and transfers ownership of the timeline object to the - * returned #ClutterEffectTemplate. - * - * Return value: the newly created #ClutterEffectTemplate object - * - * Since: 0.6 - */ -ClutterEffectTemplate * -clutter_effect_template_new_for_duration (guint msecs, - ClutterAlphaFunc alpha_func) -{ - ClutterTimeline *timeline; - ClutterEffectTemplate *retval; - - g_return_val_if_fail (msecs > 0, NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - timeline = clutter_timeline_new_for_duration (msecs); - retval = clutter_effect_template_new (timeline, alpha_func); - - /* the effect template takes ownership of the timeline */ - g_object_unref (timeline); - - return retval; -} - -/** - * clutter_effect_template_construct: - * @template_: a #ClutterEffectTemplate - * @timeline: a #ClutterTimeline - * @alpha_func: an alpha function to use for the template - * @user_data: data to be passed to the alpha function, or %NULL - * @notify: function to be called when disposing the alpha function's use - * data, or %NULL - * - * Constructs a #ClutterEffectTemplate, to be used with the effects API. - * - * This function can only be called once after the creation of @template_ - * and is only useful for language bindings. - * - * Since: 0.6 - */ -void -clutter_effect_template_construct (ClutterEffectTemplate *template_, - ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterEffectTemplatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_)); - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (alpha_func != NULL); - - if (!template_->priv->dirty) - return; - - priv = template_->priv; - - if (priv->timeline) - g_object_unref (priv->timeline); - - priv->timeline = g_object_ref (timeline); - clutter_effect_template_set_alpha_func (template_, - alpha_func, - user_data, notify); -} - -static void -clutter_effect_closure_destroy (ClutterEffectClosure *c) -{ - g_signal_handler_disconnect (c->timeline, c->signal_id); - - g_object_unref (c->actor); - g_object_unref (c->template); - g_object_unref (c->behave); - g_object_unref (c->timeline); - - g_slice_free (ClutterEffectClosure, c); -} - -static ClutterEffectClosure * -clutter_effect_closure_new (ClutterEffectTemplate *template, - ClutterActor *actor, - GCallback complete) -{ - ClutterEffectClosure *c; - ClutterEffectTemplatePrivate *priv = EFFECT_TEMPLATE_PRIVATE(template); - - c = g_slice_new0(ClutterEffectClosure); - - g_object_ref (actor); - g_object_ref (template); - - c->template = template; - c->actor = actor; - - if (clutter_effect_template_get_timeline_clone (template)) - c->timeline = clutter_timeline_clone (priv->timeline); - else - { - c->timeline = priv->timeline; - g_object_ref (priv->timeline); - } - - c->alpha = clutter_alpha_new_full (c->timeline, - priv->alpha_func, - priv->alpha_data, - NULL); - - c->signal_id = - g_signal_connect (c->timeline, "completed", G_CALLBACK (complete), c); - - return c; -} - -static void -on_effect_complete (ClutterTimeline *timeline, - gpointer user_data) -{ - ClutterEffectClosure *c = (ClutterEffectClosure*)user_data; - - if (c->completed_func) - c->completed_func (c->actor, c->completed_data); - - clutter_effect_closure_destroy (c); -} - -/** - * clutter_effect_fade: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @opacity_end: Final opacity value to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for fading a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unrefed by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_fade (ClutterEffectTemplate *template_, - ClutterActor *actor, - guint8 opacity_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - guint8 opacity_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - opacity_start = clutter_actor_get_opacity (actor); - - c->behave = clutter_behaviour_opacity_new (c->alpha, - opacity_start, - opacity_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_depth: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @depth_end: Final depth value to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for changing the depth of a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unrefed by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_depth (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint depth_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gint depth_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - depth_start = clutter_actor_get_depth (actor); - - c->behave = clutter_behaviour_depth_new (c->alpha, depth_start, depth_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_move: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @x: X coordinate of the destination - * @y: Y coordinate of the destination - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for moving a single #ClutterActor along to a - * destination point. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_move (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint x, - gint y, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - ClutterPath *path; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - path = clutter_path_new (); - - clutter_path_add_move_to (path, - clutter_actor_get_x (actor), - clutter_actor_get_y (actor)); - clutter_path_add_line_to (path, x, y); - - c->behave = clutter_behaviour_path_new (c->alpha, path); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} -/** - * clutter_effect_path: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @knots: An array of #ClutterKnots representing path for the actor - * @n_knots: Number of #ClutterKnots in passed array. - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for moving a single #ClutterActor along a path. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_path (ClutterEffectTemplate *template_, - ClutterActor *actor, - const ClutterKnot *knots, - guint n_knots, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - ClutterPath *path; - guint i; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - path = clutter_path_new (); - - c->completed_func = func; - c->completed_data = data; - - path = clutter_path_new (); - - if (n_knots) - { - clutter_actor_set_position (actor, knots[0].x, knots[0].y); - clutter_path_add_move_to (path, knots[0].x, knots[0].y); - - for (i = 1; i < n_knots; i++) - clutter_path_add_line_to (path, knots[i].x, knots[i].y); - } - - c->behave = clutter_behaviour_path_new (c->alpha, path); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_scale: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @x_scale_end: Final X axis scale factor to apply to actor - * @y_scale_end: Final Y axis scale factor to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or NULL - * - * Simple effect for scaling a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_scale (ClutterEffectTemplate *template_, - ClutterActor *actor, - gdouble x_scale_end, - gdouble y_scale_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gdouble x_scale_start, y_scale_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - clutter_actor_get_scale (actor, &x_scale_start, &y_scale_start); - c->behave = clutter_behaviour_scale_new (c->alpha, - x_scale_start, y_scale_start, - x_scale_end, y_scale_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_rotate: - * @template_: a #ClutterEffectTemplate - * @actor: a #ClutterActor to apply the effect to. - * @axis: axis of rotation - * @angle: final angle to apply to actor - * @center_x: position on X axis to rotate about. - * @center_y: position on Y axis to rotate about. - * @center_z: position on Z axis to rotate about. - * @direction: a #ClutterRotateDirection for the rotation. - * @func: a #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: user data to pass to supplied @func or %NULL - * - * Simple effect for rotating a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_rotate (ClutterEffectTemplate *template_, - ClutterActor *actor, - ClutterRotateAxis axis, - gdouble angle_end, - gint center_x, - gint center_y, - gint center_z, - ClutterRotateDirection direction, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gdouble angle_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - angle_start = clutter_actor_get_rotation (actor, axis, NULL, NULL, NULL); - - c->behave = clutter_behaviour_rotate_new (c->alpha, - axis, - direction, - angle_start, - angle_end); - g_object_set (c->behave, - "center-x", center_x, - "center-y", center_y, - "center-z", center_z, - NULL); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} diff --git a/clutter/clutter-effect.h b/clutter/clutter-effect.h deleted file mode 100644 index 0d1fb176d..000000000 --- a/clutter/clutter-effect.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006, 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, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_EFFECT_H__ -#define __CLUTTER_EFFECT_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -/** - * ClutterEffectCompleteFunc: - * @actor: a #ClutterActor - * @user_data: user data - * - * Callback function invoked when an effect is complete. - * - * Since: 0.4 - */ -typedef void (*ClutterEffectCompleteFunc) (ClutterActor *actor, - gpointer user_data); - -#define CLUTTER_TYPE_EFFECT_TEMPLATE clutter_effect_template_get_type() - -#define CLUTTER_EFFECT_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplate)) - -#define CLUTTER_EFFECT_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass)) - -#define CLUTTER_IS_EFFECT_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE)) - -#define CLUTTER_IS_EFFECT_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_EFFECT_TEMPLATE)) - -#define CLUTTER_EFFECT_TEMPLATE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass)) - -typedef struct _ClutterEffectTemplate ClutterEffectTemplate; -typedef struct _ClutterEffectTemplatePrivate ClutterEffectTemplatePrivate; -typedef struct _ClutterEffectTemplateClass ClutterEffectTemplateClass; - - -struct _ClutterEffectTemplate -{ - /*< private >*/ - GObject parent_instance; - - ClutterEffectTemplatePrivate *priv; -}; - -struct _ClutterEffectTemplateClass -{ - /*< private >*/ - GObjectClass parent_class; - - /* padding, for future expansion */ - void (*_clutter_reserved1) (void); - void (*_clutter_reserved2) (void); - void (*_clutter_reserved3) (void); - void (*_clutter_reserved4) (void); -}; - -GType clutter_effect_template_get_type (void) G_GNUC_CONST; -ClutterEffectTemplate *clutter_effect_template_new (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func); -ClutterEffectTemplate *clutter_effect_template_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify); -ClutterEffectTemplate *clutter_effect_template_new_for_duration (guint msecs, - ClutterAlphaFunc alpha_func); -void clutter_effect_template_construct (ClutterEffectTemplate *template_, - ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify); -void clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_, - gboolean setting); -gboolean clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_); - - -/* - * Clutter effects - */ - -ClutterTimeline *clutter_effect_fade (ClutterEffectTemplate *template_, - ClutterActor *actor, - guint8 opacity_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_depth (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint depth_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_move (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint x, - gint y, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_path (ClutterEffectTemplate *template_, - ClutterActor *actor, - const ClutterKnot *knots, - guint n_knots, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_scale (ClutterEffectTemplate *template_, - ClutterActor *actor, - gdouble x_scale_end, - gdouble y_scale_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_rotate (ClutterEffectTemplate *template_, - ClutterActor *actor, - ClutterRotateAxis axis, - gdouble angle, - gint center_x, - gint center_y, - gint center_z, - ClutterRotateDirection direction, - ClutterEffectCompleteFunc func, - gpointer data); - -G_END_DECLS - -#endif /* __CLUTTER_EFFECT_H__ */ diff --git a/clutter/clutter-interval.c b/clutter/clutter-interval.c index 5f2924d09..efdf58dff 100644 --- a/clutter/clutter-interval.c +++ b/clutter/clutter-interval.c @@ -57,9 +57,18 @@ #include #include +#include "clutter-color.h" +#include "clutter-fixed.h" #include "clutter-interval.h" #include "clutter-units.h" -#include "clutter-fixed.h" + +typedef struct +{ + GType value_type; + ClutterProgressFunc func; +} ProgressData; + +static GHashTable *progress_funcs = NULL; enum { @@ -171,19 +180,39 @@ clutter_interval_real_validate (ClutterInterval *interval, return TRUE; } -static void +static gboolean clutter_interval_real_compute_value (ClutterInterval *interval, gdouble factor, GValue *value) { GValue *initial, *final; GType value_type; + gboolean retval = FALSE; initial = clutter_interval_peek_initial_value (interval); final = clutter_interval_peek_final_value (interval); value_type = clutter_interval_get_value_type (interval); + if (G_UNLIKELY (progress_funcs != NULL)) + { + ProgressData *p_data; + + p_data = + g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type)); + + /* if we have a progress function, and that function was + * successful in computing the progress, then we bail out + * as fast as we can + */ + if (p_data != NULL) + { + retval = p_data->func (initial, final, factor, value); + if (retval) + return retval; + } + } + switch (G_TYPE_FUNDAMENTAL (value_type)) { case G_TYPE_INT: @@ -196,6 +225,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - ia)) + ia; g_value_set_int (value, res); + + retval = TRUE; } break; @@ -209,6 +240,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - (gdouble) ia)) + ia; g_value_set_uint (value, res); + + retval = TRUE; } break; @@ -222,6 +255,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - (gdouble) ia)) + ia; g_value_set_uchar (value, res); + + retval = TRUE; } break; @@ -239,6 +274,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, g_value_set_double (value, res); else g_value_set_float (value, res); + + retval = TRUE; } break; @@ -247,11 +284,35 @@ clutter_interval_real_compute_value (ClutterInterval *interval, g_value_set_boolean (value, TRUE); else g_value_set_boolean (value, FALSE); + + retval = TRUE; + break; + + case G_TYPE_BOXED: + if (value_type == CLUTTER_TYPE_COLOR) + { + const ClutterColor *ia, *ib; + ClutterColor res = { 0, }; + + ia = clutter_value_get_color (initial); + ib = clutter_value_get_color (final); + + res.red = (factor * (ib->red - (gdouble) ia->red)) + ia->red; + res.green = (factor * (ib->green - (gdouble) ia->green)) + ia->green; + res.blue = (factor * (ib->blue - (gdouble) ia->blue)) + ia->blue; + res.alpha = (factor * (ib->alpha - (gdouble) ia->alpha)) + ia->alpha; + + clutter_value_set_color (value, &res); + + retval = TRUE; + } break; default: break; } + + return retval; } static void @@ -818,19 +879,99 @@ clutter_interval_validate (ClutterInterval *interval, * Computes the value between the @interval boundaries given the * progress @factor and puts it into @value. * + * Return value: %TRUE if the operation was successful + * * Since: 1.0 */ -void +gboolean clutter_interval_compute_value (ClutterInterval *interval, gdouble factor, GValue *value) { - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); + g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); + g_return_val_if_fail (value != NULL, FALSE); factor = CLAMP (factor, 0.0, 1.0); - CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, - factor, - value); + return CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, + factor, + value); +} + +/** + * clutter_interval_register_progress_func: + * @value_type: a #GType + * @func: a #ClutterProgressFunc, or %NULL to unset a previously + * set progress function + * + * Sets the progress function for a given @value_type, like: + * + * |[ + * clutter_interval_register_progress_func (MY_TYPE_FOO, + * my_foo_progress); + * ]| + * + * Whenever a #ClutterInterval instance using the default + * #ClutterInterval::compute_value implementation is set as an + * interval between two #GValue of type @value_type, it will call + * @func to establish the value depending on the given progress, + * for instance: + * + * |[ + * static gboolean + * my_int_progress (const GValue *a, + * const GValue *b, + * gdouble progress, + * GValue *retval) + * { + * gint ia = g_value_get_int (a); + * gint ib = g_value_get_int (b); + * gint res = factor * (ib - ia) + ia; + * + * g_value_set_int (retval, res); + * + * return TRUE; + * } + * + * clutter_interval_register_progress_func (G_TYPE_INT, my_int_progress); + * ]| + * + * To unset a previously set progress function of a #GType, pass %NULL + * for @func. + * + * Since: 1.0 + */ +void +clutter_interval_register_progress_func (GType value_type, + ClutterProgressFunc func) +{ + ProgressData *progress_func; + + g_return_if_fail (value_type != G_TYPE_INVALID); + + if (G_UNLIKELY (progress_funcs == NULL)) + progress_funcs = g_hash_table_new (NULL, NULL); + + progress_func = + g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type)); + if (G_UNLIKELY (progress_func)) + { + if (func == NULL) + { + g_hash_table_remove (progress_funcs, GUINT_TO_POINTER (value_type)); + g_slice_free (ProgressData, progress_func); + } + else + progress_func->func = func; + } + else + { + progress_func = g_slice_new (ProgressData); + progress_func->value_type = value_type; + progress_func->func = func; + + g_hash_table_replace (progress_funcs, + GUINT_TO_POINTER (value_type), + progress_func); + } } diff --git a/clutter/clutter-interval.h b/clutter/clutter-interval.h index 56d155f28..72ae5304c 100644 --- a/clutter/clutter-interval.h +++ b/clutter/clutter-interval.h @@ -44,6 +44,34 @@ typedef struct _ClutterInterval ClutterInterval; typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate; typedef struct _ClutterIntervalClass ClutterIntervalClass; +/** + * ClutterProgressFunc: + * @a: the initial value of an interval + * @b: the final value of an interval + * @progress: the progress factor, between 0 and 1 + * @retval: the value used to store the progress + * + * Prototype of the progress function used to compute the value + * between the two ends @a and @b of an interval depending on + * the value of @progress. + * + * The #GValue in @retval is already initialized with the same + * type as @a and @b. + * + * This function will be called by #ClutterInterval if the + * type of the values of the interval was registered using + * clutter_interval_register_progress_func(). + * + * Return value: %TRUE if the function successfully computed + * the value and stored it inside @retval + * + * Since: 1.0 + */ +typedef gboolean (* ClutterProgressFunc) (const GValue *a, + const GValue *b, + gdouble progress, + GValue *retval); + /** * ClutterInterval: * @@ -79,7 +107,7 @@ struct _ClutterIntervalClass /*< public >*/ gboolean (* validate) (ClutterInterval *interval, GParamSpec *pspec); - void (* compute_value) (ClutterInterval *interval, + gboolean (* compute_value) (ClutterInterval *interval, gdouble factor, GValue *value); @@ -122,10 +150,13 @@ void clutter_interval_get_interval (ClutterInterval *interval, gboolean clutter_interval_validate (ClutterInterval *interval, GParamSpec *pspec); -void clutter_interval_compute_value (ClutterInterval *interval, +gboolean clutter_interval_compute_value (ClutterInterval *interval, gdouble factor, GValue *value); +void clutter_interval_register_progress_func (GType value_type, + ClutterProgressFunc func); + G_END_DECLS #endif /* __CLUTTER_INTERVAL_H__ */ diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index f6d42288f..6a4e850b8 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -115,6 +115,8 @@ enum UNFULLSCREEN, ACTIVATE, DEACTIVATE, + QUEUE_REDRAW, + LAST_SIGNAL }; @@ -335,6 +337,42 @@ clutter_stage_real_fullscreen (ClutterStage *stage) clutter_actor_allocate (CLUTTER_ACTOR (stage), &box, FALSE); } +static gboolean +redraw_update_idle (gpointer user_data) +{ + ClutterStage *stage = user_data; + ClutterStagePrivate *priv = stage->priv; + + if (priv->update_idle) + { + g_source_remove (priv->update_idle); + priv->update_idle = 0; + } + + CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage); + clutter_redraw (stage); + + return FALSE; +} + +static void +clutter_stage_real_queue_redraw (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + + if (priv->update_idle == 0) + { + CLUTTER_TIMESTAMP (SCHEDULER, "Adding idle source for stage: %p", stage); + + /* FIXME: weak_ref self in case we dissapear before paint? */ + priv->update_idle = + clutter_threads_add_idle_full (CLUTTER_PRIORITY_REDRAW, + redraw_update_idle, + stage, + NULL); + } +} + static void clutter_stage_set_property (GObject *object, guint prop_id, @@ -687,8 +725,58 @@ clutter_stage_class_init (ClutterStageClass *klass) NULL, NULL, clutter_marshal_VOID__VOID, G_TYPE_NONE, 0); + /** + * ClutterStage::queue-redraw: + * @stage: the stage which was queued for redraw + * + * The ::queue-redraw signal is emitted each time a #ClutterStage + * has been queued for a redraw. You can use this signal to know + * when clutter_stage_queue_redraw() has been called. + * + * Toolkits embedding a #ClutterStage which require a redraw and + * relayout cycle can stop the emission of this signal using the + * GSignal API, redraw the UI and then call clutter_redraw() + * themselves, like: + * + * |[ + * static void + * on_redraw_complete (void) + * { + * /* execute the Clutter drawing pipeline */ + * clutter_redraw (); + * } + * + * static void + * on_stage_queue_redraw (ClutterStage *stage) + * { + * /* this prevents the default handler to run */ + * g_signal_stop_emission_by_name (stage, "queue-redraw"); + * + * /* queue a redraw with the host toolkit and call + * * a function when the redraw has been completed + * */ + * queue_a_redraw (G_CALLBACK (on_redraw_complete)); + * } + * ]| + * + * This signal is emitted before the Clutter paint + * pipeline is run. If you want to know when the pipeline has been + * completed you should connect to the ::paint signal on the Stage + * with g_signal_connect_after(). + * + * Since: 1.0 + */ + stage_signals[QUEUE_REDRAW] = + g_signal_new (I_("queue-redraw"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ClutterStageClass, queue_redraw), + NULL, NULL, + clutter_marshal_VOID__VOID, + G_TYPE_NONE, 0); klass->fullscreen = clutter_stage_real_fullscreen; + klass->queue_redraw = clutter_stage_real_queue_redraw; g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate)); } @@ -1801,22 +1889,29 @@ clutter_stage_ensure_current (ClutterStage *stage) _clutter_backend_ensure_context (ctx->backend, stage); } -static gboolean -redraw_update_idle (gpointer user_data) +/** + * clutter_stage_ensure_viewport: + * @stage: a #ClutterStage + * + * Ensures that the GL viewport is updated with the current + * stage window size. + * + * This function will queue a redraw of @stage. + * + * This function should not be called by applications; it is used + * when embedding a #ClutterStage into a toolkit with another + * windowing system, like GTK+. + * + * Since: 1.0 + */ +void +clutter_stage_ensure_viewport (ClutterStage *stage) { - ClutterStage *stage = user_data; - ClutterStagePrivate *priv = stage->priv; + g_return_if_fail (CLUTTER_IS_STAGE (stage)); - if (priv->update_idle) - { - g_source_remove (priv->update_idle); - priv->update_idle = 0; - } + CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); - CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage); - clutter_redraw (stage); - - return FALSE; + clutter_stage_queue_redraw (stage); } /** @@ -1835,17 +1930,7 @@ clutter_stage_queue_redraw (ClutterStage *stage) { g_return_if_fail (CLUTTER_IS_STAGE (stage)); - if (!stage->priv->update_idle) - { - CLUTTER_TIMESTAMP (SCHEDULER, "Adding idle source for stage: %p", stage); - - /* FIXME: weak_ref self in case we dissapear before paint? */ - stage->priv->update_idle = - clutter_threads_add_idle_full (CLUTTER_PRIORITY_REDRAW, - redraw_update_idle, - stage, - NULL); - } + g_signal_emit (stage, stage_signals[QUEUE_REDRAW], 0); } /** diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index cb8ca9063..9cbbdeb92 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -106,6 +106,8 @@ struct _ClutterStageClass void (* activate) (ClutterStage *stage); void (* deactivate) (ClutterStage *stage); + void (* queue_redraw) (ClutterStage *stage); + /*< private >*/ /* padding for future expansion */ gpointer _padding_dummy[32]; @@ -229,6 +231,7 @@ ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage); void clutter_stage_ensure_current (ClutterStage *stage); void clutter_stage_queue_redraw (ClutterStage *stage); gboolean clutter_stage_is_default (ClutterStage *stage); +void clutter_stage_ensure_viewport (ClutterStage *stage); /* Commodity macro */ #define clutter_stage_add(stage,actor) G_STMT_START { \ diff --git a/clutter/clutter-text.c b/clutter/clutter-text.c index 4b7ae3f13..94229694d 100644 --- a/clutter/clutter-text.c +++ b/clutter/clutter-text.c @@ -202,31 +202,16 @@ static gint offset_to_bytes (const gchar *text, gint pos) { - gchar *c = NULL; - gint i, j, len; + const gchar *ptr; if (pos < 0) return strlen (text); - c = g_utf8_next_char (text); - j = 1; - len = strlen (text); + /* Loop over each character in the string until we either reach the + end or the requested position */ + for (ptr = text; *ptr && pos-- > 0; ptr = g_utf8_next_char (ptr)); - for (i = 0; i < len; i++) - { - if (&text[i] == c) - { - if (j == pos) - break; - else - { - c = g_utf8_next_char (c); - j++; - } - } - } - - return i; + return ptr - text; } #define bytes_to_offset(t,p) (g_utf8_pointer_to_offset ((t), (t) + (p))) @@ -688,11 +673,11 @@ clutter_text_get_property (GObject *gobject, break; case PROP_POSITION: - g_value_set_int (value, CLUTTER_FIXED_TO_FLOAT (priv->position)); + g_value_set_int (value, priv->position); break; case PROP_SELECTION_BOUND: - g_value_set_int (value, CLUTTER_FIXED_TO_FLOAT (priv->selection_bound)); + g_value_set_int (value, priv->selection_bound); break; case PROP_EDITABLE: @@ -719,6 +704,30 @@ clutter_text_get_property (GObject *gobject, g_value_set_boolean (value, priv->single_line_mode); break; + case PROP_ELLIPSIZE: + g_value_set_enum (value, priv->ellipsize); + break; + + case PROP_LINE_WRAP: + g_value_set_boolean (value, priv->wrap); + break; + + case PROP_LINE_WRAP_MODE: + g_value_set_enum (value, priv->wrap_mode); + break; + + case PROP_ALIGNMENT: + g_value_set_enum (value, priv->alignment); + break; + + case PROP_JUSTIFY: + g_value_set_boolean (value, priv->justify); + break; + + case PROP_ATTRIBUTES: + g_value_set_boxed (value, priv->attrs); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } @@ -993,7 +1002,9 @@ clutter_text_key_press (ClutterActor *actor, if (key_unichar == '\r') key_unichar = '\n'; - if (g_unichar_validate (key_unichar)) + if (key_unichar == '\n' || + (g_unichar_validate (key_unichar) && + !g_unichar_iscntrl (key_unichar))) { /* truncate the eventual selection so that the * Unicode character can replace it @@ -1267,7 +1278,7 @@ clutter_text_real_move_up (ClutterText *self, PangoLayoutLine *layout_line; PangoLayout *layout; gint line_no; - gint index_; + gint index_, trailing; gint x; layout = clutter_text_get_layout (self); @@ -1287,21 +1298,23 @@ clutter_text_real_move_up (ClutterText *self, if (priv->x_pos != -1) x = priv->x_pos; - else - priv->x_pos = x; layout_line = pango_layout_get_line_readonly (layout, line_no); if (!layout_line) return FALSE; - pango_layout_line_x_to_index (layout_line, x, &index_, NULL); + pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); { gint pos = bytes_to_offset (priv->text, index_); - clutter_text_set_cursor_position (self, pos); + clutter_text_set_cursor_position (self, pos + trailing); } + /* Store the target x position to avoid drifting left and right when + moving the cursor up and down */ + priv->x_pos = x; + if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) clutter_text_clear_selection (self); @@ -1318,7 +1331,7 @@ clutter_text_real_move_down (ClutterText *self, PangoLayoutLine *layout_line; PangoLayout *layout; gint line_no; - gint index_; + gint index_, trailing; gint x; layout = clutter_text_get_layout (self); @@ -1334,21 +1347,23 @@ clutter_text_real_move_down (ClutterText *self, if (priv->x_pos != -1) x = priv->x_pos; - else - priv->x_pos = x; layout_line = pango_layout_get_line_readonly (layout, line_no + 1); if (!layout_line) return FALSE; - pango_layout_line_x_to_index (layout_line, x, &index_, NULL); + pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); { gint pos = bytes_to_offset (priv->text, index_); - clutter_text_set_cursor_position (self, pos); + clutter_text_set_cursor_position (self, pos + trailing); } + /* Store the target x position to avoid drifting left and right when + moving the cursor up and down */ + priv->x_pos = x; + if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) clutter_text_clear_selection (self); @@ -3290,6 +3305,10 @@ clutter_text_set_cursor_position (ClutterText *self, else priv->position = position; + /* Forget the target x position so that it will be recalculated next + time the cursor is moved up or down */ + priv->x_pos = -1; + if (CLUTTER_ACTOR_IS_VISIBLE (self)) clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); } diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 086a5134c..d081b3889 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -96,6 +96,13 @@ struct _ClutterTexturePrivate guint repeat_y : 1; guint in_dispose : 1; guint keep_aspect_ratio : 1; + guint load_async : 1; + + GThread *load_thread; + guint load_idle; + gchar *load_filename; + CoglBitmap *load_bitmap; + GError *load_error; }; enum @@ -110,13 +117,17 @@ enum PROP_FILTER_QUALITY, PROP_COGL_TEXTURE, PROP_FILENAME, - PROP_KEEP_ASPECT_RATIO + PROP_KEEP_ASPECT_RATIO, + PROP_LOAD_ASYNC }; enum { SIZE_CHANGE, PIXBUF_CHANGE, + LOAD_SUCCESS, + LOAD_FINISHED, + LAST_SIGNAL }; @@ -252,8 +263,8 @@ clutter_texture_realize (ClutterActor *actor) if (priv->texture != COGL_INVALID_HANDLE) cogl_texture_unref (priv->texture); - priv->texture - = cogl_texture_new_with_size + priv->texture = + cogl_texture_new_with_size (priv->width, priv->height, priv->no_slice ? -1 : priv->max_tile_waste, @@ -601,6 +612,45 @@ clutter_texture_paint (ClutterActor *self) 0, 0, t_w, t_h); } +/* + * clutter_texture_async_load_cancel: + * @texture: a #ClutterTexture + * + * Cancels an asynchronous loading operation, whether done + * with threads enabled or just using the main loop + */ +static void +clutter_texture_async_load_cancel (ClutterTexture *texture) +{ + ClutterTexturePrivate *priv = texture->priv; + + if (priv->load_thread) + { + g_thread_join (priv->load_thread); + priv->load_thread = NULL; + } + + if (priv->load_idle) + { + g_source_remove (priv->load_idle); + priv->load_idle = 0; + } + + if (priv->load_error) + { + g_error_free (priv->load_error); + priv->load_error = NULL; + } + + if (priv->load_bitmap) + { + cogl_bitmap_free (priv->load_bitmap); + priv->load_bitmap = NULL; + } + + g_free (priv->load_filename); +} + static void clutter_texture_dispose (GObject *object) { @@ -625,7 +675,9 @@ clutter_texture_dispose (GObject *object) g_free (priv->local_data); priv->local_data = NULL; } - + + clutter_texture_async_load_cancel (texture); + G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); } @@ -686,6 +738,9 @@ clutter_texture_set_property (GObject *object, case PROP_KEEP_ASPECT_RATIO: priv->keep_aspect_ratio = g_value_get_boolean (value); break; + case PROP_LOAD_ASYNC: + priv->load_async = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -736,6 +791,9 @@ clutter_texture_get_property (GObject *object, case PROP_KEEP_ASPECT_RATIO: g_value_set_boolean (value, priv->keep_aspect_ratio); break; + case PROP_LOAD_ASYNC: + g_value_set_boolean (value, priv->load_async); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -861,6 +919,29 @@ clutter_texture_class_init (ClutterTextureClass *klass) FALSE, CLUTTER_PARAM_READWRITE)); + /** + * ClutterTexture:load-async: + * + * Tries to load a texture from a filename by using a local thread + * to perform the read operations. Threading is only enabled if + * g_thread_init() has been called prior to clutter_init(), otherwise + * #ClutterTexture will use the main loop to load the image. + * + * The upload of the texture data on the GL pipeline is not + * asynchronous, as it must be performed from within the same + * thread that called clutter_main(). + * + * Since: 1.0 + */ + g_object_class_install_property + (gobject_class, PROP_LOAD_ASYNC, + g_param_spec_boolean ("load-async", + "Load asynchronously", + "Load files inside a thread to avoid blocking when " + "loading images.", + FALSE, + CLUTTER_PARAM_READWRITE)); + /** * ClutterTexture::size-change: * @texture: the texture which received the signal @@ -896,6 +977,27 @@ clutter_texture_class_init (ClutterTextureClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /** + * ClutterTexture::load-finished: + * @texture: the texture which received the signal + * @error: A set error, or %NULL + * + * The ::load-finished signal is emitted when a texture load has + * completed. If there was an error during loading, @error will + * be set, otherwise it will be %NULL + * + * Since: 1.0 + */ + texture_signals[LOAD_FINISHED] = + g_signal_new (I_("load-finished"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTextureClass, load_finished), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); } static ClutterScriptableIface *parent_scriptable_iface = NULL; @@ -1168,6 +1270,8 @@ clutter_texture_set_from_data (ClutterTexture *texture, cogl_texture_unref (new_texture); + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); + return TRUE; } @@ -1262,14 +1366,14 @@ clutter_texture_set_from_rgb_data (ClutterTexture *texture, * Return value: %TRUE if the texture was successfully updated * * Since: 0.4 - **/ + */ gboolean -clutter_texture_set_from_yuv_data (ClutterTexture *texture, - const guchar *data, - gint width, - gint height, - ClutterTextureFlags flags, - GError **error) +clutter_texture_set_from_yuv_data (ClutterTexture *texture, + const guchar *data, + gint width, + gint height, + ClutterTextureFlags flags, + GError **error) { ClutterTexturePrivate *priv; @@ -1301,6 +1405,188 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture, error); } +/* + * clutter_texture_async_load_complete: + * @self: a #ClutterTexture + * @error: load error + * + * If @error is %NULL, loads the #CoglBitmap into a #CoglTexture. + * + * This function emits the ::load-finished signal on @self. + */ +static void +clutter_texture_async_load_complete (ClutterTexture *self, + const GError *error) +{ + ClutterTexturePrivate *priv = self->priv; + CoglHandle handle; + gboolean enable_mipmap = FALSE; + gint waste = -1; + + if (error == NULL) + { + if (priv->no_slice) + waste = priv->max_tile_waste; + + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + enable_mipmap = TRUE; + + handle = cogl_texture_new_from_bitmap (priv->load_bitmap, + waste, enable_mipmap, + COGL_PIXEL_FORMAT_ANY); + clutter_texture_set_cogl_texture (self, handle); + cogl_texture_unref (handle); + + cogl_bitmap_free (priv->load_bitmap); + priv->load_bitmap = NULL; + } + + g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error); + + clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); +} + +static gboolean +clutter_texture_thread_cb (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + + priv->load_idle = 0; + + if (priv->load_thread) + { + g_thread_join (priv->load_thread); + priv->load_thread = NULL; + } + else + return FALSE; + + clutter_texture_async_load_complete (self, priv->load_error); + + if (priv->load_error) + { + g_error_free (priv->load_error); + priv->load_error = NULL; + } + + return FALSE; +} + +static gpointer +clutter_texture_thread_func (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + + /* Try loading with imaging backend */ + priv->load_bitmap = cogl_bitmap_new_from_file (priv->load_filename, + &priv->load_error); + g_free (priv->load_filename); + priv->load_filename = NULL; + + /* make sure we load the image in the main thread, where we + * hold the main Clutter lock + */ + priv->load_idle = + clutter_threads_add_idle (clutter_texture_thread_cb, self); + + return NULL; +} + +static gboolean +clutter_texture_idle_func (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + GError *internal_error; + + internal_error = NULL; + priv->load_bitmap = cogl_bitmap_new_from_file (priv->load_filename, + &internal_error); + + clutter_texture_async_load_complete (self, internal_error); + + g_free (priv->load_filename); + priv->load_filename = NULL; + + if (internal_error) + g_error_free (internal_error); + + return FALSE; +} + +/* + * clutter_texture_async_load: + * @self: a #ClutterTexture + * @error: return location for a #GError + * + * Starts an asynchronous load of the file name stored inside + * the load_filename private member. + * + * If threading is enabled we use a GThread to perform the actual + * I/O; if threading is not enabled, we use an idle GSource. + * + * The I/O is the only bit done in a thread -- uploading the + * texture data to the GL pipeline must be done from within the + * same thread that called clutter_main(). Threaded upload should + * be part of the GL implementation. + * + * This function will block until we get a size from the file + * so that we can effectively get the size the texture actor after + * clutter_texture_set_from_file(). + * + * Return value: %TRUE if the asynchronous loading was successfully + * initiated, %FALSE otherwise + */ +static gboolean +clutter_texture_async_load (ClutterTexture *self, + GError **error) +{ + ClutterTexturePrivate *priv = self->priv; + gint width, height; + gboolean res; + + g_assert (priv->load_filename != NULL); + + /* ask the file for a size; if we cannot get the size then + * there's no point in even continuing the asynchronous + * loading, so we just stop there + */ + res = cogl_bitmap_get_size_from_file (priv->load_filename, + &width, + &height); + if (!res) + { + g_set_error (error, CLUTTER_TEXTURE_ERROR, + CLUTTER_TEXTURE_ERROR_BAD_FORMAT, + "Failed to create COGL texture"); + return FALSE; + } + else + { + priv->width = width; + priv->height = height; + } + + if (g_thread_supported ()) + { + priv->load_thread = + g_thread_create ((GThreadFunc) clutter_texture_thread_func, + self, TRUE, + error); + + return priv->load_thread != NULL? TRUE : FALSE; + } + else + { + priv->load_idle = + clutter_threads_add_idle (clutter_texture_idle_func, self); + + return TRUE; + } +} + /** * clutter_texture_set_from_file: * @texture: A #ClutterTexture @@ -1310,6 +1596,12 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture, * Sets the #ClutterTexture image data from an image file. In case of * failure, %FALSE is returned and @error is set. * + * If #ClutterTexture:load-async is set to %TRUE, this function + * will return as soon as possible, and the actual image loading + * from disk will be performed asynchronously. #ClutterTexture::load-finished + * will be emitted when the image has been loaded or if an error + * occurred. + * * Return value: %TRUE if the image was successfully loaded and set * * Since: 0.8 @@ -1319,28 +1611,48 @@ clutter_texture_set_from_file (ClutterTexture *texture, const gchar *filename, GError **error) { - CoglHandle new_texture; - ClutterTexturePrivate *priv; + ClutterTexturePrivate *priv; + CoglHandle new_texture = COGL_INVALID_HANDLE; + GError *internal_error = NULL; + gboolean enable_mipmap = FALSE; + gint max_waste = -1; priv = texture->priv; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if ((new_texture = cogl_texture_new_from_file - (filename, - priv->no_slice ? -1 : priv->max_tile_waste, - priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, - COGL_PIXEL_FORMAT_ANY, - error)) - == COGL_INVALID_HANDLE) + if (priv->load_async) + { + clutter_texture_async_load_cancel (texture); + + priv->load_filename = g_strdup (filename); + + return clutter_texture_async_load (texture, error); + } + + if (priv->no_slice) + max_waste = priv->max_tile_waste; + + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + enable_mipmap = TRUE; + + new_texture = cogl_texture_new_from_file (filename, + max_waste, enable_mipmap, + COGL_PIXEL_FORMAT_ANY, + &internal_error); + if (new_texture == COGL_INVALID_HANDLE) { /* If COGL didn't give an error then make one up */ - if (error && *error == NULL) + if (internal_error == NULL) { g_set_error (error, CLUTTER_TEXTURE_ERROR, CLUTTER_TEXTURE_ERROR_BAD_FORMAT, "Failed to create COGL texture"); } + else + g_propagate_error (error, internal_error); + + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); return FALSE; } @@ -1353,6 +1665,8 @@ clutter_texture_set_from_file (ClutterTexture *texture, cogl_texture_unref (new_texture); + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); + return TRUE; } @@ -1714,7 +2028,7 @@ on_fbo_source_size_change (GObject *object, return; } - clutter_actor_set_size (CLUTTER_ACTOR(texture), w, h); + clutter_actor_set_size (CLUTTER_ACTOR (texture), w, h); } } @@ -1889,9 +2203,9 @@ clutter_texture_new_from_actor (ClutterActor *actor) priv->width = w; priv->height = h; - clutter_actor_set_size (CLUTTER_ACTOR(texture), priv->width, priv->height); + clutter_actor_set_size (CLUTTER_ACTOR (texture), priv->width, priv->height); - return CLUTTER_ACTOR(texture); + return CLUTTER_ACTOR (texture); } static void diff --git a/clutter/clutter-texture.h b/clutter/clutter-texture.h index e15f798b1..3f20413e8 100644 --- a/clutter/clutter-texture.h +++ b/clutter/clutter-texture.h @@ -84,6 +84,8 @@ struct _ClutterTextureClass gint width, gint height); void (*pixbuf_change) (ClutterTexture *texture); + void (*load_finished) (ClutterTexture *texture, + GError *error); /*< private >*/ /* padding, for future expansion */ @@ -92,7 +94,6 @@ struct _ClutterTextureClass void (*_clutter_texture3) (void); void (*_clutter_texture4) (void); void (*_clutter_texture5) (void); - void (*_clutter_texture6) (void); }; /** diff --git a/clutter/clutter-units.h b/clutter/clutter-units.h index 8337d19ff..b85375a98 100644 --- a/clutter/clutter-units.h +++ b/clutter/clutter-units.h @@ -59,6 +59,8 @@ typedef gint32 ClutterUnit; #define CLUTTER_UNITS_FROM_FIXED(x) (x) #define CLUTTER_UNITS_TO_FIXED(x) (x) +#define CLUTTER_UNITS_FORMAT "d" + /** * CLUTTER_UNITS_FROM_DEVICE: * @x: value in pixels diff --git a/clutter/clutter.h b/clutter/clutter.h index 817dbef6c..478d7b19f 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -30,6 +30,7 @@ #include "clutter-actor.h" #include "clutter-alpha.h" +#include "clutter-animatable.h" #include "clutter-animation.h" #include "clutter-backend.h" #include "clutter-behaviour-depth.h" @@ -46,7 +47,6 @@ #include "clutter-color.h" #include "clutter-container.h" #include "clutter-deprecated.h" -#include "clutter-effect.h" #include "clutter-event.h" #include "clutter-feature.h" #include "clutter-frame-source.h" diff --git a/clutter/cogl/cogl-texture.h b/clutter/cogl/cogl-texture.h index 3ca0d8137..cee2f439e 100644 --- a/clutter/cogl/cogl-texture.h +++ b/clutter/cogl/cogl-texture.h @@ -134,6 +134,26 @@ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLuint y_pot_waste, CoglPixelFormat format); +/** + * cogl_texture_new_from_bitmap: + * @handle: handle of the preloaded texture. + * @max_waste: maximum extra horizontal and|or vertical margin pixels to make + * texture fit GPU limitations. + * @auto_mipmap: enable or disable automatic generation of mipmap pyramid + * from the base level image whenever it is updated. + * @internal_format: the #CoglPixelFormat to use for the GPU storage of the + * texture. + * + * Create a cogl texture from a #CoglBitmap. + * + * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE + * if creating the texture failed. + */ +CoglHandle cogl_texture_new_from_bitmap (CoglBitmap *bitmap, + gint max_waste, + gboolean auto_mipmap, + CoglPixelFormat internal_format); + /** * cogl_is_texture: * @handle: A CoglHandle @@ -385,6 +405,45 @@ void cogl_texture_polygon (CoglHandle handle, CoglTextureVertex *vertices, gboolean use_color); +/** + * cogl_bitmap_new_from_file: + * @filename: the file to load. + * @error: a #GError or %NULL. + * + * Load an image file from disk. This function can be safely called from + * within a thread. + * + * Returns: A #CoglBitmap to the new loaded image data, or %NULL if loading + * the image failed. + * + * Since: 1.0 + */ +CoglBitmap * cogl_bitmap_new_from_file (const gchar *filename, + GError **error); + +/** + * cogl_bitmap_get_size_from_file: + * @filename: the file to check + * @width: return location for the bitmap width + * @height: return location for the bitmap height + * + * Parses an image file enough to extract the width and height + * of the bitmap. + * + * Since: 1.0 + */ +gboolean cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height); + +/** + * cogl_bitmap_free: + * @bmp: a #CoglBitmap. + * + * Frees a #CoglBitmap. + */ +void cogl_bitmap_free (CoglBitmap *bmp); + /** * cogl_texture_multiple_rectangles: * @handle: a @CoglHandle. @@ -401,7 +460,7 @@ void cogl_texture_polygon (CoglHandle handle, * parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same * meaning as in cogl_texture_rectangle(). * - * Since: 1.0 + * Since: 0.8.6 */ void cogl_texture_multiple_rectangles (CoglHandle handle, diff --git a/clutter/cogl/cogl-types.h b/clutter/cogl/cogl-types.h index 4fb69953a..ece3270b7 100644 --- a/clutter/cogl/cogl-types.h +++ b/clutter/cogl/cogl-types.h @@ -28,6 +28,13 @@ G_BEGIN_DECLS +/** + * CoglBitmap: + * + * Type used for storing image data. + */ +typedef struct _CoglBitmap CoglBitmap; + /** * CoglHandle: * @@ -86,27 +93,29 @@ typedef struct _CoglTextureVertex CoglTextureVertex; /** * CoglPixelFormat: - * @COGL_PIXEL_FORMAT_ANY: - * @COGL_PIXEL_FORMAT_A_8: - * @COGL_PIXEL_FORMAT_RGB_888: - * @COGL_PIXEL_FORMAT_BGR_888: - * @COGL_PIXEL_FORMAT_RGBA_8888: - * @COGL_PIXEL_FORMAT_BGRA_8888: - * @COGL_PIXEL_FORMAT_ARGB_8888: - * @COGL_PIXEL_FORMAT_ABGR_8888: - * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: - * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: - * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: - * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: - * @COGL_PIXEL_FORMAT_RGB_565: - * @COGL_PIXEL_FORMAT_RGBA_4444: - * @COGL_PIXEL_FORMAT_RGBA_5551: - * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: - * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: - * @COGL_PIXEL_FORMAT_YUV: - * @COGL_PIXEL_FORMAT_G_8: + * @COGL_PIXEL_FORMAT_ANY: Any format + * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask + * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits + * @COGL_PIXEL_FORMAT_YUV: FIXME + * @COGL_PIXEL_FORMAT_G_8: FIXME + * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits + * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits + * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits + * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits + * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits + * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits + * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits + * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits + * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits + * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits + * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits * * Pixel formats used by COGL. + * + * Since: 0.8 */ typedef enum { @@ -173,19 +182,21 @@ typedef enum /** * CoglFeatureFlags: - * @COGL_FEATURE_TEXTURE_RECTANGLE: - * @COGL_FEATURE_TEXTURE_NPOT: - * @COGL_FEATURE_TEXTURE_YUV: - * @COGL_FEATURE_TEXTURE_READ_PIXELS: - * @COGL_FEATURE_SHADERS_GLSL: - * @COGL_FEATURE_OFFSCREEN: - * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: - * @COGL_FEATURE_OFFSCREEN_BLIT: - * @COGL_FEATURE_FOUR_CLIP_PLANES: - * @COGL_FEATURE_STENCIL_BUFFER: - * @COGL_FEATURE_VBOS: + * @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support + * @COGL_FEATURE_TEXTURE_NPOT: ARB_texture_non_power_of_two support + * @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support + * @COGL_FEATURE_TEXTURE_READ_PIXELS: glReadPixels() support + * @COGL_FEATURE_SHADERS_GLSL: GLSL support + * @COGL_FEATURE_OFFSCREEN: FBO support + * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs + * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs + * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available + * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support + * @COGL_FEATURE_VBOS: VBO support * * Flags for the supported features. + * + * Since: 0.8 */ typedef enum { @@ -204,11 +215,13 @@ typedef enum /** * CoglBufferTarget: - * @COGL_WINDOW_BUFFER: - * @COGL_MASK_BUFFER: - * @COGL_OFFSCREEN_BUFFER: + * @COGL_WINDOW_BUFFER: FIXME + * @COGL_MASK_BUFFER: FIXME + * @COGL_OFFSCREEN_BUFFER: FIXME * + * Target flags for FBOs. * + * Since: 0.8 */ typedef enum { diff --git a/clutter/cogl/common/Makefile.am b/clutter/cogl/common/Makefile.am index db0f0b42d..fb2adf28f 100644 --- a/clutter/cogl/common/Makefile.am +++ b/clutter/cogl/common/Makefile.am @@ -5,6 +5,7 @@ INCLUDES = \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_builddir)/clutter \ -I$(top_builddir)/clutter/cogl \ + -DG_LOG_DOMAIN=\"Cogl-Common\" \ -DCLUTTER_COMPILATION \ $(CLUTTER_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \ diff --git a/clutter/cogl/common/cogl-bitmap-pixbuf.c b/clutter/cogl/common/cogl-bitmap-pixbuf.c index 77316dff5..8d86d94e4 100644 --- a/clutter/cogl/common/cogl-bitmap-pixbuf.c +++ b/clutter/cogl/common/cogl-bitmap-pixbuf.c @@ -84,6 +84,20 @@ cogl_bitmap_error_quark (void) return g_quark_from_static_string ("cogl-bitmap-error-quark"); } +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + if (width) + *width = 0; + + if (height) + *height = 0; + + return TRUE; +} + /* the error does not contain the filename as the caller already has it */ gboolean _cogl_bitmap_from_file (CoglBitmap *bmp, @@ -177,9 +191,22 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, #elif defined(USE_GDKPIXBUF) gboolean -_cogl_bitmap_from_file (CoglBitmap *bmp, - const gchar *filename, - GError **error) +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + g_return_val_if_fail (filename != NULL, FALSE); + + if (gdk_pixbuf_get_file_info (filename, width, height) != NULL) + return TRUE; + + return FALSE; +} + +gboolean +_cogl_bitmap_from_file (CoglBitmap *bmp, + const gchar *filename, + GError **error) { GdkPixbuf *pixbuf; gboolean has_alpha; @@ -198,11 +225,13 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (bmp == NULL) return FALSE; - + if (bmp == NULL) + return FALSE; + /* Load from file using GdkPixbuf */ pixbuf = gdk_pixbuf_new_from_file (filename, error); - if (pixbuf == NULL) return FALSE; + if (pixbuf == NULL) + return FALSE; /* Get pixbuf properties */ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); @@ -278,6 +307,20 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, #include "stb_image.c" +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + if (width) + *width = 0; + + if (height) + *height = 0; + + return TRUE; +} + gboolean _cogl_bitmap_from_file (CoglBitmap *bmp, const gchar *filename, @@ -290,11 +333,15 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (bmp == NULL) return FALSE; + if (bmp == NULL) + return FALSE; /* Load from file using stb */ - pixels = stbi_load (filename, &width, &height, &stb_pixel_format, STBI_rgb_alpha); - if (pixels == NULL) return FALSE; + pixels = stbi_load (filename, + &width, &height, &stb_pixel_format, + STBI_rgb_alpha); + if (pixels == NULL) + return FALSE; /* Store bitmap info */ bmp->data = g_memdup (pixels, height * width * 4); diff --git a/clutter/cogl/common/cogl-bitmap.c b/clutter/cogl/common/cogl-bitmap.c index 39341e0b0..b0a3b7138 100644 --- a/clutter/cogl/common/cogl-bitmap.c +++ b/clutter/cogl/common/cogl-bitmap.c @@ -148,3 +148,42 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, dstdata += dst->rowstride; } } + +gboolean +cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + return _cogl_bitmap_get_size_from_file (filename, width, height); +} + +CoglBitmap * +cogl_bitmap_new_from_file (const gchar *filename, + GError **error) +{ + CoglBitmap bmp; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + /* Try loading with imaging backend */ + if (!_cogl_bitmap_from_file (&bmp, filename, error)) + { + /* Try fallback */ + if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) + return NULL; + else if (error && *error) + { + g_error_free (*error); + *error = NULL; + } + } + + return (CoglBitmap *) g_memdup (&bmp, sizeof (CoglBitmap)); +} + +void +cogl_bitmap_free (CoglBitmap *bmp) +{ + g_free (bmp->data); + g_free (bmp); +} diff --git a/clutter/cogl/common/cogl-bitmap.h b/clutter/cogl/common/cogl-bitmap.h index ca9f8a9c3..953ac5a32 100644 --- a/clutter/cogl/common/cogl-bitmap.h +++ b/clutter/cogl/common/cogl-bitmap.h @@ -28,8 +28,6 @@ #include -typedef struct _CoglBitmap CoglBitmap; - struct _CoglBitmap { guchar *data; @@ -92,4 +90,9 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, gint width, gint height); +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height); + #endif /* __COGL_BITMAP_H */ diff --git a/clutter/cogl/common/cogl-mesh.c b/clutter/cogl/common/cogl-mesh.c index 88a0ba473..f7287f953 100644 --- a/clutter/cogl/common/cogl-mesh.c +++ b/clutter/cogl/common/cogl-mesh.c @@ -209,6 +209,8 @@ COGL_HANDLE_DEFINE (Mesh, mesh, mesh_handles); * * This creates a Cogl handle for a new mesh that you can then start to add * attributes too. + * + * Return value: a new #CoglHandle */ CoglHandle cogl_mesh_new (guint n_vertices) diff --git a/clutter/cogl/gl/Makefile.am b/clutter/cogl/gl/Makefile.am index 2d90ba9c0..7635b1b90 100644 --- a/clutter/cogl/gl/Makefile.am +++ b/clutter/cogl/gl/Makefile.am @@ -20,6 +20,7 @@ INCLUDES = \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_builddir)/clutter \ -I$(top_builddir)/clutter/cogl \ + -DG_LOG_DOMAIN=\"Cogl-GL\" \ -DCLUTTER_COMPILATION \ $(CLUTTER_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \ diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c index a27a8b253..4c30639a9 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -1323,30 +1323,13 @@ cogl_texture_new_from_data (guint width, } CoglHandle -cogl_texture_new_from_file (const gchar *filename, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format, - GError **error) +cogl_texture_new_from_bitmap (CoglBitmap *bmp, + gint max_waste, + gboolean auto_mipmap, + CoglPixelFormat internal_format) { - CoglBitmap bmp; CoglTexture *tex; - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - - /* Try loading with imaging backend */ - if (!_cogl_bitmap_from_file (&bmp, filename, error)) - { - /* Try fallback */ - if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) - return COGL_INVALID_HANDLE; - else if (error && *error) - { - g_error_free (*error); - *error = NULL; - } - } - /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); @@ -1356,8 +1339,9 @@ cogl_texture_new_from_file (const gchar *filename, tex->is_foreign = FALSE; tex->auto_mipmap = auto_mipmap; - tex->bitmap = bmp; + tex->bitmap = *bmp; tex->bitmap_owner = TRUE; + bmp->data = NULL; tex->slice_x_spans = NULL; tex->slice_y_spans = NULL; @@ -1398,6 +1382,30 @@ cogl_texture_new_from_file (const gchar *filename, return _cogl_texture_handle_new (tex); } +CoglHandle +cogl_texture_new_from_file (const gchar *filename, + gint max_waste, + gboolean auto_mipmap, + CoglPixelFormat internal_format, + GError **error) +{ + CoglBitmap *bmp; + CoglHandle handle; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + if (!(bmp = cogl_bitmap_new_from_file (filename, error))) + return COGL_INVALID_HANDLE; + + handle = cogl_texture_new_from_bitmap (bmp, + max_waste, + auto_mipmap, + internal_format); + cogl_bitmap_free (bmp); + + return handle; +} + CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLenum gl_target, diff --git a/clutter/cogl/gles/Makefile.am b/clutter/cogl/gles/Makefile.am index 19cf0a0d7..1731d2cb5 100644 --- a/clutter/cogl/gles/Makefile.am +++ b/clutter/cogl/gles/Makefile.am @@ -20,6 +20,7 @@ INCLUDES = \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_builddir)/clutter \ -I$(top_builddir)/clutter/cogl \ + -DG_LOG_DOMAIN=\"Cogl-GLES\" \ -DCLUTTER_COMPILATION \ $(CLUTTER_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \ diff --git a/clutter/cogl/gles/cogl-context.h b/clutter/cogl/gles/cogl-context.h index 5d835712a..92b8b96a2 100644 --- a/clutter/cogl/gles/cogl-context.h +++ b/clutter/cogl/gles/cogl-context.h @@ -72,6 +72,7 @@ typedef struct can be flushed */ GLuint texture_current; GLenum texture_target; + GLenum texture_format; /* Framebuffer objects */ GArray *fbo_handles; diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.c b/clutter/cogl/gles/cogl-gles2-wrapper.c index fea76500e..d43ad21da 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.c +++ b/clutter/cogl/gles/cogl-gles2-wrapper.c @@ -891,8 +891,8 @@ cogl_gles2_do_set_uniform (GLint location, CoglBoxedValue *value) } } -void -cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) +static void +cogl_wrap_prepare_for_draw (void) { CoglGles2WrapperProgram *program; @@ -999,9 +999,25 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) w->dirty_custom_uniforms = 0; } +} + +void +cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) +{ + cogl_wrap_prepare_for_draw (); + glDrawArrays (mode, first, count); } +void +cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + cogl_wrap_prepare_for_draw (); + + glDrawElements (mode, count, type, indices); +} + void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, GLenum internal_format) diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.h b/clutter/cogl/gles/cogl-gles2-wrapper.h index 514b89cc4..05f7c600f 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.h +++ b/clutter/cogl/gles/cogl-gles2-wrapper.h @@ -250,7 +250,8 @@ void cogl_wrap_glFogx (GLenum pname, GLfixed param); void cogl_wrap_glFogxv (GLenum pname, const GLfixed *params); void cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count); - +void cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); void cogl_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param); void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, @@ -274,6 +275,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program); #define cogl_wrap_glClearColorx glClearColor #define cogl_wrap_glDrawArrays glDrawArrays +#define cogl_wrap_glDrawElements glDrawElements #define cogl_wrap_glPushMatrix glPushMatrix #define cogl_wrap_glPopMatrix glPopMatrix #define cogl_wrap_glMatrixMode glMatrixMode diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c index 915e82b23..7de709507 100644 --- a/clutter/cogl/gles/cogl-texture.c +++ b/clutter/cogl/gles/cogl-texture.c @@ -44,6 +44,7 @@ #define glTexCoordPointer cogl_wrap_glTexCoordPointer #define glColorPointer cogl_wrap_glColorPointer #define glDrawArrays cogl_wrap_glDrawArrays +#define glDrawElements cogl_wrap_glDrawElements #define glTexParameteri cogl_wrap_glTexParameteri /* @@ -1446,30 +1447,13 @@ cogl_texture_new_from_data (guint width, } CoglHandle -cogl_texture_new_from_file (const gchar *filename, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format, - GError **error) +cogl_texture_new_from_bitmap (CoglBitmap *bmp, + gint max_waste, + gboolean auto_mipmap, + CoglPixelFormat internal_format) { - CoglBitmap bmp; CoglTexture *tex; - - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - /* Try loading with imaging backend */ - if (!_cogl_bitmap_from_file (&bmp, filename, error)) - { - /* Try fallback */ - if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) - return COGL_INVALID_HANDLE; - else if (error && *error) - { - g_error_free (*error); - *error = NULL; - } - } - /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); @@ -1479,8 +1463,9 @@ cogl_texture_new_from_file (const gchar *filename, tex->is_foreign = FALSE; tex->auto_mipmap = auto_mipmap; - tex->bitmap = bmp; + tex->bitmap = *bmp; tex->bitmap_owner = TRUE; + bmp->data = NULL; tex->slice_x_spans = NULL; tex->slice_y_spans = NULL; @@ -1521,6 +1506,30 @@ cogl_texture_new_from_file (const gchar *filename, return _cogl_texture_handle_new (tex); } +CoglHandle +cogl_texture_new_from_file (const gchar *filename, + gint max_waste, + gboolean auto_mipmap, + CoglPixelFormat internal_format, + GError **error) +{ + CoglBitmap *bmp; + CoglHandle handle; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + if (!(bmp = cogl_bitmap_new_from_file (filename, error))) + return COGL_INVALID_HANDLE; + + handle = cogl_texture_new_from_bitmap (bmp, + max_waste, + auto_mipmap, + internal_format); + cogl_bitmap_free (bmp); + + return handle; +} + CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLenum gl_target, @@ -2094,7 +2103,9 @@ _cogl_texture_flush_vertices (void) GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) ); - GE( glBindTexture (ctx->texture_target, ctx->texture_current) ); + GE( cogl_gles2_wrapper_bind_texture (ctx->texture_target, + ctx->texture_current, + ctx->texture_format) ); GE( glDrawElements (GL_TRIANGLES, needed_indices, GL_UNSIGNED_SHORT, @@ -2284,6 +2295,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_flush_vertices (); ctx->texture_target = tex->gl_target; ctx->texture_current = gl_handle; + ctx->texture_format = tex->gl_intformat; _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1), COGL_FIXED_TO_FLOAT (slice_qy1), @@ -2328,6 +2340,7 @@ _cogl_texture_quad_hw (CoglTexture *tex, _cogl_texture_flush_vertices (); ctx->texture_target = tex->gl_target; ctx->texture_current = gl_handle; + ctx->texture_format = tex->gl_intformat; /* Don't include the waste in the texture coordinates */ x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index 280f34216..ecc6e8dd9 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -317,8 +317,25 @@ create_cogl_texture (ClutterTexture *texture, { ClutterGLXTexturePixmap *texture_glx = CLUTTER_GLX_TEXTURE_PIXMAP (texture); ClutterGLXTexturePixmapPrivate *priv = texture_glx->priv; - CoglHandle handle; - gboolean using_rectangle; + CoglHandle handle; + gboolean using_rectangle; + GLint gl_format; + CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_RGBA_8888; + guint depth; + + g_object_get (G_OBJECT (texture_glx), "pixmap-depth", &depth, NULL); + if (depth == 32) + { + gl_format = GL_RGBA; + cogl_format = COGL_PIXEL_FORMAT_RGBA_8888; + } + else if (depth == 24) + { + gl_format = GL_RGB; + cogl_format = COGL_PIXEL_FORMAT_RGB_888; + } + else + g_critical ("Can't create a TFP cogl texture for pixmap with depth < 24"); /* We want to use the GL_ARB_texture_rectangle extension on some chipsets because GL_ARB_texture_non_power_of_two is not always @@ -332,21 +349,20 @@ create_cogl_texture (ClutterTexture *texture, glGenTextures (1, &tex); glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex); glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0, - GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + GL_RGB, width, height, + 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); handle = cogl_texture_new_from_foreign (tex, CGL_TEXTURE_RECTANGLE_ARB, width, height, 0, 0, - COGL_PIXEL_FORMAT_RGBA_8888 - | COGL_BGR_BIT); + cogl_format | COGL_BGR_BIT); } else { handle = cogl_texture_new_with_size (width, height, -1, FALSE, - COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT); + cogl_format | COGL_BGR_BIT); using_rectangle = FALSE; } diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 06e27e766..0f75daf2c 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -427,17 +427,21 @@ event_translate (ClutterBackend *backend, case ConfigureNotify: if (!stage_x11->is_foreign_xwin) { - /* Set a flag so that the stage will know the actor is being - resized in response to the window size changing as - opposed to a request from the application. This prevents - it from trying to resize the window again */ - stage_x11->handling_configure = TRUE; + CLUTTER_NOTE (BACKEND, "%s: ConfigureNotify[%x] (%d, %d)", + G_STRLOC, + (unsigned int) stage_x11->xwin, + xevent->xconfigure.width, + xevent->xconfigure.height); clutter_actor_set_size (CLUTTER_ACTOR (stage), xevent->xconfigure.width, xevent->xconfigure.height); - stage_x11->handling_configure = FALSE; + /* the resize process is complete, so we can ask the stage + * to set up the GL viewport with the new size + */ + CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), + CLUTTER_ACTOR_SYNC_MATRICES); } res = FALSE; break; diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 010063951..725a75650 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -270,25 +270,20 @@ clutter_stage_x11_allocate (ClutterActor *self, stage_x11->xwin_width = new_width; stage_x11->xwin_height = new_height; - /* The 'handling_configure' flag below is used to prevent the - window from being resized again in response to a - ConfigureNotify event. Normally this will not be a problem - because the window will be resized to xwin_width and - xwin_height so the above test will prevent it from resizing - the window a second time. However if the stage is resized - multiple times without the events being processed in between - (eg, when calling g_object_set to set both width and height) - then there will be multiple ConfigureNotify events in the - queue. Handling the first event will undo the work of setting - the second property which will cause it to keep generating - events in an infinite loop. See bug #810 */ - if (stage_x11->xwin != None - && !stage_x11->is_foreign_xwin - && !stage_x11->handling_configure) - XResizeWindow (stage_x11->xdpy, - stage_x11->xwin, - stage_x11->xwin_width, - stage_x11->xwin_height); + if (stage_x11->xwin != None && + !stage_x11->is_foreign_xwin) + { + CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)", + G_STRLOC, + (unsigned int) stage_x11->xwin, + stage_x11->xwin_width, + stage_x11->xwin_height); + + XResizeWindow (stage_x11->xdpy, + stage_x11->xwin, + stage_x11->xwin_width, + stage_x11->xwin_height); + } clutter_stage_x11_fix_window_size (stage_x11); @@ -298,9 +293,6 @@ clutter_stage_x11_allocate (ClutterActor *self, clutter_actor_unrealize (self); clutter_actor_realize (self); } - - CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), - CLUTTER_ACTOR_SYNC_MATRICES); } /* chain up to fill in actor->priv->allocation */ @@ -397,6 +389,8 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window, if (!stage) return; + CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); + if (is_fullscreen) { int width, height; @@ -479,8 +473,6 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window, stage_x11->fullscreen_on_map = FALSE; } } - - CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } static void @@ -572,7 +564,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->is_foreign_xwin = FALSE; stage->fullscreen_on_map = FALSE; - stage->handling_configure = FALSE; stage->is_cursor_visible = TRUE; stage->title = NULL; @@ -740,6 +731,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage, clutter_actor_set_geometry (actor, &geom); clutter_actor_realize (actor); + CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES); + return TRUE; } @@ -769,4 +762,3 @@ clutter_stage_x11_unmap (ClutterStageX11 *stage_x11) CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED); CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_MAPPED); } - diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 229f058e1..c1a913950 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -47,7 +47,6 @@ struct _ClutterStageX11 guint is_foreign_xwin : 1; guint fullscreen_on_map : 1; - guint handling_configure : 1; guint is_cursor_visible : 1; Display *xdpy; diff --git a/doc/reference/clutter/clutter-docs.xml b/doc/reference/clutter/clutter-docs.xml index e29317036..a9ecc8a0f 100644 --- a/doc/reference/clutter/clutter-docs.xml +++ b/doc/reference/clutter/clutter-docs.xml @@ -57,8 +57,8 @@ - + @@ -105,6 +105,7 @@ + diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 7c9ed607b..2f66645de 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -28,6 +28,7 @@ clutter_media_get_type clutter-units Unit conversion ClutterUnit +CLUTTER_UNITS_FORMAT CLUTTER_UNITS_FROM_DEVICE CLUTTER_UNITS_TO_DEVICE CLUTTER_UNITS_FROM_FIXED @@ -168,6 +169,35 @@ ClutterCloneTexturePrivate clutter_clone_texture_get_type +
+clutter-cairo-texture +ClutterCairoTexture +ClutterCairoTexture +ClutterCairoTextureClass +clutter_cairo_texture_new +clutter_cairo_texture_set_surface_size +clutter_cairo_texture_get_surface_size + + +clutter_cairo_texture_create +clutter_cairo_texture_create_region + + +clutter_cairo_set_source_color + + +CLUTTER_TYPE_CAIRO_TEXTURE +CLUTTER_CAIRO_TEXTURE +CLUTTER_IS_CAIRO_TEXTURE +CLUTTER_CAIRO_TEXTURE_CLASS +CLUTTER_IS_CAIRO_TEXTURE_CLASS +CLUTTER_CAIRO_TEXTURE_GET_CLASS + + +ClutterCairoTexturePrivate +clutter_cairo_texture_get_type +
+
clutter-group ClutterGroup @@ -517,6 +547,7 @@ clutter_stage_show_cursor clutter_stage_hide_cursor clutter_stage_get_actor_at_pos clutter_stage_ensure_current +clutter_stage_ensure_viewport clutter_stage_queue_redraw clutter_stage_event clutter_stage_set_key_focus @@ -1186,39 +1217,6 @@ CLUTTER_COGL CLUTTER_NO_FPU
-
-clutter-effect -Clutter Effects -ClutterEffectTemplate -ClutterEffectTemplateClass -clutter_effect_template_new -clutter_effect_template_new_full -clutter_effect_template_new_for_duration -clutter_effect_template_construct -clutter_effect_template_get_timeline_clone -clutter_effect_template_set_timeline_clone - - -ClutterEffectCompleteFunc -clutter_effect_fade -clutter_effect_move -clutter_effect_path -clutter_effect_scale -clutter_effect_depth -clutter_effect_rotate - - -CLUTTER_TYPE_EFFECT_TEMPLATE -CLUTTER_EFFECT_TEMPLATE -CLUTTER_IS_EFFECT_TEMPLATE -CLUTTER_EFFECT_TEMPLATE_CLASS -CLUTTER_IS_EFFECT_TEMPLATE_CLASS -CLUTTER_EFFECT_TEMPLATE_GET_CLASS - -ClutterEffectTemplatePrivate -clutter_effect_template_get_type -
-
clutter-behaviour-depth ClutterBehaviourDepth @@ -1497,9 +1495,6 @@ clutter_shader_float_get_type clutter_shader_int_get_type clutter_shader_matrix_get_type clutter_shader_error_quark -clutter_shader_float_get_type -clutter_shader_int_get_type -clutter_shader_matrix_get_type
@@ -1509,8 +1504,8 @@ ClutterAnimation ClutterAnimationClass ClutterAnimationMode clutter_animation_new -clutter_animation_set_actor -clutter_animation_get_actor +clutter_animation_set_object +clutter_animation_get_object clutter_animation_set_mode clutter_animation_get_mode clutter_animation_set_duration @@ -1569,6 +1564,10 @@ clutter_interval_get_interval clutter_interval_compute_value clutter_interval_validate + +ClutterProgressFunc +clutter_interval_register_progress_func + CLUTTER_TYPE_INTERVAL CLUTTER_INTERVAL @@ -1582,31 +1581,6 @@ ClutterIntervalPrivate clutter_interval_get_type
-
-Key Bindings -clutter-binding-pool -ClutterBindingPool -ClutterBindingActionFunc - - -clutter_binding_pool_new -clutter_binding_pool_get_for_class -clutter_binding_pool_find - - -clutter_binding_pool_install_action -clutter_binding_pool_install_closure -clutter_binding_pool_override_action -clutter_binding_pool_override_closure -clutter_binding_pool_find_action -clutter_binding_pool_remove_action -clutter_binding_pool_block_action -clutter_binding_pool_unblock_action - - -clutter_binding_pool_activate -
-
clutter-cairo-texture ClutterCairoTexture @@ -1634,6 +1608,7 @@ CLUTTER_CAIRO_TEXTURE_GET_CLASS ClutterCairoTexturePrivate clutter_cairo_texture_get_type +
ClutterText @@ -1713,3 +1688,53 @@ CLUTTER_TYPE_TEXT ClutterTextPrivate clutter_text_get_type
+ +
+clutter-animatable +ClutterAnimatable +ClutterAnimatable +ClutterAnimatableIface +clutter_animatable_animate_property + + +CLUTTER_TYPE_ANIMATABLE +CLUTTER_ANIMATABLE +CLUTTER_IS_ANIMATABLE +CLUTTER_ANIMATABLE_GET_IFACE + + +clutter_animatable_get_type +
+ +
+Key Bindings +clutter-binding-pool +ClutterBindingPool +ClutterBindingActionFunc + + +clutter_binding_pool_new +clutter_binding_pool_get_for_class +clutter_binding_pool_find + + +clutter_binding_pool_install_action +clutter_binding_pool_install_closure +clutter_binding_pool_override_action +clutter_binding_pool_override_closure +clutter_binding_pool_find_action +clutter_binding_pool_remove_action +clutter_binding_pool_block_action +clutter_binding_pool_unblock_action + + +clutter_binding_pool_activate + + +CLUTTER_BINDING_POOL +CLUTTER_IS_BINDING_POOL +CLUTTER_TYPE_BINDING_POOL + + +clutter_binding_pool_get_type +
diff --git a/doc/reference/clutter/clutter.types b/doc/reference/clutter/clutter.types index f59698f02..c4fc972dc 100644 --- a/doc/reference/clutter/clutter.types +++ b/doc/reference/clutter/clutter.types @@ -28,3 +28,4 @@ clutter_shader_get_type clutter_child_meta_get_type clutter_cairo_texture_get_type clutter_text_get_type +clutter_animatable_get_type diff --git a/fixed-to-float-patches/clutter-actor.c.0.patch b/fixed-to-float-patches/clutter-actor.c.0.patch index 91fcd853b..17c746d3a 100644 --- a/fixed-to-float-patches/clutter-actor.c.0.patch +++ b/fixed-to-float-patches/clutter-actor.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c -index 8db8206..f4cec66 100644 +index 1e481cd..9cbee04 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -806,7 +806,7 @@ static inline void @@ -25,25 +25,3 @@ index 8db8206..f4cec66 100644 #define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2))) /* transforms a 4-tuple of coordinates using @matrix and -@@ -3244,8 +3247,8 @@ clutter_actor_get_preferred_width (ClutterActor *self, - - if (natural_width < min_width) - { -- g_warning ("Actor of type %s reported a natural width of %d (%d px) " -- "lower than min width %d (%d px)", -+ g_warning ("Actor of type %s reported a natural width of %f (%d px) " -+ "lower than min width %f (%d px)", - G_OBJECT_TYPE_NAME (self), - natural_width, CLUTTER_UNITS_TO_DEVICE (natural_width), - min_width, CLUTTER_UNITS_TO_DEVICE (min_width)); -@@ -3314,8 +3317,8 @@ clutter_actor_get_preferred_height (ClutterActor *self, - - if (natural_height < min_height) - { -- g_warning ("Actor of type %s reported a natural height of %d " -- "(%d px) lower than min height %d (%d px)", -+ g_warning ("Actor of type %s reported a natural height of %f " -+ "(%d px) lower than min height %f (%d px)", - G_OBJECT_TYPE_NAME (self), - natural_height, CLUTTER_UNITS_TO_DEVICE (natural_height), - min_height, CLUTTER_UNITS_TO_DEVICE (min_height)); diff --git a/fixed-to-float-patches/clutter-fixed.c.0.patch b/fixed-to-float-patches/clutter-fixed.c.0.patch index d1d4bc3e5..5e4f809c5 100644 --- a/fixed-to-float-patches/clutter-fixed.c.0.patch +++ b/fixed-to-float-patches/clutter-fixed.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/clutter-fixed.c b/clutter/clutter-fixed.c -index 89f43c2..6d5bf01 100644 +index 3027a75..315fe32 100644 --- a/clutter/clutter-fixed.c +++ b/clutter/clutter-fixed.c @@ -251,8 +251,8 @@ param_fixed_init (GParamSpec *pspec) diff --git a/fixed-to-float-patches/clutter-fixed.h.0.patch b/fixed-to-float-patches/clutter-fixed.h.0.patch index fc7bb5590..f1c98fdfe 100644 --- a/fixed-to-float-patches/clutter-fixed.h.0.patch +++ b/fixed-to-float-patches/clutter-fixed.h.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/clutter-fixed.h b/clutter/clutter-fixed.h -index 3ae0916..5d150da 100644 +index 3ae0916..61e2fd4 100644 --- a/clutter/clutter-fixed.h +++ b/clutter/clutter-fixed.h @@ -39,126 +39,118 @@ G_BEGIN_DECLS diff --git a/fixed-to-float-patches/clutter-texture.c.0.patch b/fixed-to-float-patches/clutter-texture.c.0.patch index 1340c0f24..448367b00 100644 --- a/fixed-to-float-patches/clutter-texture.c.0.patch +++ b/fixed-to-float-patches/clutter-texture.c.0.patch @@ -1,8 +1,8 @@ diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c -index 42be677..7273946 100644 +index b0b46e4..8a306e9 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c -@@ -463,7 +463,7 @@ clutter_texture_set_fbo_projection (ClutterActor *self) +@@ -474,7 +474,7 @@ clutter_texture_set_fbo_projection (ClutterActor *self) /* Set up a projection matrix so that the actor will be projected as if it was drawn at its original location */ diff --git a/fixed-to-float-patches/clutter-units.h.0.patch b/fixed-to-float-patches/clutter-units.h.0.patch index 52ac9606a..d1ef2cb8e 100644 --- a/fixed-to-float-patches/clutter-units.h.0.patch +++ b/fixed-to-float-patches/clutter-units.h.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/clutter-units.h b/clutter/clutter-units.h -index 8337d19..2a8ef65 100644 +index b85375a..1084095 100644 --- a/clutter/clutter-units.h +++ b/clutter/clutter-units.h @@ -42,7 +42,7 @@ G_BEGIN_DECLS @@ -11,7 +11,7 @@ index 8337d19..2a8ef65 100644 /* * Currently CLUTTER_UNIT maps directly onto ClutterFixed. Nevertheless, the -@@ -50,11 +50,11 @@ typedef gint32 ClutterUnit; +@@ -50,16 +50,16 @@ typedef gint32 ClutterUnit; * decide to change this relationship in the future. */ @@ -27,7 +27,13 @@ index 8337d19..2a8ef65 100644 #define CLUTTER_UNITS_FROM_FIXED(x) (x) #define CLUTTER_UNITS_TO_FIXED(x) (x) -@@ -90,7 +90,7 @@ typedef gint32 ClutterUnit; + +-#define CLUTTER_UNITS_FORMAT "d" ++#define CLUTTER_UNITS_FORMAT "f" + + /** + * CLUTTER_UNITS_FROM_DEVICE: +@@ -92,7 +92,7 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ @@ -36,7 +42,7 @@ index 8337d19..2a8ef65 100644 /** * CLUTTER_UNITS_TO_PANGO_UNIT: -@@ -100,7 +100,7 @@ typedef gint32 ClutterUnit; +@@ -102,7 +102,7 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ @@ -45,7 +51,7 @@ index 8337d19..2a8ef65 100644 #define CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE(x) \ ((clutter_actor_get_widthu (clutter_stage_get_default ()) * x) / 100) -@@ -125,8 +125,7 @@ typedef gint32 ClutterUnit; +@@ -127,8 +127,7 @@ typedef gint32 ClutterUnit; #define CLUTTER_UNITS_FROM_MM(x) \ (CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 25.4))) @@ -55,7 +61,7 @@ index 8337d19..2a8ef65 100644 /** * CLUTTER_UNITS_FROM_POINTS: -@@ -139,9 +138,6 @@ typedef gint32 ClutterUnit; +@@ -141,9 +140,6 @@ typedef gint32 ClutterUnit; #define CLUTTER_UNITS_FROM_POINTS(x) \ CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 72.0)) @@ -65,7 +71,7 @@ index 8337d19..2a8ef65 100644 #define CLUTTER_TYPE_UNIT (clutter_unit_get_type ()) #define CLUTTER_TYPE_PARAM_UNIT (clutter_param_unit_get_type ()) #define CLUTTER_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_UNIT, ClutterParamSpecUnit)) -@@ -154,7 +150,7 @@ typedef gint32 ClutterUnit; +@@ -156,7 +152,7 @@ typedef gint32 ClutterUnit; * * Since: 0.8 */ @@ -74,7 +80,7 @@ index 8337d19..2a8ef65 100644 /** * CLUTTER_MINUNIT: -@@ -163,7 +159,7 @@ typedef gint32 ClutterUnit; +@@ -165,7 +161,7 @@ typedef gint32 ClutterUnit; * * Since: 0.8 */ diff --git a/fixed-to-float-patches/cogl-primitives.c.0.patch b/fixed-to-float-patches/cogl-primitives.c.0.patch index ea09ab582..c3bbd813c 100644 --- a/fixed-to-float-patches/cogl-primitives.c.0.patch +++ b/fixed-to-float-patches/cogl-primitives.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/cogl/common/cogl-primitives.c b/clutter/cogl/common/cogl-primitives.c -index 7dfc78e..c9578db 100644 +index 27e0e36..27834f7 100644 --- a/clutter/cogl/common/cogl-primitives.c +++ b/clutter/cogl/common/cogl-primitives.c @@ -33,6 +33,7 @@ diff --git a/fixed-to-float-patches/gl-cogl-primitives.c.0.patch b/fixed-to-float-patches/gl-cogl-primitives.c.0.patch index b1602e78b..bd938a27e 100644 --- a/fixed-to-float-patches/gl-cogl-primitives.c.0.patch +++ b/fixed-to-float-patches/gl-cogl-primitives.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/cogl/gl/cogl-primitives.c b/clutter/cogl/gl/cogl-primitives.c -index 98d247a..ec9593b 100644 +index dc5c5c6..8a0843d 100644 --- a/clutter/cogl/gl/cogl-primitives.c +++ b/clutter/cogl/gl/cogl-primitives.c @@ -34,6 +34,7 @@ diff --git a/fixed-to-float-patches/gl-cogl-texture.c.0.patch b/fixed-to-float-patches/gl-cogl-texture.c.0.patch index 8e99de198..fff78f571 100644 --- a/fixed-to-float-patches/gl-cogl-texture.c.0.patch +++ b/fixed-to-float-patches/gl-cogl-texture.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c -index 1bbaaa4..612c417 100644 +index 5b7326c..1dac073 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -37,6 +37,7 @@ diff --git a/fixed-to-float-patches/gles-cogl-gles2-wrapper.c.0.patch b/fixed-to-float-patches/gles-cogl-gles2-wrapper.c.0.patch index 9cebe5b34..83d1490bc 100644 --- a/fixed-to-float-patches/gles-cogl-gles2-wrapper.c.0.patch +++ b/fixed-to-float-patches/gles-cogl-gles2-wrapper.c.0.patch @@ -1,8 +1,8 @@ diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.c b/clutter/cogl/gles/cogl-gles2-wrapper.c -index 859c895..8a2fd24 100644 +index b2e19eb..9435131 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.c +++ b/clutter/cogl/gles/cogl-gles2-wrapper.c -@@ -1142,15 +1142,6 @@ cogl_wrap_glClipPlanex (GLenum plane, GLfloat *equation) +@@ -1158,15 +1158,6 @@ cogl_wrap_glClipPlanex (GLenum plane, GLfloat *equation) /* FIXME */ } @@ -18,7 +18,7 @@ index 859c895..8a2fd24 100644 void cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) { -@@ -1169,31 +1160,24 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) +@@ -1185,31 +1176,24 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) } void diff --git a/fixed-to-float-patches/gles-cogl-gles2-wrapper.h.0.patch b/fixed-to-float-patches/gles-cogl-gles2-wrapper.h.0.patch index f67d98c15..9d74af73f 100644 --- a/fixed-to-float-patches/gles-cogl-gles2-wrapper.h.0.patch +++ b/fixed-to-float-patches/gles-cogl-gles2-wrapper.h.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.h b/clutter/cogl/gles/cogl-gles2-wrapper.h -index 265da78..2493b81 100644 +index 8cb9e8b..a194157 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.h +++ b/clutter/cogl/gles/cogl-gles2-wrapper.h @@ -244,7 +244,7 @@ void cogl_wrap_glColor4x (GLclampx r, GLclampx g, GLclampx b, GLclampx a); @@ -11,7 +11,7 @@ index 265da78..2493b81 100644 void cogl_wrap_glFogx (GLenum pname, GLfloat param); void cogl_wrap_glFogxv (GLenum pname, const GLfloat *params); -@@ -297,7 +297,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program); +@@ -299,7 +299,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program); #define cogl_wrap_glColor4x glColor4f #define cogl_wrap_glClipPlanex glClipPlanef #define cogl_wrap_glGetIntegerv glGetIntegerv diff --git a/fixed-to-float-patches/gles-cogl-texture.c.0.patch b/fixed-to-float-patches/gles-cogl-texture.c.0.patch index d1d6b00f9..a315d17c7 100644 --- a/fixed-to-float-patches/gles-cogl-texture.c.0.patch +++ b/fixed-to-float-patches/gles-cogl-texture.c.0.patch @@ -1,5 +1,5 @@ diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c -index fb628b0..85bfc2b 100644 +index ca48a33..e054d84 100644 --- a/clutter/cogl/gles/cogl-texture.c +++ b/clutter/cogl/gles/cogl-texture.c @@ -39,6 +39,7 @@ @@ -10,7 +10,7 @@ index fb628b0..85bfc2b 100644 #define glVertexPointer cogl_wrap_glVertexPointer #define glTexCoordPointer cogl_wrap_glTexCoordPointer -@@ -767,7 +768,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, +@@ -768,7 +769,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint wx, wy; src = source_bmp->data @@ -19,7 +19,7 @@ index fb628b0..85bfc2b 100644 - dst_y) * source_bmp->rowstride + (src_x + x_span->start + x_span->size - x_span->waste -@@ -812,7 +813,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, +@@ -813,7 +814,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint copy_width; src = source_bmp->data diff --git a/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.0.patch b/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.0.patch index d51cd9eb1..7a84920ed 100644 --- a/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.0.patch +++ b/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.0.patch @@ -1,8 +1,8 @@ diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c -index f4cec66..a8fc882 100644 +index 9cbee04..e0903fe 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c -@@ -1342,8 +1342,8 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) +@@ -1348,8 +1348,8 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) gboolean is_stage = CLUTTER_IS_STAGE (self); if (!is_stage) @@ -13,7 +13,7 @@ index f4cec66..a8fc882 100644 0); /* -@@ -1357,50 +1357,50 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) +@@ -1363,50 +1363,50 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) if (priv->rzang) { @@ -345,7 +345,7 @@ index 8a0843d..e445657 100644 _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/clutter/cogl/gl/cogl.c b/clutter/cogl/gl/cogl.c -index 5100a08..bef567f 100644 +index d815e3b..aa0ec78 100644 --- a/clutter/cogl/gl/cogl.c +++ b/clutter/cogl/gl/cogl.c @@ -217,32 +217,15 @@ cogl_scale (float x, float y) @@ -512,7 +512,7 @@ index d8fe121..cf305a8 100644 _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c -index 16cf666..dc2c339 100644 +index aa4e4fc..e835085 100644 --- a/clutter/cogl/gles/cogl.c +++ b/clutter/cogl/gles/cogl.c @@ -123,35 +123,15 @@ cogl_scale (float x, float y) diff --git a/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.1.patch b/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.1.patch index e51bf864a..f04f60a7d 100644 --- a/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.1.patch +++ b/fixed-to-float-patches/remove_cogl_apis_taking_fixed_params.1.patch @@ -18,7 +18,7 @@ index cf305a8..1a58805 100644 GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glPopMatrix () ); diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c -index dc2c339..9065eb2 100644 +index e835085..fc73e44 100644 --- a/clutter/cogl/gles/cogl.c +++ b/clutter/cogl/gles/cogl.c @@ -437,7 +437,7 @@ _cogl_add_stencil_clip (float x_offset, diff --git a/tests/interactive/Makefile.am b/tests/interactive/Makefile.am index 33b371437..8c20d7c9e 100644 --- a/tests/interactive/Makefile.am +++ b/tests/interactive/Makefile.am @@ -15,7 +15,6 @@ UNIT_TESTS = \ test-script.c \ test-model.c \ test-grab.c \ - test-effects.c \ test-fullscreen.c \ test-shader.c \ test-unproject.c \ @@ -39,7 +38,8 @@ UNIT_TESTS = \ test-easing.c \ test-binding-pool.c \ test-text.c \ - test-text-field.c + test-text-field.c \ + test-clutter-cairo-flowers.c if X11_TESTS UNIT_TESTS += test-pixmap.c diff --git a/tests/interactive/test-animation.c b/tests/interactive/test-animation.c index 000e02bd8..ee0ff7337 100644 --- a/tests/interactive/test-animation.c +++ b/tests/interactive/test-animation.c @@ -23,13 +23,12 @@ on_button_press (ClutterActor *actor, ClutterAnimation *animation; gint old_x, old_y, new_x, new_y; guint old_width, old_height, new_width, new_height; - guint8 old_op, new_op; gdouble new_angle; ClutterVertex vertex = { 0, }; + ClutterColor new_color = { 0, }; clutter_actor_get_position (actor, &old_x, &old_y); clutter_actor_get_size (actor, &old_width, &old_height); - old_op = clutter_actor_get_opacity (actor); /* determine the final state of the animation depending on * the state of the actor @@ -40,8 +39,12 @@ on_button_press (ClutterActor *actor, new_y = old_y - 100; new_width = old_width + 200; new_height = old_height + 200; - new_op = 255; new_angle = 360.0; + + new_color.red = 0xdd; + new_color.green = 0x44; + new_color.blue = 0xdd; + new_color.alpha = 0xff; } else { @@ -49,8 +52,12 @@ on_button_press (ClutterActor *actor, new_y = old_y + 100; new_width = old_width - 200; new_height = old_height - 200; - new_op = 128; new_angle = 0.0; + + new_color.red = 0x44; + new_color.green = 0xdd; + new_color.blue = 0x44; + new_color.alpha = 0x88; } vertex.x = CLUTTER_UNITS_FROM_FLOAT ((float) new_width / 2); @@ -62,7 +69,7 @@ on_button_press (ClutterActor *actor, "y", new_y, "width", new_width, "height", new_height, - "opacity", new_op, + "color", &new_color, "rotation-angle-z", new_angle, "fixed::rotation-center-z", &vertex, "fixed::reactive", FALSE, diff --git a/tests/interactive/test-clutter-cairo-flowers.c b/tests/interactive/test-clutter-cairo-flowers.c new file mode 100644 index 000000000..c66531672 --- /dev/null +++ b/tests/interactive/test-clutter-cairo-flowers.c @@ -0,0 +1,212 @@ +/* + * Pretty cairo flower hack. + */ + +#include + +#include /* for sleep(), used for screenshots */ +#include +#include "math.h" + +#define PETAL_MIN 20 +#define PETAL_VAR 40 +#define N_FLOWERS 40 /* reduce if you have a small card */ + +typedef struct Flower +{ + ClutterActor *ctex; + gint x,y,rot,v,rv; +} +Flower; + +ClutterActor* +make_flower_actor (void) +{ + /* No science here, just a hack from toying */ + gint i, j; + + double colors[] = { + 0.71, 0.81, 0.83, + 1.0, 0.78, 0.57, + 0.64, 0.30, 0.35, + 0.73, 0.40, 0.39, + 0.91, 0.56, 0.64, + 0.70, 0.47, 0.45, + 0.92, 0.75, 0.60, + 0.82, 0.86, 0.85, + 0.51, 0.56, 0.67, + 1.0, 0.79, 0.58, + + }; + + gint size; + gint petal_size; + gint n_groups; /* Num groups of petals 1-3 */ + gint n_petals; /* num of petals 4 - 8 */ + gint pm1, pm2; + + gint idx, last_idx = -1; + + ClutterActor *ctex; + cairo_t *cr; + + petal_size = PETAL_MIN + rand() % PETAL_VAR; + size = petal_size * 8; + + n_groups = rand() % 3 + 1; + + ctex = clutter_cairo_texture_new (size, size); + + cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (ctex)); + + cairo_set_tolerance (cr, 0.1); + + /* Clear */ + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + cairo_translate(cr, size/2, size/2); + + for (i=0; iy += flowers[i]->v; + flowers[i]->rot += flowers[i]->rv; + + if (flowers[i]->y > (gint)clutter_actor_get_height + (clutter_stage_get_default ())) + flowers[i]->y = -clutter_actor_get_height (flowers[i]->ctex); + + clutter_actor_set_position (flowers[i]->ctex, + flowers[i]->x, flowers[i]->y); + + clutter_actor_set_rotation (flowers[i]->ctex, + CLUTTER_Z_AXIS, + flowers[i]->rot, + clutter_actor_get_width (flowers[i]->ctex)/2, + clutter_actor_get_height (flowers[i]->ctex)/2, + 0); + } + + return TRUE; +} + +void foo(void) { g_usleep(10000000); } + +int +test_clutter_cairo_flowers_main (int argc, char **argv) +{ + int i; + ClutterActor *stage; + ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; + Flower *flowers[N_FLOWERS]; + + srand(time(NULL)); + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE (stage), + &stage_color); + + g_object_set(stage, "fullscreen", TRUE, NULL); + + for (i=0; i< N_FLOWERS; i++) + { + flowers[i] = g_new0(Flower, 1); + flowers[i]->ctex = make_flower_actor(); + flowers[i]->x = rand() % clutter_actor_get_width(stage) + - (PETAL_MIN+PETAL_VAR)*2; + flowers[i]->y = rand() % clutter_actor_get_height(stage); + flowers[i]->rv = rand() % 5 + 1; + flowers[i]->v = rand() % 10 + 2; + + clutter_group_add (CLUTTER_GROUP(stage), flowers[i]->ctex); + clutter_actor_set_position (flowers[i]->ctex, + flowers[i]->x, flowers[i]->y); + } + + g_timeout_add (50, tick, flowers); + + clutter_actor_show_all (CLUTTER_ACTOR (stage)); + + g_signal_connect (stage, "key-press-event", + G_CALLBACK (clutter_main_quit), + NULL); + + clutter_main(); + + return 1; +} + diff --git a/tests/interactive/test-depth.c b/tests/interactive/test-depth.c index 34c024ede..394398147 100644 --- a/tests/interactive/test-depth.c +++ b/tests/interactive/test-depth.c @@ -26,7 +26,7 @@ raise_top (gpointer ignored) static ClutterActor * clone_box (ClutterTexture *original) { - gint width, height; + guint width, height; ClutterActor *group; ClutterActor *clone; @@ -40,7 +40,7 @@ clone_box (ClutterTexture *original) clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 180, width/2, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); @@ -57,13 +57,13 @@ clone_box (ClutterTexture *original) clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clutter_actor_set_position (clone, 0, height); clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clutter_actor_set_position (clone, 0, 0); clutter_actor_show_all (group); diff --git a/tests/interactive/test-effects.c b/tests/interactive/test-effects.c deleted file mode 100644 index 10dcbec7b..000000000 --- a/tests/interactive/test-effects.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -static ClutterEffectTemplate *tmpl = NULL; -static ClutterTimeline *timeline = NULL; - -G_MODULE_EXPORT int -test_effects_main (int argc, char *argv[]) -{ - ClutterActor *stage, *actor; - ClutterContainer *container; - ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff }; - ClutterColor rect_color = { 0, 0, 0, 0xdd }; - - clutter_init (&argc, &argv); - - timeline = clutter_timeline_new_for_duration (5000); - clutter_timeline_set_loop (timeline, TRUE); - tmpl = - clutter_effect_template_new (timeline, clutter_ramp_inc_func); - - stage = clutter_stage_get_default (); - container = CLUTTER_CONTAINER (stage); - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_size (stage, 800, 600); - clutter_actor_show_all (stage); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 10); - clutter_effect_fade (tmpl, actor, 0x22, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 70); - clutter_effect_depth (tmpl, actor, -500, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 140); - clutter_effect_move (tmpl, actor, 750, 140, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 210); - { - ClutterKnot knots[2]; - - knots[0].x = 750; knots[0].y = 210; - knots[1].x = 350; knots[1].y = 210; - - clutter_effect_path (tmpl, actor, knots, 2, NULL, NULL); - } - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 280); - clutter_actor_set_anchor_point_from_gravity (actor, CLUTTER_GRAVITY_CENTER); - - clutter_effect_scale (tmpl, actor, 2.0, 2.0, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 350); - clutter_effect_rotate (tmpl, actor, - CLUTTER_Z_AXIS, 180.0, - 25, 25, 0, - CLUTTER_ROTATE_CW, - NULL, NULL); - clutter_actor_show (actor); - - clutter_main (); - - g_object_unref (tmpl); - g_object_unref (timeline); - - return EXIT_SUCCESS; -} diff --git a/tests/interactive/test-project.c b/tests/interactive/test-project.c index 33560df0b..7c9403014 100644 --- a/tests/interactive/test-project.c +++ b/tests/interactive/test-project.c @@ -21,19 +21,19 @@ init_handles () clutter_actor_set_position (p[i], 0, 0); clutter_group_add (CLUTTER_GROUP (main_stage), p[i]); - clutter_actor_set_position (p[i], - CLUTTER_FIXED_TO_INT (v[i].x) - - clutter_actor_get_width (p[i])/2, - CLUTTER_FIXED_TO_INT (v[i].y) - - clutter_actor_get_height (p[i])/2); + clutter_actor_set_positionu (p[i], + v[i].x - + clutter_actor_get_widthu (p[i])/2, + v[i].y - + clutter_actor_get_heightu (p[i])/2); clutter_actor_raise_top (p[i]); clutter_actor_show (p[i]); } - v1.x = CLUTTER_INT_TO_FIXED (clutter_actor_get_width (rect)/2); - v1.y = CLUTTER_INT_TO_FIXED (clutter_actor_get_height (rect)/2); + v1.x = clutter_actor_get_widthu (rect) / 2; + v1.y = clutter_actor_get_heightu (rect) / 2; v1.z = 0; clutter_actor_apply_transform_to_point (rect, &v1, &v2); @@ -41,11 +41,11 @@ init_handles () clutter_actor_set_size (p[4], 5, 5); clutter_actor_set_position (p[4], 0, 0); clutter_group_add (CLUTTER_GROUP (main_stage), p[4]); - clutter_actor_set_position (p[4], - CLUTTER_FIXED_TO_INT (v2.x) - - clutter_actor_get_width (p[4])/2, - CLUTTER_FIXED_TO_INT (v2.y) - - clutter_actor_get_height (p[4])/2); + clutter_actor_set_positionu (p[4], + v2.x - + clutter_actor_get_widthu (p[4])/2, + v2.y - + clutter_actor_get_heightu (p[4])/2); clutter_actor_raise_top (p[4]); @@ -62,23 +62,21 @@ place_handles () clutter_actor_get_abs_allocation_vertices (rect, v); for (i = 0; i < 4; ++i) { - clutter_actor_set_position (p[i], - CLUTTER_FIXED_TO_INT (v[i].x) - - clutter_actor_get_width (p[i])/2, - CLUTTER_FIXED_TO_INT (v[i].y) - - clutter_actor_get_height (p[i])/2); + clutter_actor_set_positionu (p[i], + v[i].x - + clutter_actor_get_widthu (p[i])/2, + v[i].y - + clutter_actor_get_heightu (p[i])/2); } - v1.x = CLUTTER_INT_TO_FIXED (clutter_actor_get_width (rect)/2); - v1.y = CLUTTER_INT_TO_FIXED (clutter_actor_get_height (rect)/2); + v1.x = clutter_actor_get_widthu (rect)/2; + v1.y = clutter_actor_get_heightu (rect)/2; v1.z = 0; clutter_actor_apply_transform_to_point (rect, &v1, &v2); - clutter_actor_set_position (p[4], - CLUTTER_FIXED_TO_INT (v2.x) - - clutter_actor_get_width (p[4])/2, - CLUTTER_FIXED_TO_INT (v2.y) - - clutter_actor_get_height (p[4])/2); + clutter_actor_set_positionu (p[4], + v2.x - clutter_actor_get_widthu (p[4])/2, + v2.y - clutter_actor_get_heightu (p[4])/2); } #define M(m,row,col) (m)[col*4+row] @@ -127,7 +125,7 @@ on_event (ClutterStage *stage, gint x, y; gint i; ClutterActorBox box1, box2; - ClutterFixed xp, yp; + ClutterUnit xp, yp; i = find_handle_index (dragging); @@ -139,25 +137,24 @@ on_event (ClutterStage *stage, clutter_actor_get_allocation_box (dragging, &box1); clutter_actor_get_allocation_box (rect, &box2); - xp = CLUTTER_INT_TO_FIXED (x-3) - box1.x1; - yp = CLUTTER_INT_TO_FIXED (y-3) - box1.y1; + xp = CLUTTER_UNITS_FROM_DEVICE (x - 3) - box1.x1; + yp = CLUTTER_UNITS_FROM_DEVICE (y - 3) - box1.y1; if (i == 4) { g_debug ("moving box by %f, %f", - CLUTTER_FIXED_TO_FLOAT (xp), - CLUTTER_FIXED_TO_FLOAT (yp)); + CLUTTER_UNITS_TO_FLOAT (xp), + CLUTTER_UNITS_TO_FLOAT (yp)); - clutter_actor_move_by (rect, - CLUTTER_FIXED_TO_INT(xp), - CLUTTER_FIXED_TO_INT(yp)); + clutter_actor_move_byu (rect, xp, yp); } else { g_debug ("adjusting box by %f, %f, handle %d", - CLUTTER_FIXED_TO_FLOAT (xp), - CLUTTER_FIXED_TO_FLOAT (yp), + CLUTTER_UNITS_TO_FLOAT (xp), + CLUTTER_UNITS_TO_FLOAT (yp), i); + switch (i) { case 0: diff --git a/tests/micro-bench/test-text.c b/tests/micro-bench/test-text.c index afbb8b47b..a322e3c4f 100644 --- a/tests/micro-bench/test-text.c +++ b/tests/micro-bench/test-text.c @@ -9,10 +9,9 @@ #define COLS 18 #define ROWS 20 -gboolean idle (gpointer data) +static void +on_paint (ClutterActor *actor, gconstpointer *data) { - ClutterActor *stage = CLUTTER_ACTOR (data); - static GTimer *timer = NULL; static int fps = 0; @@ -29,8 +28,13 @@ gboolean idle (gpointer data) fps = 0; } - clutter_actor_paint (stage); ++fps; +} + +static gboolean +queue_redraw (gpointer stage) +{ + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); return TRUE; } @@ -41,6 +45,9 @@ main (int argc, char *argv[]) ClutterActor *stage; ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff }; + ClutterActor *group; + + setenv ("CLUTTER_VBLANK", "none", 0); clutter_init (&argc, &argv); @@ -48,6 +55,14 @@ main (int argc, char *argv[]) clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + group = clutter_group_new (); + clutter_actor_set_size (group, STAGE_WIDTH, STAGE_WIDTH); + clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); + + g_idle_add (queue_redraw, stage); + + g_signal_connect (group, "paint", G_CALLBACK (on_paint), NULL); + { gint row, col; @@ -88,15 +103,13 @@ main (int argc, char *argv[]) (1.0*STAGE_HEIGHT/ROWS));*/ clutter_actor_set_scale (label, scale, scale); clutter_text_set_line_wrap (CLUTTER_TEXT (label), FALSE); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); + clutter_container_add_actor (CLUTTER_CONTAINER (group), label); } } clutter_actor_show_all (stage); g_signal_connect (stage, "key-press-event", G_CALLBACK (clutter_main_quit), NULL); - - g_idle_add (idle, (gpointer) stage); clutter_main();