Merge branch 'master' into cogl-float

The patches have been updated to apply cleanly.

The patches for the g_warnings in clutter-actor.c have been removed
because master now uses CLUTTER_UNITS_FORMAT so they aren't
necessary. The clutter-units.h patch now sets CLUTTER_UNITS_FORMAT to
'f'.
This commit is contained in:
Neil Roberts 2009-01-15 16:38:49 +00:00
commit 4e94500a2a
64 changed files with 1950 additions and 1633 deletions

15
.gitignore vendored
View File

@ -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]

View File

@ -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 \

View File

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

View File

@ -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;

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* 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 #GValue<!-- -->s 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);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ANIMATABLE_H__
#define __CLUTTER_ANIMATABLE_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-animation.h>
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 #GObject<!-- -->s 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__ */

View File

@ -27,12 +27,12 @@
* @short_description: Simple implicit animations
*
* #ClutterAnimation is an object providing simple, implicit animations
* for #ClutterActor<!-- -->s.
* for #GObject<!-- -->s.
*
* #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 <gobject/gvaluecollector.h>
#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);
}

View File

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

View File

@ -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");

View File

@ -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;

View File

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

View File

@ -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 >*/

View File

@ -1,848 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Jorn Baayen <jorn@openedhand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
*
* 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 <math.h>
#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;
}

View File

@ -1,162 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_EFFECT_H__
#define __CLUTTER_EFFECT_H__
#include <glib-object.h>
#include <clutter/clutter-actor.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-alpha.h>
#include <clutter/clutter-behaviour.h>
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__ */

View File

@ -57,9 +57,18 @@
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#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);
}
}

View File

@ -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__ */

View File

@ -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)
* {
* /&ast; execute the Clutter drawing pipeline &ast;/
* clutter_redraw ();
* }
*
* static void
* on_stage_queue_redraw (ClutterStage *stage)
* {
* /&ast; this prevents the default handler to run &ast;/
* g_signal_stop_emission_by_name (stage, "queue-redraw");
*
* /&ast; queue a redraw with the host toolkit and call
* &ast; a function when the redraw has been completed
* &ast;/
* queue_a_redraw (G_CALLBACK (on_redraw_complete));
* }
* ]|
*
* <note><para>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().</para></note>
*
* 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);
}
/**

View File

@ -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 { \

View File

@ -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));
}

View File

@ -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

View File

@ -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);
};
/**

View File

@ -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

View File

@ -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"

View File

@ -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,

View File

@ -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
{

View File

@ -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) \

View File

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

View File

@ -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);
}

View File

@ -28,8 +28,6 @@
#include <glib.h>
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 */

View File

@ -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)

View File

@ -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) \

View File

@ -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,

View File

@ -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) \

View File

@ -72,6 +72,7 @@ typedef struct
can be flushed */
GLuint texture_current;
GLenum texture_target;
GLenum texture_format;
/* Framebuffer objects */
GArray *fbo_handles;

View File

@ -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)

View File

@ -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

View File

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

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -57,8 +57,8 @@
<xi:include href="xml/clutter-rectangle.xml"/>
<xi:include href="xml/clutter-texture.xml"/>
<xi:include href="xml/clutter-clone-texture.xml"/>
<xi:include href="xml/clutter-cairo-texture.xml"/>
<xi:include href="xml/clutter-text.xml"/>
<xi:include href="xml/clutter-cairo-texture.xml"/>
</chapter>
<chapter>
@ -105,6 +105,7 @@
<xi:include href="xml/clutter-interval.xml"/>
<xi:include href="xml/clutter-animation.xml"/>
<xi:include href="xml/clutter-animatable.xml"/>
</chapter>
</part>

View File

@ -28,6 +28,7 @@ clutter_media_get_type
<FILE>clutter-units</FILE>
<TITLE>Unit conversion</TITLE>
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
</SECTION>
<SECTION>
<FILE>clutter-cairo-texture</FILE>
<TITLE>ClutterCairoTexture</TITLE>
ClutterCairoTexture
ClutterCairoTextureClass
clutter_cairo_texture_new
clutter_cairo_texture_set_surface_size
clutter_cairo_texture_get_surface_size
<SUBSECTION>
clutter_cairo_texture_create
clutter_cairo_texture_create_region
<SUBSECTION>
clutter_cairo_set_source_color
<SUBSECTION Standard>
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
<SUBSECTION Private>
ClutterCairoTexturePrivate
clutter_cairo_texture_get_type
</SECTION>
<SECTION>
<FILE>clutter-group</FILE>
<TITLE>ClutterGroup</TITLE>
@ -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
</SECTION>
<SECTION>
<FILE>clutter-effect</FILE>
<TITLE>Clutter Effects</TITLE>
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
<SUBSECTION>
ClutterEffectCompleteFunc
clutter_effect_fade
clutter_effect_move
clutter_effect_path
clutter_effect_scale
clutter_effect_depth
clutter_effect_rotate
<SUBSECTION Standard>
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
<SUBSECTION Private>
ClutterEffectTemplatePrivate
clutter_effect_template_get_type
</SECTION>
<SECTION>
<FILE>clutter-behaviour-depth</FILE>
<TITLE>ClutterBehaviourDepth</TITLE>
@ -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
</SECTION>
<SECTION>
@ -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
<SUBSECTION>
ClutterProgressFunc
clutter_interval_register_progress_func
<SUBSECTION Standard>
CLUTTER_TYPE_INTERVAL
CLUTTER_INTERVAL
@ -1582,31 +1581,6 @@ ClutterIntervalPrivate
clutter_interval_get_type
</SECTION>
<SECTION>
<TITLE>Key Bindings</TITLE>
<FILE>clutter-binding-pool</FILE>
ClutterBindingPool
ClutterBindingActionFunc
<SUBSECTION>
clutter_binding_pool_new
clutter_binding_pool_get_for_class
clutter_binding_pool_find
<SUBSECTION>
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
<SUBSECTION>
clutter_binding_pool_activate
</SECTION>
<SECTION>
<FILE>clutter-cairo-texture</FILE>
<TITLE>ClutterCairoTexture</TITLE>
@ -1634,6 +1608,7 @@ CLUTTER_CAIRO_TEXTURE_GET_CLASS
<SUBSECTION Private>
ClutterCairoTexturePrivate
clutter_cairo_texture_get_type
</SECTION>
<SECTION>
<TITLE>ClutterText</TITLE>
@ -1713,3 +1688,53 @@ CLUTTER_TYPE_TEXT
ClutterTextPrivate
clutter_text_get_type
</SECTION>
<SECTION>
<FILE>clutter-animatable</FILE>
<TITLE>ClutterAnimatable</TITLE>
ClutterAnimatable
ClutterAnimatableIface
clutter_animatable_animate_property
<SUBSECTION Standard>
CLUTTER_TYPE_ANIMATABLE
CLUTTER_ANIMATABLE
CLUTTER_IS_ANIMATABLE
CLUTTER_ANIMATABLE_GET_IFACE
<SUBSECTION Private>
clutter_animatable_get_type
</SECTION>
<SECTION>
<TITLE>Key Bindings</TITLE>
<FILE>clutter-binding-pool</FILE>
ClutterBindingPool
ClutterBindingActionFunc
<SUBSECTION>
clutter_binding_pool_new
clutter_binding_pool_get_for_class
clutter_binding_pool_find
<SUBSECTION>
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
<SUBSECTION>
clutter_binding_pool_activate
<SUBSECTION Standard>
CLUTTER_BINDING_POOL
CLUTTER_IS_BINDING_POOL
CLUTTER_TYPE_BINDING_POOL
<SUBSECTION Private>
clutter_binding_pool_get_type
</SECTION>

View File

@ -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

View File

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

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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
*/

View File

@ -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 @@

View File

@ -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 @@

View File

@ -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 @@

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -0,0 +1,212 @@
/*
* Pretty cairo flower hack.
*/
#include <clutter/clutter.h>
#include <unistd.h> /* for sleep(), used for screenshots */
#include <stdlib.h>
#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; i<n_groups; i++)
{
n_petals = rand() % 5 + 4;
cairo_save (cr);
cairo_rotate (cr, rand() % 6);
do {
idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
} while (idx == last_idx);
cairo_set_source_rgba (cr, colors[idx], colors[idx+1],
colors[idx+2], 0.5);
last_idx = idx;
/* some bezier randomness */
pm1 = rand() % 20;
pm2 = rand() % 4;
for (j=1; j<n_petals+1; j++)
{
cairo_save (cr);
cairo_rotate (cr, ((2*M_PI)/n_petals)*j);
/* Petals are made up beziers */
cairo_new_path (cr);
cairo_move_to (cr, 0, 0);
cairo_rel_curve_to (cr,
petal_size, petal_size,
(pm2+2)*petal_size, petal_size,
(2*petal_size) + pm1, 0);
cairo_rel_curve_to (cr,
0 + (pm2*petal_size), -petal_size,
-petal_size, -petal_size,
-((2*petal_size) + pm1), 0);
cairo_close_path (cr);
cairo_fill (cr);
cairo_restore (cr);
}
petal_size -= rand() % (size/8);
cairo_restore (cr);
}
/* Finally draw flower center */
do {
idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
} while (idx == last_idx);
if (petal_size < 0)
petal_size = rand() % 10;
cairo_set_source_rgba (cr, colors[idx], colors[idx+1], colors[idx+2], 0.5);
cairo_arc(cr, 0, 0, petal_size, 0, M_PI * 2);
cairo_fill(cr);
cairo_destroy(cr);
return ctex;
}
gboolean
tick (gpointer data)
{
Flower **flowers = (Flower**)data;
gint i = 0;
for (i=0; i< N_FLOWERS; i++)
{
flowers[i]->y += 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;
}

View File

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

View File

@ -1,95 +0,0 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
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;
}

View File

@ -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:

View File

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