1  /* gbinding.c: Binding for object properties
       2   *
       3   * Copyright (C) 2010  Intel Corp.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   *
      20   * Author: Emmanuele Bassi <ebassi@linux.intel.com>
      21   */
      22  
      23  /**
      24   * GBinding:
      25   *
      26   * `GObject` instance (or source) and another property on another `GObject`
      27   * instance (or target).
      28   *
      29   * Whenever the source property changes, the same value is applied to the
      30   * target property; for instance, the following binding:
      31   *
      32   * ```c
      33   *   g_object_bind_property (object1, "property-a",
      34   *                           object2, "property-b",
      35   *                           G_BINDING_DEFAULT);
      36   * ```
      37   *
      38   * will cause the property named "property-b" of @object2 to be updated
      39   * every time [method@GObject.set] or the specific accessor changes the value of
      40   * the property "property-a" of @object1.
      41   *
      42   * It is possible to create a bidirectional binding between two properties
      43   * of two `GObject` instances, so that if either property changes, the
      44   * other is updated as well, for instance:
      45   *
      46   * ```c
      47   *   g_object_bind_property (object1, "property-a",
      48   *                           object2, "property-b",
      49   *                           G_BINDING_BIDIRECTIONAL);
      50   * ```
      51   *
      52   * will keep the two properties in sync.
      53   *
      54   * It is also possible to set a custom transformation function (in both
      55   * directions, in case of a bidirectional binding) to apply a custom
      56   * transformation from the source value to the target value before
      57   * applying it; for instance, the following binding:
      58   *
      59   * ```c
      60   *   g_object_bind_property_full (adjustment1, "value",
      61   *                                adjustment2, "value",
      62   *                                G_BINDING_BIDIRECTIONAL,
      63   *                                celsius_to_fahrenheit,
      64   *                                fahrenheit_to_celsius,
      65   *                                NULL, NULL);
      66   * ```
      67   *
      68   * will keep the "value" property of the two adjustments in sync; the
      69   * @celsius_to_fahrenheit function will be called whenever the "value"
      70   * property of @adjustment1 changes and will transform the current value
      71   * of the property before applying it to the "value" property of @adjustment2.
      72   *
      73   * Vice versa, the @fahrenheit_to_celsius function will be called whenever
      74   * the "value" property of @adjustment2 changes, and will transform the
      75   * current value of the property before applying it to the "value" property
      76   * of @adjustment1.
      77   *
      78   * Note that #GBinding does not resolve cycles by itself; a cycle like
      79   *
      80   * ```
      81   *   object1:propertyA -> object2:propertyB
      82   *   object2:propertyB -> object3:propertyC
      83   *   object3:propertyC -> object1:propertyA
      84   * ```
      85   *
      86   * might lead to an infinite loop. The loop, in this particular case,
      87   * can be avoided if the objects emit the `GObject::notify` signal only
      88   * if the value has effectively been changed. A binding is implemented
      89   * using the `GObject::notify` signal, so it is susceptible to all the
      90   * various ways of blocking a signal emission, like [func@GObject.signal_stop_emission]
      91   * or [func@GObject.signal_handler_block].
      92   *
      93   * A binding will be severed, and the resources it allocates freed, whenever
      94   * either one of the `GObject` instances it refers to are finalized, or when
      95   * the #GBinding instance loses its last reference.
      96   *
      97   * Bindings for languages with garbage collection can use
      98   * [method@GObject.Binding.unbind] to explicitly release a binding between the source
      99   * and target properties, instead of relying on the last reference on the
     100   * binding, source, and target instances to drop.
     101   *
     102   * Since: 2.26
     103   */
     104  
     105  #include "config.h"
     106  
     107  #include <string.h>
     108  
     109  #include "gbinding.h"
     110  #include "genums.h"
     111  #include "gmarshal.h"
     112  #include "gobject.h"
     113  #include "gsignal.h"
     114  #include "gparamspecs.h"
     115  #include "gvaluetypes.h"
     116  
     117  #include "glibintl.h"
     118  
     119  
     120  GType
     121  g_binding_flags_get_type (void)
     122  {
     123    static GType static_g_define_type_id = 0;
     124  
     125    if (g_once_init_enter_pointer (&static_g_define_type_id))
     126      {
     127        static const GFlagsValue values[] = {
     128          { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" },
     129          { G_BINDING_BIDIRECTIONAL, "G_BINDING_BIDIRECTIONAL", "bidirectional" },
     130          { G_BINDING_SYNC_CREATE, "G_BINDING_SYNC_CREATE", "sync-create" },
     131          { G_BINDING_INVERT_BOOLEAN, "G_BINDING_INVERT_BOOLEAN", "invert-boolean" },
     132          { 0, NULL, NULL }
     133        };
     134        GType g_define_type_id =
     135          g_flags_register_static (g_intern_static_string ("GBindingFlags"), values);
     136        g_once_init_leave_pointer (&static_g_define_type_id, g_define_type_id);
     137      }
     138  
     139    return static_g_define_type_id;
     140  }
     141  
     142  /* Reference counted helper struct that is passed to all callbacks to ensure
     143   * that they never work with already freed objects without having to store
     144   * strong references for them.
     145   *
     146   * Using strong references anywhere is not possible because of the API
     147   * requirements of GBinding, specifically that the initial reference of the
     148   * GBinding is owned by the source/target and the caller and can be released
     149   * either by the source/target being finalized or calling g_binding_unbind().
     150   *
     151   * As such, the only strong reference has to be owned by both weak notifies of
     152   * the source and target and the first to be called has to release it.
     153   */
     154  typedef struct {
     155    GWeakRef binding;
     156    GWeakRef source;
     157    GWeakRef target;
     158    gboolean binding_removed;
     159  } BindingContext;
     160  
     161  static BindingContext *
     162  binding_context_ref (BindingContext *context)
     163  {
     164    return g_atomic_rc_box_acquire (context);
     165  }
     166  
     167  static void
     168  binding_context_clear (BindingContext *context)
     169  {
     170    g_weak_ref_clear (&context->binding);
     171    g_weak_ref_clear (&context->source);
     172    g_weak_ref_clear (&context->target);
     173  }
     174  
     175  static void
     176  binding_context_unref (BindingContext *context)
     177  {
     178    g_atomic_rc_box_release_full (context, (GDestroyNotify) binding_context_clear);
     179  }
     180  
     181  /* Reference counting for the transform functions to ensure that they're always
     182   * valid while making use of them in the property notify callbacks.
     183   *
     184   * The transform functions are released when unbinding but unbinding can happen
     185   * while the transform functions are currently in use inside the notify callbacks.
     186   */
     187  typedef struct {
     188    GBindingTransformFunc transform_s2t;
     189    GBindingTransformFunc transform_t2s;
     190  
     191    gpointer transform_data;
     192    GDestroyNotify destroy_notify;
     193  } TransformFunc;
     194  
     195  static TransformFunc *
     196  transform_func_new (GBindingTransformFunc transform_s2t,
     197                      GBindingTransformFunc transform_t2s,
     198                      gpointer              transform_data,
     199                      GDestroyNotify        destroy_notify)
     200  {
     201    TransformFunc *func = g_atomic_rc_box_new0 (TransformFunc);
     202  
     203    func->transform_s2t = transform_s2t;
     204    func->transform_t2s = transform_t2s;
     205    func->transform_data = transform_data;
     206    func->destroy_notify = destroy_notify;
     207  
     208    return func;
     209  }
     210  
     211  static TransformFunc *
     212  transform_func_ref (TransformFunc *func)
     213  {
     214    return g_atomic_rc_box_acquire (func);
     215  }
     216  
     217  static void
     218  transform_func_clear (TransformFunc *func)
     219  {
     220    if (func->destroy_notify)
     221      func->destroy_notify (func->transform_data);
     222  }
     223  
     224  static void
     225  transform_func_unref (TransformFunc *func)
     226  {
     227    g_atomic_rc_box_release_full (func, (GDestroyNotify) transform_func_clear);
     228  }
     229  
     230  #define G_BINDING_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass))
     231  #define G_IS_BINDING_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_BINDING))
     232  #define G_BINDING_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_BINDING, GBindingClass))
     233  
     234  typedef struct _GBindingClass           GBindingClass;
     235  
     236  struct _GBinding
     237  {
     238    GObject parent_instance;
     239  
     240    /* no reference is held on the objects, to avoid cycles */
     241    BindingContext *context;
     242  
     243    /* protects transform_func, source, target property notify and
     244     * target_weak_notify_installed for unbinding */
     245    GMutex unbind_lock;
     246  
     247    /* transform functions, only NULL after unbinding */
     248    TransformFunc *transform_func; /* LOCK: unbind_lock */
     249  
     250    /* the property names are interned, so they should not be freed */
     251    const gchar *source_property;
     252    const gchar *target_property;
     253  
     254    GParamSpec *source_pspec;
     255    GParamSpec *target_pspec;
     256  
     257    GBindingFlags flags;
     258  
     259    guint source_notify; /* LOCK: unbind_lock */
     260    guint target_notify; /* LOCK: unbind_lock */
     261    gboolean target_weak_notify_installed; /* LOCK: unbind_lock */
     262  
     263    /* a guard, to avoid loops */
     264    guint is_frozen : 1;
     265  };
     266  
     267  struct _GBindingClass
     268  {
     269    GObjectClass parent_class;
     270  };
     271  
     272  enum
     273  {
     274    PROP_0,
     275  
     276    PROP_SOURCE,
     277    PROP_TARGET,
     278    PROP_SOURCE_PROPERTY,
     279    PROP_TARGET_PROPERTY,
     280    PROP_FLAGS
     281  };
     282  
     283  static guint gobject_notify_signal_id;
     284  
     285  G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT)
     286  
     287  static void weak_unbind (gpointer user_data, GObject *where_the_object_was);
     288  
     289  /* Must be called with the unbind lock held, context/binding != NULL and strong
     290   * references to source/target or NULL.
     291   * Return TRUE if the binding was actually removed and FALSE if it was already
     292   * removed before. */
     293  static gboolean
     294  unbind_internal_locked (BindingContext *context, GBinding *binding, GObject *source, GObject *target)
     295  {
     296    gboolean binding_was_removed = FALSE;
     297  
     298    g_assert (context != NULL);
     299    g_assert (binding != NULL);
     300  
     301    /* If the target went away we still have a strong reference to the source
     302     * here and can clear it from the binding. Otherwise if the source went away
     303     * we can clear the target from the binding. Finalizing an object clears its
     304     * signal handlers and all weak references pointing to it before calling
     305     * weak notify callbacks.
     306     *
     307     * If both still exist we clean up everything set up by the binding.
     308     */
     309    if (source)
     310      {
     311        /* We always add/remove the source property notify and the weak notify
     312         * of the source at the same time, and should only ever do that once. */
     313        if (binding->source_notify != 0)
     314          {
     315            g_signal_handler_disconnect (source, binding->source_notify);
     316  
     317            g_object_weak_unref (source, weak_unbind, context);
     318            binding_context_unref (context);
     319  
     320            binding->source_notify = 0;
     321          }
     322        g_weak_ref_set (&context->source, NULL);
     323      }
     324  
     325    /* As above, but with the target. If source==target then no weak notify was
     326     * installed for the target, which is why that is stored as a separate
     327     * boolean inside the binding. */
     328    if (target)
     329      {
     330        /* There might be a target property notify without a weak notify on the
     331         * target or the other way around, so these have to be handled
     332         * independently here unlike for the source. */
     333        if (binding->target_notify != 0)
     334          {
     335            g_signal_handler_disconnect (target, binding->target_notify);
     336  
     337            binding->target_notify = 0;
     338          }
     339        g_weak_ref_set (&context->target, NULL);
     340  
     341        /* Remove the weak notify from the target, at most once */
     342        if (binding->target_weak_notify_installed)
     343          {
     344            g_object_weak_unref (target, weak_unbind, context);
     345            binding_context_unref (context);
     346            binding->target_weak_notify_installed = FALSE;
     347          }
     348      }
     349  
     350    /* Make sure to remove the binding only once and return to the caller that
     351     * this was the call that actually removed it. */
     352    if (!context->binding_removed)
     353      {
     354        context->binding_removed = TRUE;
     355        binding_was_removed = TRUE;
     356      }
     357  
     358    return binding_was_removed;
     359  }
     360  
     361  /* the basic assumption is that if either the source or the target
     362   * goes away then the binding does not exist any more and it should
     363   * be reaped as well. Each weak notify owns a strong reference to the
     364   * binding that should be dropped here. */
     365  static void
     366  weak_unbind (gpointer  user_data,
     367               GObject  *where_the_object_was)
     368  {
     369    BindingContext *context = user_data;
     370    GBinding *binding;
     371    GObject *source, *target;
     372    gboolean binding_was_removed = FALSE;
     373    TransformFunc *transform_func;
     374  
     375    binding = g_weak_ref_get (&context->binding);
     376    if (!binding)
     377      {
     378        /* The binding was already destroyed before so there's nothing to do */
     379        binding_context_unref (context);
     380        return;
     381      }
     382  
     383    g_mutex_lock (&binding->unbind_lock);
     384  
     385    transform_func = g_steal_pointer (&binding->transform_func);
     386  
     387    source = g_weak_ref_get (&context->source);
     388    target = g_weak_ref_get (&context->target);
     389  
     390    /* If this is called then either the source or target or both must be in the
     391     * process of being disposed. If this happens as part of g_object_unref()
     392     * then the weak references are actually cleared, otherwise if disposing
     393     * happens as part of g_object_run_dispose() then they would still point to
     394     * the disposed object.
     395     *
     396     * If the object this is being called for is either the source or the target
     397     * and we actually got a strong reference to it nonetheless (see above),
     398     * then signal handlers and weak notifies for it are already disconnected
     399     * and they must not be disconnected a second time. Instead simply clear the
     400     * weak reference and be done with it.
     401     *
     402     * See https://gitlab.gnome.org/GNOME/glib/-/issues/2266 */
     403  
     404    if (source == where_the_object_was)
     405      {
     406        g_weak_ref_set (&context->source, NULL);
     407        g_clear_object (&source);
     408      }
     409  
     410    if (target == where_the_object_was)
     411      {
     412        g_weak_ref_set (&context->target, NULL);
     413        g_clear_object (&target);
     414      }
     415  
     416    binding_was_removed = unbind_internal_locked (context, binding, source, target);
     417  
     418    g_mutex_unlock (&binding->unbind_lock);
     419  
     420    /* Unref source, target and transform_func after the mutex is unlocked as it
     421     * might release the last reference, which then accesses the mutex again */
     422    g_clear_object (&target);
     423    g_clear_object (&source);
     424  
     425    g_clear_pointer (&transform_func, transform_func_unref);
     426  
     427    /* This releases the strong reference we got from the weak ref above */
     428    g_object_unref (binding);
     429  
     430    /* This will take care of the binding itself. */
     431    if (binding_was_removed)
     432      g_object_unref (binding);
     433  
     434    /* Each weak notify owns a reference to the binding context. */
     435    binding_context_unref (context);
     436  }
     437  
     438  static gboolean
     439  default_transform (GBinding     *binding,
     440                     const GValue *value_a,
     441                     GValue       *value_b,
     442                     gpointer      user_data G_GNUC_UNUSED)
     443  {
     444    /* if it's not the same type, try to convert it using the GValue
     445     * transformation API; otherwise just copy it
     446     */
     447    if (!g_type_is_a (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
     448      {
     449        /* are these two types compatible (can be directly copied)? */
     450        if (g_value_type_compatible (G_VALUE_TYPE (value_a),
     451                                     G_VALUE_TYPE (value_b)))
     452          {
     453            g_value_copy (value_a, value_b);
     454            return TRUE;
     455          }
     456  
     457        if (g_value_type_transformable (G_VALUE_TYPE (value_a),
     458                                        G_VALUE_TYPE (value_b)))
     459          {
     460            if (g_value_transform (value_a, value_b))
     461              return TRUE;
     462          }
     463  
     464        g_critical ("%s: Unable to convert a value of type %s to a "
     465                    "value of type %s",
     466                    G_STRLOC,
     467                    g_type_name (G_VALUE_TYPE (value_a)),
     468                    g_type_name (G_VALUE_TYPE (value_b)));
     469  
     470        return FALSE;
     471      }
     472  
     473    g_value_copy (value_a, value_b);
     474    return TRUE;
     475  }
     476  
     477  static gboolean
     478  default_invert_boolean_transform (GBinding     *binding,
     479                                    const GValue *value_a,
     480                                    GValue       *value_b,
     481                                    gpointer      user_data G_GNUC_UNUSED)
     482  {
     483    gboolean value;
     484  
     485    g_assert (G_VALUE_HOLDS_BOOLEAN (value_a));
     486    g_assert (G_VALUE_HOLDS_BOOLEAN (value_b));
     487  
     488    value = g_value_get_boolean (value_a);
     489    value = !value;
     490  
     491    g_value_set_boolean (value_b, value);
     492  
     493    return TRUE;
     494  }
     495  
     496  static void
     497  on_source_notify (GObject          *source,
     498                    GParamSpec       *pspec,
     499                    BindingContext   *context)
     500  {
     501    GBinding *binding;
     502    GObject *target;
     503    TransformFunc *transform_func;
     504    GValue from_value = G_VALUE_INIT;
     505    GValue to_value = G_VALUE_INIT;
     506    gboolean res;
     507  
     508    binding = g_weak_ref_get (&context->binding);
     509    if (!binding)
     510      return;
     511  
     512    if (binding->is_frozen)
     513      {
     514        g_object_unref (binding);
     515        return;
     516      }
     517  
     518    target = g_weak_ref_get (&context->target);
     519    if (!target)
     520      {
     521        g_object_unref (binding);
     522        return;
     523      }
     524  
     525    /* Get the transform function safely */
     526    g_mutex_lock (&binding->unbind_lock);
     527    if (!binding->transform_func)
     528      {
     529        /* it was released already during unbinding, nothing to do here */
     530        g_mutex_unlock (&binding->unbind_lock);
     531        return;
     532      }
     533    transform_func = transform_func_ref (binding->transform_func);
     534    g_mutex_unlock (&binding->unbind_lock);
     535  
     536    g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
     537    g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
     538  
     539    g_object_get_property (source, binding->source_pspec->name, &from_value);
     540  
     541    res = transform_func->transform_s2t (binding,
     542                                         &from_value,
     543                                         &to_value,
     544                                         transform_func->transform_data);
     545  
     546    transform_func_unref (transform_func);
     547  
     548    if (res)
     549      {
     550        binding->is_frozen = TRUE;
     551  
     552        (void) g_param_value_validate (binding->target_pspec, &to_value);
     553        g_object_set_property (target, binding->target_pspec->name, &to_value);
     554  
     555        binding->is_frozen = FALSE;
     556      }
     557  
     558    g_value_unset (&from_value);
     559    g_value_unset (&to_value);
     560  
     561    g_object_unref (target);
     562    g_object_unref (binding);
     563  }
     564  
     565  static void
     566  on_target_notify (GObject          *target,
     567                    GParamSpec       *pspec,
     568                    BindingContext   *context)
     569  {
     570    GBinding *binding;
     571    GObject *source;
     572    TransformFunc *transform_func;
     573    GValue from_value = G_VALUE_INIT;
     574    GValue to_value = G_VALUE_INIT;
     575    gboolean res;
     576  
     577    binding = g_weak_ref_get (&context->binding);
     578    if (!binding)
     579      return;
     580  
     581    if (binding->is_frozen)
     582      {
     583        g_object_unref (binding);
     584        return;
     585      }
     586  
     587    source = g_weak_ref_get (&context->source);
     588    if (!source)
     589      {
     590        g_object_unref (binding);
     591        return;
     592      }
     593  
     594    /* Get the transform function safely */
     595    g_mutex_lock (&binding->unbind_lock);
     596    if (!binding->transform_func)
     597      {
     598        /* it was released already during unbinding, nothing to do here */
     599        g_mutex_unlock (&binding->unbind_lock);
     600        return;
     601      }
     602    transform_func = transform_func_ref (binding->transform_func);
     603    g_mutex_unlock (&binding->unbind_lock);
     604  
     605    g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
     606    g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
     607  
     608    g_object_get_property (target, binding->target_pspec->name, &from_value);
     609  
     610    res = transform_func->transform_t2s (binding,
     611                                         &from_value,
     612                                         &to_value,
     613                                         transform_func->transform_data);
     614    transform_func_unref (transform_func);
     615  
     616    if (res)
     617      {
     618        binding->is_frozen = TRUE;
     619  
     620        (void) g_param_value_validate (binding->source_pspec, &to_value);
     621        g_object_set_property (source, binding->source_pspec->name, &to_value);
     622  
     623        binding->is_frozen = FALSE;
     624      }
     625  
     626    g_value_unset (&from_value);
     627    g_value_unset (&to_value);
     628  
     629    g_object_unref (source);
     630    g_object_unref (binding);
     631  }
     632  
     633  static inline void
     634  g_binding_unbind_internal (GBinding *binding,
     635                             gboolean  unref_binding)
     636  {
     637    BindingContext *context = binding->context;
     638    GObject *source, *target;
     639    gboolean binding_was_removed = FALSE;
     640    TransformFunc *transform_func;
     641  
     642    g_mutex_lock (&binding->unbind_lock);
     643  
     644    transform_func = g_steal_pointer (&binding->transform_func);
     645  
     646    source = g_weak_ref_get (&context->source);
     647    target = g_weak_ref_get (&context->target);
     648  
     649    binding_was_removed = unbind_internal_locked (context, binding, source, target);
     650  
     651    g_mutex_unlock (&binding->unbind_lock);
     652  
     653    /* Unref source, target and transform_func after the mutex is unlocked as it
     654     * might release the last reference, which then accesses the mutex again */
     655    g_clear_object (&target);
     656    g_clear_object (&source);
     657  
     658    g_clear_pointer (&transform_func, transform_func_unref);
     659  
     660    if (binding_was_removed && unref_binding)
     661      g_object_unref (binding);
     662  }
     663  
     664  static void
     665  g_binding_finalize (GObject *gobject)
     666  {
     667    GBinding *binding = G_BINDING (gobject);
     668  
     669    g_binding_unbind_internal (binding, FALSE);
     670  
     671    binding_context_unref (binding->context);
     672  
     673    g_mutex_clear (&binding->unbind_lock);
     674  
     675    G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
     676  }
     677  
     678  /* @key must have already been validated with is_valid()
     679   * Modifies @key in place. */
     680  static void
     681  canonicalize_key (gchar *key)
     682  {
     683    gchar *p;
     684  
     685    for (p = key; *p != 0; p++)
     686      {
     687        gchar c = *p;
     688  
     689        if (c == '_')
     690          *p = '-';
     691      }
     692  }
     693  
     694  /* @key must have already been validated with is_valid() */
     695  static gboolean
     696  is_canonical (const gchar *key)
     697  {
     698    return (strchr (key, '_') == NULL);
     699  }
     700  
     701  static void
     702  g_binding_set_property (GObject      *gobject,
     703                          guint         prop_id,
     704                          const GValue *value,
     705                          GParamSpec   *pspec)
     706  {
     707    GBinding *binding = G_BINDING (gobject);
     708  
     709    switch (prop_id)
     710      {
     711      case PROP_SOURCE:
     712        g_weak_ref_set (&binding->context->source, g_value_get_object (value));
     713        break;
     714  
     715      case PROP_TARGET:
     716        g_weak_ref_set (&binding->context->target, g_value_get_object (value));
     717        break;
     718  
     719      case PROP_SOURCE_PROPERTY:
     720      case PROP_TARGET_PROPERTY:
     721        {
     722          gchar *name_copy = NULL;
     723          const gchar *name = g_value_get_string (value);
     724          const gchar **dest;
     725  
     726          /* Ensure the name we intern is canonical. */
     727          if (!is_canonical (name))
     728            {
     729              name_copy = g_value_dup_string (value);
     730              canonicalize_key (name_copy);
     731              name = name_copy;
     732            }
     733  
     734          if (prop_id == PROP_SOURCE_PROPERTY)
     735            dest = &binding->source_property;
     736          else
     737            dest = &binding->target_property;
     738  
     739          *dest = g_intern_string (name);
     740  
     741          g_free (name_copy);
     742          break;
     743        }
     744  
     745      case PROP_FLAGS:
     746        binding->flags = g_value_get_flags (value);
     747        break;
     748  
     749      default:
     750        G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     751        break;
     752      }
     753  }
     754  
     755  static void
     756  g_binding_get_property (GObject    *gobject,
     757                          guint       prop_id,
     758                          GValue     *value,
     759                          GParamSpec *pspec)
     760  {
     761    GBinding *binding = G_BINDING (gobject);
     762  
     763    switch (prop_id)
     764      {
     765      case PROP_SOURCE:
     766        g_value_take_object (value, g_weak_ref_get (&binding->context->source));
     767        break;
     768  
     769      case PROP_SOURCE_PROPERTY:
     770        /* @source_property is interned, so we don’t need to take a copy */
     771        g_value_set_interned_string (value, binding->source_property);
     772        break;
     773  
     774      case PROP_TARGET:
     775        g_value_take_object (value, g_weak_ref_get (&binding->context->target));
     776        break;
     777  
     778      case PROP_TARGET_PROPERTY:
     779        /* @target_property is interned, so we don’t need to take a copy */
     780        g_value_set_interned_string (value, binding->target_property);
     781        break;
     782  
     783      case PROP_FLAGS:
     784        g_value_set_flags (value, binding->flags);
     785        break;
     786  
     787      default:
     788        G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
     789        break;
     790      }
     791  }
     792  
     793  static void
     794  g_binding_constructed (GObject *gobject)
     795  {
     796    GBinding *binding = G_BINDING (gobject);
     797    GBindingTransformFunc transform_func = default_transform;
     798    GObject *source, *target;
     799    GQuark source_property_detail;
     800    GClosure *source_notify_closure;
     801  
     802    /* assert that we were constructed correctly */
     803    source = g_weak_ref_get (&binding->context->source);
     804    target = g_weak_ref_get (&binding->context->target);
     805    g_assert (source != NULL);
     806    g_assert (target != NULL);
     807    g_assert (binding->source_property != NULL);
     808    g_assert (binding->target_property != NULL);
     809  
     810    /* we assume a check was performed prior to construction - since
     811     * g_object_bind_property_full() does it; we cannot fail construction
     812     * anyway, so it would be hard for use to properly warn here
     813     */
     814    binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), binding->source_property);
     815    binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), binding->target_property);
     816    g_assert (binding->source_pspec != NULL);
     817    g_assert (binding->target_pspec != NULL);
     818  
     819    /* switch to the invert boolean transform if needed */
     820    if (binding->flags & G_BINDING_INVERT_BOOLEAN)
     821      transform_func = default_invert_boolean_transform;
     822  
     823    /* set the default transformation functions here */
     824    binding->transform_func = transform_func_new (transform_func, transform_func, NULL, NULL);
     825  
     826    source_property_detail = g_quark_from_string (binding->source_property);
     827    source_notify_closure = g_cclosure_new (G_CALLBACK (on_source_notify),
     828                                            binding_context_ref (binding->context),
     829                                            (GClosureNotify) binding_context_unref);
     830    binding->source_notify = g_signal_connect_closure_by_id (source,
     831                                                             gobject_notify_signal_id,
     832                                                             source_property_detail,
     833                                                             source_notify_closure,
     834                                                             FALSE);
     835  
     836    g_object_weak_ref (source, weak_unbind, binding_context_ref (binding->context));
     837  
     838    if (binding->flags & G_BINDING_BIDIRECTIONAL)
     839      {
     840        GQuark target_property_detail;
     841        GClosure *target_notify_closure;
     842  
     843        target_property_detail = g_quark_from_string (binding->target_property);
     844        target_notify_closure = g_cclosure_new (G_CALLBACK (on_target_notify),
     845                                                binding_context_ref (binding->context),
     846                                                (GClosureNotify) binding_context_unref);
     847        binding->target_notify = g_signal_connect_closure_by_id (target,
     848                                                                 gobject_notify_signal_id,
     849                                                                 target_property_detail,
     850                                                                 target_notify_closure,
     851                                                                 FALSE);
     852      }
     853  
     854    if (target != source)
     855      {
     856        g_object_weak_ref (target, weak_unbind, binding_context_ref (binding->context));
     857  
     858        /* Need to remember separately if a target weak notify was installed as
     859         * unlike for the source it can exist independently of the property
     860         * notification callback */
     861        binding->target_weak_notify_installed = TRUE;
     862      }
     863  
     864    g_object_unref (source);
     865    g_object_unref (target);
     866  }
     867  
     868  static void
     869  g_binding_class_init (GBindingClass *klass)
     870  {
     871    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     872  
     873    gobject_notify_signal_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
     874    g_assert (gobject_notify_signal_id != 0);
     875  
     876    gobject_class->constructed = g_binding_constructed;
     877    gobject_class->set_property = g_binding_set_property;
     878    gobject_class->get_property = g_binding_get_property;
     879    gobject_class->finalize = g_binding_finalize;
     880  
     881    /**
     882     * GBinding:source:
     883     *
     884     * The #GObject that should be used as the source of the binding
     885     *
     886     * Since: 2.26
     887     */
     888    g_object_class_install_property (gobject_class, PROP_SOURCE,
     889                                     g_param_spec_object ("source", NULL, NULL,
     890                                                          G_TYPE_OBJECT,
     891                                                          G_PARAM_CONSTRUCT_ONLY |
     892                                                          G_PARAM_READWRITE |
     893                                                          G_PARAM_STATIC_STRINGS));
     894    /**
     895     * GBinding:target:
     896     *
     897     * The #GObject that should be used as the target of the binding
     898     *
     899     * Since: 2.26
     900     */
     901    g_object_class_install_property (gobject_class, PROP_TARGET,
     902                                     g_param_spec_object ("target", NULL, NULL,
     903                                                          G_TYPE_OBJECT,
     904                                                          G_PARAM_CONSTRUCT_ONLY |
     905                                                          G_PARAM_READWRITE |
     906                                                          G_PARAM_STATIC_STRINGS));
     907    /**
     908     * GBinding:source-property:
     909     *
     910     * The name of the property of #GBinding:source that should be used
     911     * as the source of the binding.
     912     *
     913     * This should be in [canonical form][canonical-parameter-names] to get the
     914     * best performance.
     915     *
     916     * Since: 2.26
     917     */
     918    g_object_class_install_property (gobject_class, PROP_SOURCE_PROPERTY,
     919                                     g_param_spec_string ("source-property", NULL, NULL,
     920                                                          NULL,
     921                                                          G_PARAM_CONSTRUCT_ONLY |
     922                                                          G_PARAM_READWRITE |
     923                                                          G_PARAM_STATIC_STRINGS));
     924    /**
     925     * GBinding:target-property:
     926     *
     927     * The name of the property of #GBinding:target that should be used
     928     * as the target of the binding.
     929     *
     930     * This should be in [canonical form][canonical-parameter-names] to get the
     931     * best performance.
     932     *
     933     * Since: 2.26
     934     */
     935    g_object_class_install_property (gobject_class, PROP_TARGET_PROPERTY,
     936                                     g_param_spec_string ("target-property", NULL, NULL,
     937                                                          NULL,
     938                                                          G_PARAM_CONSTRUCT_ONLY |
     939                                                          G_PARAM_READWRITE |
     940                                                          G_PARAM_STATIC_STRINGS));
     941    /**
     942     * GBinding:flags:
     943     *
     944     * Flags to be used to control the #GBinding
     945     *
     946     * Since: 2.26
     947     */
     948    g_object_class_install_property (gobject_class, PROP_FLAGS,
     949                                     g_param_spec_flags ("flags", NULL, NULL,
     950                                                         G_TYPE_BINDING_FLAGS,
     951                                                         G_BINDING_DEFAULT,
     952                                                         G_PARAM_CONSTRUCT_ONLY |
     953                                                         G_PARAM_READWRITE |
     954                                                         G_PARAM_STATIC_STRINGS));
     955  }
     956  
     957  static void
     958  g_binding_init (GBinding *binding)
     959  {
     960    g_mutex_init (&binding->unbind_lock);
     961  
     962    binding->context = g_atomic_rc_box_new0 (BindingContext);
     963    g_weak_ref_init (&binding->context->binding, binding);
     964    g_weak_ref_init (&binding->context->source, NULL);
     965    g_weak_ref_init (&binding->context->target, NULL);
     966  }
     967  
     968  /**
     969   * g_binding_get_flags:
     970   * @binding: a #GBinding
     971   *
     972   * Retrieves the flags passed when constructing the #GBinding.
     973   *
     974   * Returns: the #GBindingFlags used by the #GBinding
     975   *
     976   * Since: 2.26
     977   */
     978  GBindingFlags
     979  g_binding_get_flags (GBinding *binding)
     980  {
     981    g_return_val_if_fail (G_IS_BINDING (binding), G_BINDING_DEFAULT);
     982  
     983    return binding->flags;
     984  }
     985  
     986  /**
     987   * g_binding_get_source:
     988   * @binding: a #GBinding
     989   *
     990   * Retrieves the #GObject instance used as the source of the binding.
     991   *
     992   * A #GBinding can outlive the source #GObject as the binding does not hold a
     993   * strong reference to the source. If the source is destroyed before the
     994   * binding then this function will return %NULL.
     995   *
     996   * Use g_binding_dup_source() if the source or binding are used from different
     997   * threads as otherwise the pointer returned from this function might become
     998   * invalid if the source is finalized from another thread in the meantime.
     999   *
    1000   * Returns: (transfer none) (nullable): the source #GObject, or %NULL if the
    1001   *     source does not exist any more.
    1002   *
    1003   * Deprecated: 2.68: Use g_binding_dup_source() for a safer version of this
    1004   * function.
    1005   *
    1006   * Since: 2.26
    1007   */
    1008  GObject *
    1009  g_binding_get_source (GBinding *binding)
    1010  {
    1011    GObject *source;
    1012  
    1013    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1014  
    1015    source = g_weak_ref_get (&binding->context->source);
    1016    /* Unref here, this API is not thread-safe
    1017     * FIXME: Remove this API when we next break API */
    1018    if (source)
    1019      g_object_unref (source);
    1020  
    1021    return source;
    1022  }
    1023  
    1024  /**
    1025   * g_binding_dup_source:
    1026   * @binding: a #GBinding
    1027   *
    1028   * Retrieves the #GObject instance used as the source of the binding.
    1029   *
    1030   * A #GBinding can outlive the source #GObject as the binding does not hold a
    1031   * strong reference to the source. If the source is destroyed before the
    1032   * binding then this function will return %NULL.
    1033   *
    1034   * Returns: (transfer full) (nullable): the source #GObject, or %NULL if the
    1035   *     source does not exist any more.
    1036   *
    1037   * Since: 2.68
    1038   */
    1039  GObject *
    1040  g_binding_dup_source (GBinding *binding)
    1041  {
    1042    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1043  
    1044    return g_weak_ref_get (&binding->context->source);
    1045  }
    1046  
    1047  /**
    1048   * g_binding_get_target:
    1049   * @binding: a #GBinding
    1050   *
    1051   * Retrieves the #GObject instance used as the target of the binding.
    1052   *
    1053   * A #GBinding can outlive the target #GObject as the binding does not hold a
    1054   * strong reference to the target. If the target is destroyed before the
    1055   * binding then this function will return %NULL.
    1056   *
    1057   * Use g_binding_dup_target() if the target or binding are used from different
    1058   * threads as otherwise the pointer returned from this function might become
    1059   * invalid if the target is finalized from another thread in the meantime.
    1060   *
    1061   * Returns: (transfer none) (nullable): the target #GObject, or %NULL if the
    1062   *     target does not exist any more.
    1063   *
    1064   * Deprecated: 2.68: Use g_binding_dup_target() for a safer version of this
    1065   * function.
    1066   *
    1067   * Since: 2.26
    1068   */
    1069  GObject *
    1070  g_binding_get_target (GBinding *binding)
    1071  {
    1072    GObject *target;
    1073  
    1074    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1075  
    1076    target = g_weak_ref_get (&binding->context->target);
    1077    /* Unref here, this API is not thread-safe
    1078     * FIXME: Remove this API when we next break API */
    1079    if (target)
    1080      g_object_unref (target);
    1081  
    1082    return target;
    1083  }
    1084  
    1085  /**
    1086   * g_binding_dup_target:
    1087   * @binding: a #GBinding
    1088   *
    1089   * Retrieves the #GObject instance used as the target of the binding.
    1090   *
    1091   * A #GBinding can outlive the target #GObject as the binding does not hold a
    1092   * strong reference to the target. If the target is destroyed before the
    1093   * binding then this function will return %NULL.
    1094   *
    1095   * Returns: (transfer full) (nullable): the target #GObject, or %NULL if the
    1096   *     target does not exist any more.
    1097   *
    1098   * Since: 2.68
    1099   */
    1100  GObject *
    1101  g_binding_dup_target (GBinding *binding)
    1102  {
    1103    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1104  
    1105    return g_weak_ref_get (&binding->context->target);
    1106  }
    1107  
    1108  /**
    1109   * g_binding_get_source_property:
    1110   * @binding: a #GBinding
    1111   *
    1112   * Retrieves the name of the property of #GBinding:source used as the source
    1113   * of the binding.
    1114   *
    1115   * Returns: the name of the source property
    1116   *
    1117   * Since: 2.26
    1118   */
    1119  const gchar *
    1120  g_binding_get_source_property (GBinding *binding)
    1121  {
    1122    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1123  
    1124    return binding->source_property;
    1125  }
    1126  
    1127  /**
    1128   * g_binding_get_target_property:
    1129   * @binding: a #GBinding
    1130   *
    1131   * Retrieves the name of the property of #GBinding:target used as the target
    1132   * of the binding.
    1133   *
    1134   * Returns: the name of the target property
    1135   *
    1136   * Since: 2.26
    1137   */
    1138  const gchar *
    1139  g_binding_get_target_property (GBinding *binding)
    1140  {
    1141    g_return_val_if_fail (G_IS_BINDING (binding), NULL);
    1142  
    1143    return binding->target_property;
    1144  }
    1145  
    1146  /**
    1147   * g_binding_unbind:
    1148   * @binding: a #GBinding
    1149   *
    1150   * Explicitly releases the binding between the source and the target
    1151   * property expressed by @binding.
    1152   *
    1153   * This function will release the reference that is being held on
    1154   * the @binding instance if the binding is still bound; if you want to hold on
    1155   * to the #GBinding instance after calling g_binding_unbind(), you will need
    1156   * to hold a reference to it.
    1157   *
    1158   * Note however that this function does not take ownership of @binding, it
    1159   * only unrefs the reference that was initially created by
    1160   * g_object_bind_property() and is owned by the binding.
    1161   *
    1162   * Since: 2.38
    1163   */
    1164  void
    1165  g_binding_unbind (GBinding *binding)
    1166  {
    1167    g_return_if_fail (G_IS_BINDING (binding));
    1168  
    1169    g_binding_unbind_internal (binding, TRUE);
    1170  }
    1171  
    1172  /**
    1173   * g_object_bind_property_full:
    1174   * @source: (type GObject.Object): the source #GObject
    1175   * @source_property: the property on @source to bind
    1176   * @target: (type GObject.Object): the target #GObject
    1177   * @target_property: the property on @target to bind
    1178   * @flags: flags to pass to #GBinding
    1179   * @transform_to: (scope notified) (nullable): the transformation function
    1180   *     from the @source to the @target, or %NULL to use the default
    1181   * @transform_from: (scope notified) (nullable): the transformation function
    1182   *     from the @target to the @source, or %NULL to use the default
    1183   * @user_data: custom data to be passed to the transformation functions,
    1184   *     or %NULL
    1185   * @notify: (nullable): a function to call when disposing the binding, to free
    1186   *     resources used by the transformation functions, or %NULL if not required
    1187   *
    1188   * Complete version of g_object_bind_property().
    1189   *
    1190   * Creates a binding between @source_property on @source and @target_property
    1191   * on @target, allowing you to set the transformation functions to be used by
    1192   * the binding.
    1193   *
    1194   * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
    1195   * if @target_property on @target changes then the @source_property on @source
    1196   * will be updated as well. The @transform_from function is only used in case
    1197   * of bidirectional bindings, otherwise it will be ignored
    1198   *
    1199   * The binding will automatically be removed when either the @source or the
    1200   * @target instances are finalized. This will release the reference that is
    1201   * being held on the #GBinding instance; if you want to hold on to the
    1202   * #GBinding instance, you will need to hold a reference to it.
    1203   *
    1204   * To remove the binding, call g_binding_unbind().
    1205   *
    1206   * A #GObject can have multiple bindings.
    1207   *
    1208   * The same @user_data parameter will be used for both @transform_to
    1209   * and @transform_from transformation functions; the @notify function will
    1210   * be called once, when the binding is removed. If you need different data
    1211   * for each transformation function, please use
    1212   * g_object_bind_property_with_closures() instead.
    1213   *
    1214   * Returns: (transfer none): the #GBinding instance representing the
    1215   *     binding between the two #GObject instances. The binding is released
    1216   *     whenever the #GBinding reference count reaches zero.
    1217   *
    1218   * Since: 2.26
    1219   */
    1220  GBinding *
    1221  g_object_bind_property_full (gpointer               source,
    1222                               const gchar           *source_property,
    1223                               gpointer               target,
    1224                               const gchar           *target_property,
    1225                               GBindingFlags          flags,
    1226                               GBindingTransformFunc  transform_to,
    1227                               GBindingTransformFunc  transform_from,
    1228                               gpointer               user_data,
    1229                               GDestroyNotify         notify)
    1230  {
    1231    GParamSpec *pspec;
    1232    GBinding *binding;
    1233  
    1234    g_return_val_if_fail (G_IS_OBJECT (source), NULL);
    1235    g_return_val_if_fail (source_property != NULL, NULL);
    1236    g_return_val_if_fail (g_param_spec_is_valid_name (source_property), NULL);
    1237    g_return_val_if_fail (G_IS_OBJECT (target), NULL);
    1238    g_return_val_if_fail (target_property != NULL, NULL);
    1239    g_return_val_if_fail (g_param_spec_is_valid_name (target_property), NULL);
    1240  
    1241    if (source == target && g_strcmp0 (source_property, target_property) == 0)
    1242      {
    1243        g_critical ("Unable to bind the same property on the same instance");
    1244        return NULL;
    1245      }
    1246  
    1247    /* remove the G_BINDING_INVERT_BOOLEAN flag in case we have
    1248     * custom transformation functions
    1249     */
    1250    if ((flags & G_BINDING_INVERT_BOOLEAN) &&
    1251        (transform_to != NULL || transform_from != NULL))
    1252      {
    1253        flags &= ~G_BINDING_INVERT_BOOLEAN;
    1254      }
    1255  
    1256    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), source_property);
    1257    if (pspec == NULL)
    1258      {
    1259        g_critical ("%s: The source object of type %s has no property called '%s'",
    1260                    G_STRLOC,
    1261                    G_OBJECT_TYPE_NAME (source),
    1262                    source_property);
    1263        return NULL;
    1264      }
    1265  
    1266    if (!(pspec->flags & G_PARAM_READABLE))
    1267      {
    1268        g_critical ("%s: The source object of type %s has no readable property called '%s'",
    1269                    G_STRLOC,
    1270                    G_OBJECT_TYPE_NAME (source),
    1271                    source_property);
    1272        return NULL;
    1273      }
    1274  
    1275    if ((flags & G_BINDING_BIDIRECTIONAL) &&
    1276        ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE)))
    1277      {
    1278        g_critical ("%s: The source object of type %s has no writable property called '%s'",
    1279                    G_STRLOC,
    1280                    G_OBJECT_TYPE_NAME (source),
    1281                    source_property);
    1282        return NULL;
    1283      }
    1284  
    1285    if ((flags & G_BINDING_INVERT_BOOLEAN) &&
    1286        !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
    1287      {
    1288        g_critical ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
    1289                    "when binding boolean properties; the source property '%s' "
    1290                    "is of type '%s'",
    1291                    G_STRLOC,
    1292                    source_property,
    1293                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
    1294        return NULL;
    1295      }
    1296  
    1297    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), target_property);
    1298    if (pspec == NULL)
    1299      {
    1300        g_critical ("%s: The target object of type %s has no property called '%s'",
    1301                    G_STRLOC,
    1302                    G_OBJECT_TYPE_NAME (target),
    1303                    target_property);
    1304        return NULL;
    1305      }
    1306  
    1307    if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE))
    1308      {
    1309        g_critical ("%s: The target object of type %s has no writable property called '%s'",
    1310                    G_STRLOC,
    1311                    G_OBJECT_TYPE_NAME (target),
    1312                    target_property);
    1313        return NULL;
    1314      }
    1315  
    1316    if ((flags & G_BINDING_BIDIRECTIONAL) &&
    1317        !(pspec->flags & G_PARAM_READABLE))
    1318      {
    1319        g_critical ("%s: The target object of type %s has no readable property called '%s'",
    1320                    G_STRLOC,
    1321                    G_OBJECT_TYPE_NAME (target),
    1322                    target_property);
    1323        return NULL;
    1324      }
    1325  
    1326    if ((flags & G_BINDING_INVERT_BOOLEAN) &&
    1327        !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
    1328      {
    1329        g_critical ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
    1330                    "when binding boolean properties; the target property '%s' "
    1331                    "is of type '%s'",
    1332                    G_STRLOC,
    1333                    target_property,
    1334                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
    1335        return NULL;
    1336      }
    1337  
    1338    binding = g_object_new (G_TYPE_BINDING,
    1339                            "source", source,
    1340                            "source-property", source_property,
    1341                            "target", target,
    1342                            "target-property", target_property,
    1343                            "flags", flags,
    1344                            NULL);
    1345  
    1346    g_assert (binding->transform_func != NULL);
    1347  
    1348    /* Use default functions if not provided here */
    1349    if (transform_to == NULL)
    1350      transform_to = binding->transform_func->transform_s2t;
    1351  
    1352    if (transform_from == NULL)
    1353      transform_from = binding->transform_func->transform_t2s;
    1354  
    1355    g_clear_pointer (&binding->transform_func, transform_func_unref);
    1356    binding->transform_func = transform_func_new (transform_to, transform_from, user_data, notify);
    1357  
    1358    /* synchronize the target with the source by faking an emission of
    1359     * the ::notify signal for the source property; this will also take
    1360     * care of the bidirectional binding case because the eventual change
    1361     * will emit a notification on the target
    1362     */
    1363    if (flags & G_BINDING_SYNC_CREATE)
    1364      on_source_notify (source, binding->source_pspec, binding->context);
    1365  
    1366    return binding;
    1367  }
    1368  
    1369  /**
    1370   * g_object_bind_property:
    1371   * @source: (type GObject.Object): the source #GObject
    1372   * @source_property: the property on @source to bind
    1373   * @target: (type GObject.Object): the target #GObject
    1374   * @target_property: the property on @target to bind
    1375   * @flags: flags to pass to #GBinding
    1376   *
    1377   * Creates a binding between @source_property on @source and @target_property
    1378   * on @target.
    1379   *
    1380   * Whenever the @source_property is changed the @target_property is
    1381   * updated using the same value. For instance:
    1382   *
    1383   * |[<!-- language="C" -->
    1384   *   g_object_bind_property (action, "active", widget, "sensitive", 0);
    1385   * ]|
    1386   *
    1387   * Will result in the "sensitive" property of the widget #GObject instance to be
    1388   * updated with the same value of the "active" property of the action #GObject
    1389   * instance.
    1390   *
    1391   * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
    1392   * if @target_property on @target changes then the @source_property on @source
    1393   * will be updated as well.
    1394   *
    1395   * The binding will automatically be removed when either the @source or the
    1396   * @target instances are finalized. To remove the binding without affecting the
    1397   * @source and the @target you can just call g_object_unref() on the returned
    1398   * #GBinding instance.
    1399   *
    1400   * Removing the binding by calling g_object_unref() on it must only be done if
    1401   * the binding, @source and @target are only used from a single thread and it
    1402   * is clear that both @source and @target outlive the binding. Especially it
    1403   * is not safe to rely on this if the binding, @source or @target can be
    1404   * finalized from different threads. Keep another reference to the binding and
    1405   * use g_binding_unbind() instead to be on the safe side.
    1406   *
    1407   * A #GObject can have multiple bindings.
    1408   *
    1409   * Returns: (transfer none): the #GBinding instance representing the
    1410   *     binding between the two #GObject instances. The binding is released
    1411   *     whenever the #GBinding reference count reaches zero.
    1412   *
    1413   * Since: 2.26
    1414   */
    1415  GBinding *
    1416  g_object_bind_property (gpointer       source,
    1417                          const gchar   *source_property,
    1418                          gpointer       target,
    1419                          const gchar   *target_property,
    1420                          GBindingFlags  flags)
    1421  {
    1422    /* type checking is done in g_object_bind_property_full() */
    1423  
    1424    return g_object_bind_property_full (source, source_property,
    1425                                        target, target_property,
    1426                                        flags,
    1427                                        NULL,
    1428                                        NULL,
    1429                                        NULL, NULL);
    1430  }
    1431  
    1432  typedef struct _TransformData
    1433  {
    1434    GClosure *transform_to_closure;
    1435    GClosure *transform_from_closure;
    1436  } TransformData;
    1437  
    1438  static gboolean
    1439  bind_with_closures_transform_to (GBinding     *binding,
    1440                                   const GValue *source,
    1441                                   GValue       *target,
    1442                                   gpointer      data)
    1443  {
    1444    TransformData *t_data = data;
    1445    GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
    1446    GValue retval = G_VALUE_INIT;
    1447    gboolean res;
    1448  
    1449    g_value_init (¶ms[0], G_TYPE_BINDING);
    1450    g_value_set_object (¶ms[0], binding);
    1451  
    1452    g_value_init (¶ms[1], G_TYPE_VALUE);
    1453    g_value_set_boxed (¶ms[1], source);
    1454  
    1455    g_value_init (¶ms[2], G_TYPE_VALUE);
    1456    g_value_set_boxed (¶ms[2], target);
    1457  
    1458    g_value_init (&retval, G_TYPE_BOOLEAN);
    1459    g_value_set_boolean (&retval, FALSE);
    1460  
    1461    g_closure_invoke (t_data->transform_to_closure, &retval, 3, params, NULL);
    1462  
    1463    res = g_value_get_boolean (&retval);
    1464    if (res)
    1465      {
    1466        const GValue *out_value = g_value_get_boxed (¶ms[2]);
    1467  
    1468        g_assert (out_value != NULL);
    1469  
    1470        g_value_copy (out_value, target);
    1471      }
    1472  
    1473    g_value_unset (¶ms[0]);
    1474    g_value_unset (¶ms[1]);
    1475    g_value_unset (¶ms[2]);
    1476    g_value_unset (&retval);
    1477  
    1478    return res;
    1479  }
    1480  
    1481  static gboolean
    1482  bind_with_closures_transform_from (GBinding     *binding,
    1483                                     const GValue *source,
    1484                                     GValue       *target,
    1485                                     gpointer      data)
    1486  {
    1487    TransformData *t_data = data;
    1488    GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
    1489    GValue retval = G_VALUE_INIT;
    1490    gboolean res;
    1491  
    1492    g_value_init (¶ms[0], G_TYPE_BINDING);
    1493    g_value_set_object (¶ms[0], binding);
    1494  
    1495    g_value_init (¶ms[1], G_TYPE_VALUE);
    1496    g_value_set_boxed (¶ms[1], source);
    1497  
    1498    g_value_init (¶ms[2], G_TYPE_VALUE);
    1499    g_value_set_boxed (¶ms[2], target);
    1500  
    1501    g_value_init (&retval, G_TYPE_BOOLEAN);
    1502    g_value_set_boolean (&retval, FALSE);
    1503  
    1504    g_closure_invoke (t_data->transform_from_closure, &retval, 3, params, NULL);
    1505  
    1506    res = g_value_get_boolean (&retval);
    1507    if (res)
    1508      {
    1509        const GValue *out_value = g_value_get_boxed (¶ms[2]);
    1510  
    1511        g_assert (out_value != NULL);
    1512  
    1513        g_value_copy (out_value, target);
    1514      }
    1515  
    1516    g_value_unset (¶ms[0]);
    1517    g_value_unset (¶ms[1]);
    1518    g_value_unset (¶ms[2]);
    1519    g_value_unset (&retval);
    1520  
    1521    return res;
    1522  }
    1523  
    1524  static void
    1525  bind_with_closures_free_func (gpointer data)
    1526  {
    1527    TransformData *t_data = data;
    1528  
    1529    if (t_data->transform_to_closure != NULL)
    1530      g_closure_unref (t_data->transform_to_closure);
    1531  
    1532    if (t_data->transform_from_closure != NULL)
    1533      g_closure_unref (t_data->transform_from_closure);
    1534  
    1535    g_slice_free (TransformData, t_data);
    1536  }
    1537  
    1538  /**
    1539   * g_object_bind_property_with_closures: (rename-to g_object_bind_property_full)
    1540   * @source: (type GObject.Object): the source #GObject
    1541   * @source_property: the property on @source to bind
    1542   * @target: (type GObject.Object): the target #GObject
    1543   * @target_property: the property on @target to bind
    1544   * @flags: flags to pass to #GBinding
    1545   * @transform_to: a #GClosure wrapping the transformation function
    1546   *     from the @source to the @target, or %NULL to use the default
    1547   * @transform_from: a #GClosure wrapping the transformation function
    1548   *     from the @target to the @source, or %NULL to use the default
    1549   *
    1550   * Creates a binding between @source_property on @source and @target_property
    1551   * on @target, allowing you to set the transformation functions to be used by
    1552   * the binding.
    1553   *
    1554   * This function is the language bindings friendly version of
    1555   * g_object_bind_property_full(), using #GClosures instead of
    1556   * function pointers.
    1557   *
    1558   * Returns: (transfer none): the #GBinding instance representing the
    1559   *     binding between the two #GObject instances. The binding is released
    1560   *     whenever the #GBinding reference count reaches zero.
    1561   *
    1562   * Since: 2.26
    1563   */
    1564  GBinding *
    1565  g_object_bind_property_with_closures (gpointer       source,
    1566                                        const gchar   *source_property,
    1567                                        gpointer       target,
    1568                                        const gchar   *target_property,
    1569                                        GBindingFlags  flags,
    1570                                        GClosure      *transform_to,
    1571                                        GClosure      *transform_from)
    1572  {
    1573    TransformData *data;
    1574  
    1575    data = g_slice_new0 (TransformData);
    1576  
    1577    if (transform_to != NULL)
    1578      {
    1579        if (G_CLOSURE_NEEDS_MARSHAL (transform_to))
    1580          g_closure_set_marshal (transform_to, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
    1581  
    1582        data->transform_to_closure = g_closure_ref (transform_to);
    1583        g_closure_sink (data->transform_to_closure);
    1584      }
    1585  
    1586    if (transform_from != NULL)
    1587      {
    1588        if (G_CLOSURE_NEEDS_MARSHAL (transform_from))
    1589          g_closure_set_marshal (transform_from, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
    1590  
    1591        data->transform_from_closure = g_closure_ref (transform_from);
    1592        g_closure_sink (data->transform_from_closure);
    1593      }
    1594  
    1595    return g_object_bind_property_full (source, source_property,
    1596                                        target, target_property,
    1597                                        flags,
    1598                                        transform_to != NULL ? bind_with_closures_transform_to : NULL,
    1599                                        transform_from != NULL ? bind_with_closures_transform_from : NULL,
    1600                                        data,
    1601                                        bind_with_closures_free_func);
    1602  }