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();