From 7fa7c4a1b621eff0533ff70b1b6c9be001f62e2a Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 22 Jan 2010 21:36:41 +0000 Subject: [PATCH] animation: Transform if necessary The Animation code does transformation of values between type A and A' after checking for compatibility using g_value_type_compatible(). This is incorrect: compatibility means that the two types can be copied. The correct conversion should follow: if (compatible (type (A), type (A'))) copy (A, A'); else if (transformable (type (A), type (A'))) transform (A, A'); else error("Unable to trasform type A in A'"); The transformation might still fail, so we need to check for errors there as well as a fall-through case. --- clutter/clutter-animation.c | 42 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/clutter/clutter-animation.c b/clutter/clutter-animation.c index 23cebc95e..487fec995 100644 --- a/clutter/clutter-animation.c +++ b/clutter/clutter-animation.c @@ -1645,35 +1645,37 @@ clutter_animation_setup_property (ClutterAnimation *animation, */ if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (&real_value))) { - if (!g_value_type_compatible (G_VALUE_TYPE (value), - G_VALUE_TYPE (&real_value)) && - !g_value_type_compatible (G_VALUE_TYPE (&real_value), - G_VALUE_TYPE (value))) + /* are these two types compatible (can be directly copied)? */ + if (g_value_type_compatible (G_VALUE_TYPE (value), + G_VALUE_TYPE (&real_value))) { - g_warning ("%s: Unable to convert from %s to %s for " - "the property '%s' of object %s", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (&real_value)), - property_name, - G_OBJECT_TYPE_NAME (priv->object)); - g_value_unset (&real_value); - return; + g_value_copy (value, &real_value); + goto done; } - if (!g_value_transform (value, &real_value)) + /* are these two type transformable? */ + if (g_value_type_transformable (G_VALUE_TYPE (value), + G_VALUE_TYPE (&real_value))) { - g_warning ("%s: Unable to transform from %s to %s", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (&real_value))); - g_value_unset (&real_value); - return; + if (g_value_transform (value, &real_value)) + goto done; } + + /* if not compatible and not transformable then we can't do much */ + g_warning ("%s: Unable to convert from %s to %s for " + "the property '%s' of object %s", + G_STRLOC, + g_type_name (G_VALUE_TYPE (value)), + g_type_name (G_VALUE_TYPE (&real_value)), + property_name, + G_OBJECT_TYPE_NAME (priv->object)); + g_value_unset (&real_value); + return; } else g_value_copy (value, &real_value); +done: /* create an interval and bind it to the property, in case * it's not a fixed property, otherwise just set it */