Moving files to packaging and extracing new tarball.
[profile/ivi/glib2.git] / gobject / gbinding.c
1 /* gbinding.c: Binding for object properties
2  *
3  * Copyright (C) 2010  Intel Corp.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Emmanuele Bassi <ebassi@linux.intel.com>
21  */
22
23 /**
24  * SECTION:gbinding
25  * @Title: GBinding
26  * @Short_Description: Bind two object properties
27  *
28  * #GBinding is the representation of a binding between a property on a
29  * #GObject instance (or source) and another property on another #GObject
30  * instance (or target). Whenever the source property changes, the same
31  * value is applied to the target property; for instance, the following
32  * binding:
33  *
34  * |[
35  *   g_object_bind_property (object1, "property-a",
36  *                           object2, "property-b",
37  *                           G_BINDING_DEFAULT);
38  * ]|
39  *
40  * will cause <emphasis>object2:property-b</emphasis> to be updated every
41  * time g_object_set() or the specific accessor changes the value of
42  * <emphasis>object1:property-a</emphasis>.
43  *
44  * It is possible to create a bidirectional binding between two properties
45  * of two #GObject instances, so that if either property changes, the
46  * other is updated as well, for instance:
47  *
48  * |[
49  *   g_object_bind_property (object1, "property-a",
50  *                           object2, "property-b",
51  *                           G_BINDING_BIDIRECTIONAL);
52  * ]|
53  *
54  * will keep the two properties in sync.
55  *
56  * It is also possible to set a custom transformation function (in both
57  * directions, in case of a bidirectional binding) to apply a custom
58  * transformation from the source value to the target value before
59  * applying it; for instance, the following binding:
60  *
61  * |[
62  *   g_object_bind_property_full (adjustment1, "value",
63  *                                adjustment2, "value",
64  *                                G_BINDING_BIDIRECTIONAL,
65  *                                celsius_to_fahrenheit,
66  *                                fahrenheit_to_celsius,
67  *                                NULL, NULL);
68  * ]|
69  *
70  * will keep the <emphasis>value</emphasis> property of the two adjustments
71  * in sync; the <function>celsius_to_fahrenheit</function> function will be
72  * called whenever the <emphasis>adjustment1:value</emphasis> property changes
73  * and will transform the current value of the property before applying it
74  * to the <emphasis>adjustment2:value</emphasis> property; vice versa, the
75  * <function>fahrenheit_to_celsius</function> function will be called whenever
76  * the <emphasis>adjustment2:value</emphasis> property changes, and will
77  * transform the current value of the property before applying it to the
78  * <emphasis>adjustment1:value</emphasis>.
79  *
80  * Note that #GBinding does not resolve cycles by itself; a cycle like
81  *
82  * |[
83  *   object1:propertyA -> object2:propertyB
84  *   object2:propertyB -> object3:propertyC
85  *   object3:propertyC -> object1:propertyA
86  * ]|
87  *
88  * might lead to an infinite loop. The loop, in this particular case,
89  * can be avoided if the objects emit the #GObject::notify signal only
90  * if the value has effectively been changed. A binding is implemented
91  * using the #GObject::notify signal, so it is susceptible to all the
92  * various ways of blocking a signal emission, like g_signal_stop_emission()
93  * or g_signal_handler_block().
94  *
95  * A binding will be severed, and the resources it allocates freed, whenever
96  * either one of the #GObject instances it refers to are finalized, or when
97  * the #GBinding instance loses its last reference.
98  *
99  * #GBinding is available since GObject 2.26
100  */
101
102 #include "config.h"
103
104 #include <string.h>
105
106 #include "gbinding.h"
107 #include "genums.h"
108 #include "gmarshal.h"
109 #include "gobject.h"
110 #include "gsignal.h"
111 #include "gparamspecs.h"
112 #include "gvaluetypes.h"
113
114 #include "glibintl.h"
115
116
117 GType
118 g_binding_flags_get_type (void)
119 {
120   static volatile gsize g_define_type_id__volatile = 0;
121
122   if (g_once_init_enter (&g_define_type_id__volatile))
123     {
124       static const GFlagsValue values[] = {
125         { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" },
126         { G_BINDING_BIDIRECTIONAL, "G_BINDING_BIDIRECTIONAL", "bidirectional" },
127         { G_BINDING_SYNC_CREATE, "G_BINDING_SYNC_CREATE", "sync-create" },
128         { G_BINDING_INVERT_BOOLEAN, "G_BINDING_INVERT_BOOLEAN", "invert-boolean" },
129         { 0, NULL, NULL }
130       };
131       GType g_define_type_id =
132         g_flags_register_static (g_intern_static_string ("GBindingFlags"), values);
133       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
134     }
135
136   return g_define_type_id__volatile;
137 }
138
139 #define G_BINDING_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass))
140 #define G_IS_BINDING_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_BINDING))
141 #define G_BINDING_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_BINDING, GBindingClass))
142
143 typedef struct _GBindingClass           GBindingClass;
144
145 struct _GBinding
146 {
147   GObject parent_instance;
148
149   /* no reference is held on the objects, to avoid cycles */
150   GObject *source;
151   GObject *target;
152
153   /* the property names are interned, so they should not be freed */
154   const gchar *source_property;
155   const gchar *target_property;
156
157   GParamSpec *source_pspec;
158   GParamSpec *target_pspec;
159
160   GBindingTransformFunc transform_s2t;
161   GBindingTransformFunc transform_t2s;
162
163   GBindingFlags flags;
164
165   guint source_notify;
166   guint target_notify;
167
168   gpointer transform_data;
169   GDestroyNotify notify;
170
171   /* a guard, to avoid loops */
172   guint is_frozen : 1;
173 };
174
175 struct _GBindingClass
176 {
177   GObjectClass parent_class;
178 };
179
180 enum
181 {
182   PROP_0,
183
184   PROP_SOURCE,
185   PROP_TARGET,
186   PROP_SOURCE_PROPERTY,
187   PROP_TARGET_PROPERTY,
188   PROP_FLAGS
189 };
190
191 static GQuark quark_gbinding = 0;
192
193 G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT);
194
195 static inline void
196 add_binding_qdata (GObject  *gobject,
197                    GBinding *binding)
198 {
199   GHashTable *bindings;
200
201   bindings = g_object_get_qdata (gobject, quark_gbinding);
202   if (bindings == NULL)
203     {
204       bindings = g_hash_table_new (NULL, NULL);
205
206       g_object_set_qdata_full (gobject, quark_gbinding,
207                                bindings,
208                                (GDestroyNotify) g_hash_table_destroy);
209     }
210
211   g_hash_table_insert (bindings, binding, GUINT_TO_POINTER (1));
212 }
213
214 static inline void
215 remove_binding_qdata (GObject  *gobject,
216                       GBinding *binding)
217 {
218   GHashTable *bindings;
219
220   bindings = g_object_get_qdata (gobject, quark_gbinding);
221   g_hash_table_remove (bindings, binding);
222 }
223
224 /* the basic assumption is that if either the source or the target
225  * goes away then the binding does not exist any more and it should
226  * be reaped as well
227  */
228 static void
229 weak_unbind (gpointer  user_data,
230              GObject  *where_the_object_was)
231 {
232   GBinding *binding = user_data;
233
234   /* if what went away was the source, unset it so that GBinding::finalize
235    * does not try to access it; otherwise, disconnect everything and remove
236    * the GBinding instance from the object's qdata
237    */
238   if (binding->source == where_the_object_was)
239     binding->source = NULL;
240   else
241     {
242       if (binding->source_notify != 0)
243         g_signal_handler_disconnect (binding->source, binding->source_notify);
244
245       g_object_weak_unref (binding->source, weak_unbind, user_data);
246       remove_binding_qdata (binding->source, binding);
247       binding->source = NULL;
248     }
249
250   /* as above, but with the target */
251   if (binding->target == where_the_object_was)
252     binding->target = NULL;
253   else
254     {
255       if (binding->target_notify != 0)
256         g_signal_handler_disconnect (binding->target, binding->target_notify);
257
258       g_object_weak_unref (binding->target, weak_unbind, user_data);
259       remove_binding_qdata (binding->target, binding);
260       binding->target = NULL;
261     }
262
263   /* this will take care of the binding itself */
264   g_object_unref (binding);
265 }
266
267 static inline gboolean
268 default_transform (const GValue *value_a,
269                    GValue       *value_b)
270 {
271   /* if it's not the same type, try to convert it using the GValue
272    * transformation API; otherwise just copy it
273    */
274   if (!g_type_is_a (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
275     {
276       /* are these two types compatible (can be directly copied)? */
277       if (g_value_type_compatible (G_VALUE_TYPE (value_a),
278                                    G_VALUE_TYPE (value_b)))
279         {
280           g_value_copy (value_a, value_b);
281           goto done;
282         }
283
284       if (g_value_type_transformable (G_VALUE_TYPE (value_a),
285                                       G_VALUE_TYPE (value_b)))
286         {
287           if (g_value_transform (value_a, value_b))
288             goto done;
289
290           g_warning ("%s: Unable to convert a value of type %s to a "
291                      "value of type %s",
292                      G_STRLOC,
293                      g_type_name (G_VALUE_TYPE (value_a)),
294                      g_type_name (G_VALUE_TYPE (value_b)));
295
296           return FALSE;
297         }
298     }
299   else
300     g_value_copy (value_a, value_b);
301
302 done:
303   return TRUE;
304 }
305
306 static inline gboolean
307 default_invert_boolean_transform (const GValue *value_a,
308                                   GValue       *value_b)
309 {
310   gboolean value;
311
312   g_assert (G_VALUE_HOLDS_BOOLEAN (value_a));
313   g_assert (G_VALUE_HOLDS_BOOLEAN (value_b));
314
315   value = g_value_get_boolean (value_a);
316   value = !value;
317
318   g_value_set_boolean (value_b, value);
319
320   return TRUE;
321 }
322
323 static gboolean
324 default_transform_to (GBinding     *binding,
325                       const GValue *value_a,
326                       GValue       *value_b,
327                       gpointer      user_data G_GNUC_UNUSED)
328 {
329   if (binding->flags & G_BINDING_INVERT_BOOLEAN)
330     return default_invert_boolean_transform (value_a, value_b);
331
332   return default_transform (value_a, value_b);
333 }
334
335 static gboolean
336 default_transform_from (GBinding     *binding,
337                         const GValue *value_a,
338                         GValue       *value_b,
339                         gpointer      user_data G_GNUC_UNUSED)
340 {
341   if (binding->flags & G_BINDING_INVERT_BOOLEAN)
342     return default_invert_boolean_transform (value_a, value_b);
343
344   return default_transform (value_a, value_b);
345 }
346
347 static void
348 on_source_notify (GObject    *gobject,
349                   GParamSpec *pspec,
350                   GBinding   *binding)
351 {
352   const gchar *p_name;
353   GValue source_value = G_VALUE_INIT;
354   GValue target_value = G_VALUE_INIT;
355   gboolean res;
356
357   if (binding->is_frozen)
358     return;
359
360   p_name = g_intern_string (pspec->name);
361
362   if (p_name != binding->source_property)
363     return;
364
365   g_value_init (&source_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
366   g_value_init (&target_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
367
368   g_object_get_property (binding->source, binding->source_pspec->name, &source_value);
369
370   res = binding->transform_s2t (binding,
371                                 &source_value,
372                                 &target_value,
373                                 binding->transform_data);
374   if (res)
375     {
376       binding->is_frozen = TRUE;
377
378       g_param_value_validate (binding->target_pspec, &target_value);
379       g_object_set_property (binding->target, binding->target_pspec->name, &target_value);
380
381       binding->is_frozen = FALSE;
382     }
383
384   g_value_unset (&source_value);
385   g_value_unset (&target_value);
386 }
387
388 static void
389 on_target_notify (GObject    *gobject,
390                   GParamSpec *pspec,
391                   GBinding   *binding)
392 {
393   const gchar *p_name;
394   GValue source_value = G_VALUE_INIT;
395   GValue target_value = G_VALUE_INIT;
396   gboolean res;
397
398   if (binding->is_frozen)
399     return;
400
401   p_name = g_intern_string (pspec->name);
402
403   if (p_name != binding->target_property)
404     return;
405
406   g_value_init (&source_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
407   g_value_init (&target_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
408
409   g_object_get_property (binding->target, binding->target_pspec->name, &source_value);
410
411   res = binding->transform_t2s (binding,
412                                 &source_value,
413                                 &target_value,
414                                 binding->transform_data);
415   if (res)
416     {
417       binding->is_frozen = TRUE;
418
419       g_param_value_validate (binding->source_pspec, &target_value);
420       g_object_set_property (binding->source, binding->source_pspec->name, &target_value);
421
422       binding->is_frozen = FALSE;
423     }
424
425   g_value_unset (&source_value);
426   g_value_unset (&target_value);
427 }
428
429 static void
430 g_binding_finalize (GObject *gobject)
431 {
432   GBinding *binding = G_BINDING (gobject);
433
434   /* dispose of the transformation data */
435   if (binding->notify != NULL)
436     {
437       binding->notify (binding->transform_data);
438
439       binding->transform_data = NULL;
440       binding->notify = NULL;
441     }
442
443   /* we need this in case the source and target instance are still
444    * valid, and it was the GBinding that was unreferenced
445    */
446   if (binding->source != NULL)
447     {
448       if (binding->source_notify != 0)
449         g_signal_handler_disconnect (binding->source, binding->source_notify);
450
451       g_object_weak_unref (binding->source, weak_unbind, binding);
452       remove_binding_qdata (binding->source, binding);
453     }
454
455   if (binding->target != NULL)
456     {
457       if (binding->target_notify != 0)
458         g_signal_handler_disconnect (binding->target, binding->target_notify);
459
460       g_object_weak_unref (binding->target, weak_unbind, binding);
461       remove_binding_qdata (binding->target, binding);
462     }
463
464   G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
465 }
466
467 static void
468 g_binding_set_property (GObject      *gobject,
469                         guint         prop_id,
470                         const GValue *value,
471                         GParamSpec   *pspec)
472 {
473   GBinding *binding = G_BINDING (gobject);
474
475   switch (prop_id)
476     {
477     case PROP_SOURCE:
478       binding->source = g_value_get_object (value);
479       break;
480
481     case PROP_SOURCE_PROPERTY:
482       binding->source_property = g_intern_string (g_value_get_string (value));
483       break;
484
485     case PROP_TARGET:
486       binding->target = g_value_get_object (value);
487       break;
488
489     case PROP_TARGET_PROPERTY:
490       binding->target_property = g_intern_string (g_value_get_string (value));
491       break;
492
493     case PROP_FLAGS:
494       binding->flags = g_value_get_flags (value);
495       break;
496
497     default:
498       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
499       break;
500     }
501 }
502
503 static void
504 g_binding_get_property (GObject    *gobject,
505                         guint       prop_id,
506                         GValue     *value,
507                         GParamSpec *pspec)
508 {
509   GBinding *binding = G_BINDING (gobject);
510
511   switch (prop_id)
512     {
513     case PROP_SOURCE:
514       g_value_set_object (value, binding->source);
515       break;
516
517     case PROP_SOURCE_PROPERTY:
518       g_value_set_string (value, binding->source_property);
519       break;
520
521     case PROP_TARGET:
522       g_value_set_object (value, binding->target);
523       break;
524
525     case PROP_TARGET_PROPERTY:
526       g_value_set_string (value, binding->target_property);
527       break;
528
529     case PROP_FLAGS:
530       g_value_set_flags (value, binding->flags);
531       break;
532
533     default:
534       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
535       break;
536     }
537 }
538
539 static void
540 g_binding_constructed (GObject *gobject)
541 {
542   GBinding *binding = G_BINDING (gobject);
543
544   /* assert that we were constructed correctly */
545   g_assert (binding->source != NULL);
546   g_assert (binding->target != NULL);
547   g_assert (binding->source_property != NULL);
548   g_assert (binding->target_property != NULL);
549
550   /* we assume a check was performed prior to construction - since
551    * g_object_bind_property_full() does it; we cannot fail construction
552    * anyway, so it would be hard for use to properly warn here
553    */
554   binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->source), binding->source_property);
555   binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->target), binding->target_property);
556   g_assert (binding->source_pspec != NULL);
557   g_assert (binding->target_pspec != NULL);
558
559   /* set the default transformation functions here */
560   binding->transform_s2t = default_transform_to;
561   binding->transform_t2s = default_transform_from;
562
563   binding->transform_data = NULL;
564   binding->notify = NULL;
565
566   binding->source_notify = g_signal_connect (binding->source, "notify",
567                                              G_CALLBACK (on_source_notify),
568                                              binding);
569
570   g_object_weak_ref (binding->source, weak_unbind, binding);
571   add_binding_qdata (binding->source, binding);
572
573   if (binding->flags & G_BINDING_BIDIRECTIONAL)
574     binding->target_notify = g_signal_connect (binding->target, "notify",
575                                                G_CALLBACK (on_target_notify),
576                                                binding);
577
578   if (binding->target != binding->source)
579     {
580       g_object_weak_ref (binding->target, weak_unbind, binding);
581       add_binding_qdata (binding->target, binding);
582     }
583 }
584
585 static void
586 g_binding_class_init (GBindingClass *klass)
587 {
588   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
589
590   quark_gbinding = g_quark_from_static_string ("g-binding");
591
592   gobject_class->constructed = g_binding_constructed;
593   gobject_class->set_property = g_binding_set_property;
594   gobject_class->get_property = g_binding_get_property;
595   gobject_class->finalize = g_binding_finalize;
596
597   /**
598    * GBinding:source:
599    *
600    * The #GObject that should be used as the source of the binding
601    *
602    * Since: 2.26
603    */
604   g_object_class_install_property (gobject_class, PROP_SOURCE,
605                                    g_param_spec_object ("source",
606                                                         P_("Source"),
607                                                         P_("The source of the binding"),
608                                                         G_TYPE_OBJECT,
609                                                         G_PARAM_CONSTRUCT_ONLY |
610                                                         G_PARAM_READWRITE |
611                                                         G_PARAM_STATIC_STRINGS));
612   /**
613    * GBinding:target:
614    *
615    * The #GObject that should be used as the target of the binding
616    *
617    * Since: 2.26
618    */
619   g_object_class_install_property (gobject_class, PROP_TARGET,
620                                    g_param_spec_object ("target",
621                                                         P_("Target"),
622                                                         P_("The target of the binding"),
623                                                         G_TYPE_OBJECT,
624                                                         G_PARAM_CONSTRUCT_ONLY |
625                                                         G_PARAM_READWRITE |
626                                                         G_PARAM_STATIC_STRINGS));
627   /**
628    * GBinding:source-property:
629    *
630    * The name of the property of #GBinding:source that should be used
631    * as the source of the binding
632    *
633    * Since: 2.26
634    */
635   g_object_class_install_property (gobject_class, PROP_SOURCE_PROPERTY,
636                                    g_param_spec_string ("source-property",
637                                                         P_("Source Property"),
638                                                         P_("The property on the source to bind"),
639                                                         NULL,
640                                                         G_PARAM_CONSTRUCT_ONLY |
641                                                         G_PARAM_READWRITE |
642                                                         G_PARAM_STATIC_STRINGS));
643   /**
644    * GBinding:target-property:
645    *
646    * The name of the property of #GBinding:target that should be used
647    * as the target of the binding
648    *
649    * Since: 2.26
650    */
651   g_object_class_install_property (gobject_class, PROP_TARGET_PROPERTY,
652                                    g_param_spec_string ("target-property",
653                                                         P_("Target Property"),
654                                                         P_("The property on the target to bind"),
655                                                         NULL,
656                                                         G_PARAM_CONSTRUCT_ONLY |
657                                                         G_PARAM_READWRITE |
658                                                         G_PARAM_STATIC_STRINGS));
659   /**
660    * GBinding:flags:
661    *
662    * Flags to be used to control the #GBinding
663    *
664    * Since: 2.26
665    */
666   g_object_class_install_property (gobject_class, PROP_FLAGS,
667                                    g_param_spec_flags ("flags",
668                                                        P_("Flags"),
669                                                        P_("The binding flags"),
670                                                        G_TYPE_BINDING_FLAGS,
671                                                        G_BINDING_DEFAULT,
672                                                        G_PARAM_CONSTRUCT_ONLY |
673                                                        G_PARAM_READWRITE |
674                                                        G_PARAM_STATIC_STRINGS));
675 }
676
677 static void
678 g_binding_init (GBinding *binding)
679 {
680 }
681
682 /**
683  * g_binding_get_flags:
684  * @binding: a #GBinding
685  *
686  * Retrieves the flags passed when constructing the #GBinding
687  *
688  * Return value: the #GBindingFlags used by the #GBinding
689  *
690  * Since: 2.26
691  */
692 GBindingFlags
693 g_binding_get_flags (GBinding *binding)
694 {
695   g_return_val_if_fail (G_IS_BINDING (binding), G_BINDING_DEFAULT);
696
697   return binding->flags;
698 }
699
700 /**
701  * g_binding_get_source:
702  * @binding: a #GBinding
703  *
704  * Retrieves the #GObject instance used as the source of the binding
705  *
706  * Return value: (transfer none): the source #GObject
707  *
708  * Since: 2.26
709  */
710 GObject *
711 g_binding_get_source (GBinding *binding)
712 {
713   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
714
715   return binding->source;
716 }
717
718 /**
719  * g_binding_get_target:
720  * @binding: a #GBinding
721  *
722  * Retrieves the #GObject instance used as the target of the binding
723  *
724  * Return value: (transfer none): the target #GObject
725  *
726  * Since: 2.26
727  */
728 GObject *
729 g_binding_get_target (GBinding *binding)
730 {
731   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
732
733   return binding->target;
734 }
735
736 /**
737  * g_binding_get_source_property:
738  * @binding: a #GBinding
739  *
740  * Retrieves the name of the property of #GBinding:source used as the source
741  * of the binding
742  *
743  * Return value: the name of the source property
744  *
745  * Since: 2.26
746  */
747 const gchar *
748 g_binding_get_source_property (GBinding *binding)
749 {
750   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
751
752   return binding->source_property;
753 }
754
755 /**
756  * g_binding_get_target_property:
757  * @binding: a #GBinding
758  *
759  * Retrieves the name of the property of #GBinding:target used as the target
760  * of the binding
761  *
762  * Return value: the name of the target property
763  *
764  * Since: 2.26
765  */
766 const gchar *
767 g_binding_get_target_property (GBinding *binding)
768 {
769   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
770
771   return binding->target_property;
772 }
773
774 /**
775  * g_object_bind_property_full:
776  * @source: (type GObject.Object): the source #GObject
777  * @source_property: the property on @source to bind
778  * @target: (type GObject.Object): the target #GObject
779  * @target_property: the property on @target to bind
780  * @flags: flags to pass to #GBinding
781  * @transform_to: (scope notified) (allow-none): the transformation function
782  *   from the @source to the @target, or %NULL to use the default
783  * @transform_from: (scope notified) (allow-none): the transformation function
784  *   from the @target to the @source, or %NULL to use the default
785  * @user_data: custom data to be passed to the transformation functions,
786  *   or %NULL
787  * @notify: function to be called when disposing the binding, to free the
788  *   resources used by the transformation functions
789  *
790  * Complete version of g_object_bind_property().
791  *
792  * Creates a binding between @source_property on @source and @target_property
793  * on @target, allowing you to set the transformation functions to be used by
794  * the binding.
795  *
796  * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
797  * if @target_property on @target changes then the @source_property on @source
798  * will be updated as well. The @transform_from function is only used in case
799  * of bidirectional bindings, otherwise it will be ignored
800  *
801  * The binding will automatically be removed when either the @source or the
802  * @target instances are finalized. To remove the binding without affecting the
803  * @source and the @target you can just call g_object_unref() on the returned
804  * #GBinding instance.
805  *
806  * A #GObject can have multiple bindings.
807  *
808  * <note>The same @user_data parameter will be used for both @transform_to
809  * and @transform_from transformation functions; the @notify function will
810  * be called once, when the binding is removed. If you need different data
811  * for each transformation function, please use
812  * g_object_bind_property_with_closures() instead.</note>
813  *
814  * Return value: (transfer none): the #GBinding instance representing the
815  *   binding between the two #GObject instances. The binding is released
816  *   whenever the #GBinding reference count reaches zero.
817  *
818  * Since: 2.26
819  */
820 GBinding *
821 g_object_bind_property_full (gpointer               source,
822                              const gchar           *source_property,
823                              gpointer               target,
824                              const gchar           *target_property,
825                              GBindingFlags          flags,
826                              GBindingTransformFunc  transform_to,
827                              GBindingTransformFunc  transform_from,
828                              gpointer               user_data,
829                              GDestroyNotify         notify)
830 {
831   GParamSpec *pspec;
832   GBinding *binding;
833
834   g_return_val_if_fail (G_IS_OBJECT (source), NULL);
835   g_return_val_if_fail (source_property != NULL, NULL);
836   g_return_val_if_fail (G_IS_OBJECT (target), NULL);
837   g_return_val_if_fail (target_property != NULL, NULL);
838
839   if (source == target && g_strcmp0 (source_property, target_property) == 0)
840     {
841       g_warning ("Unable to bind the same property on the same instance");
842       return NULL;
843     }
844
845   /* remove the G_BINDING_INVERT_BOOLEAN flag in case we have
846    * custom transformation functions
847    */
848   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
849       (transform_to != NULL || transform_from != NULL))
850     {
851       flags &= ~G_BINDING_INVERT_BOOLEAN;
852     }
853
854   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), source_property);
855   if (pspec == NULL)
856     {
857       g_warning ("%s: The source object of type %s has no property called '%s'",
858                  G_STRLOC,
859                  G_OBJECT_TYPE_NAME (source),
860                  source_property);
861       return NULL;
862     }
863
864   if (!(pspec->flags & G_PARAM_READABLE))
865     {
866       g_warning ("%s: The source object of type %s has no readable property called '%s'",
867                  G_STRLOC,
868                  G_OBJECT_TYPE_NAME (source),
869                  source_property);
870       return NULL;
871     }
872
873   if ((flags & G_BINDING_BIDIRECTIONAL) &&
874       ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE)))
875     {
876       g_warning ("%s: The source object of type %s has no writable property called '%s'",
877                  G_STRLOC,
878                  G_OBJECT_TYPE_NAME (source),
879                  source_property);
880       return NULL;
881     }
882
883   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
884       !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
885     {
886       g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
887                  "when binding boolean properties; the source property '%s' "
888                  "is of type '%s'",
889                  G_STRLOC,
890                  source_property,
891                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
892       return NULL;
893     }
894
895   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), target_property);
896   if (pspec == NULL)
897     {
898       g_warning ("%s: The target object of type %s has no property called '%s'",
899                  G_STRLOC,
900                  G_OBJECT_TYPE_NAME (target),
901                  target_property);
902       return NULL;
903     }
904
905   if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE))
906     {
907       g_warning ("%s: The target object of type %s has no writable property called '%s'",
908                  G_STRLOC,
909                  G_OBJECT_TYPE_NAME (target),
910                  target_property);
911       return NULL;
912     }
913
914   if ((flags & G_BINDING_BIDIRECTIONAL) &&
915       !(pspec->flags & G_PARAM_READABLE))
916     {
917       g_warning ("%s: The target object of type %s has no readable property called '%s'",
918                  G_STRLOC,
919                  G_OBJECT_TYPE_NAME (target),
920                  target_property);
921       return NULL;
922     }
923
924   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
925       !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
926     {
927       g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
928                  "when binding boolean properties; the target property '%s' "
929                  "is of type '%s'",
930                  G_STRLOC,
931                  target_property,
932                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
933       return NULL;
934     }
935
936   binding = g_object_new (G_TYPE_BINDING,
937                           "source", source,
938                           "source-property", source_property,
939                           "target", target,
940                           "target-property", target_property,
941                           "flags", flags,
942                           NULL);
943
944   if (transform_to != NULL)
945     binding->transform_s2t = transform_to;
946
947   if (transform_from != NULL)
948     binding->transform_t2s = transform_from;
949
950   binding->transform_data = user_data;
951   binding->notify = notify;
952
953   /* synchronize the target with the source by faking an emission of
954    * the ::notify signal for the source property; this will also take
955    * care of the bidirectional binding case because the eventual change
956    * will emit a notification on the target
957    */
958   if (flags & G_BINDING_SYNC_CREATE)
959     on_source_notify (binding->source, binding->source_pspec, binding);
960
961   return binding;
962 }
963
964 /**
965  * g_object_bind_property:
966  * @source: (type GObject.Object): the source #GObject
967  * @source_property: the property on @source to bind
968  * @target: (type GObject.Object): the target #GObject
969  * @target_property: the property on @target to bind
970  * @flags: flags to pass to #GBinding
971  *
972  * Creates a binding between @source_property on @source and @target_property
973  * on @target. Whenever the @source_property is changed the @target_property is
974  * updated using the same value. For instance:
975  *
976  * |[
977  *   g_object_bind_property (action, "active", widget, "sensitive", 0);
978  * ]|
979  *
980  * Will result in the "sensitive" property of the widget #GObject instance to be
981  * updated with the same value of the "active" property of the action #GObject
982  * instance.
983  *
984  * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
985  * if @target_property on @target changes then the @source_property on @source
986  * will be updated as well.
987  *
988  * The binding will automatically be removed when either the @source or the
989  * @target instances are finalized. To remove the binding without affecting the
990  * @source and the @target you can just call g_object_unref() on the returned
991  * #GBinding instance.
992  *
993  * A #GObject can have multiple bindings.
994  *
995  * Return value: (transfer none): the #GBinding instance representing the
996  *   binding between the two #GObject instances. The binding is released
997  *   whenever the #GBinding reference count reaches zero.
998  *
999  * Since: 2.26
1000  */
1001 GBinding *
1002 g_object_bind_property (gpointer       source,
1003                         const gchar   *source_property,
1004                         gpointer       target,
1005                         const gchar   *target_property,
1006                         GBindingFlags  flags)
1007 {
1008   /* type checking is done in g_object_bind_property_full() */
1009
1010   return g_object_bind_property_full (source, source_property,
1011                                       target, target_property,
1012                                       flags,
1013                                       NULL,
1014                                       NULL,
1015                                       NULL, NULL);
1016 }
1017
1018 typedef struct _TransformData
1019 {
1020   GClosure *transform_to_closure;
1021   GClosure *transform_from_closure;
1022 } TransformData;
1023
1024 static gboolean
1025 bind_with_closures_transform_to (GBinding     *binding,
1026                                  const GValue *source,
1027                                  GValue       *target,
1028                                  gpointer      data)
1029 {
1030   TransformData *t_data = data;
1031   GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
1032   GValue retval = G_VALUE_INIT;
1033   gboolean res;
1034
1035   g_value_init (&params[0], G_TYPE_BINDING);
1036   g_value_set_object (&params[0], binding);
1037
1038   g_value_init (&params[1], G_TYPE_VALUE);
1039   g_value_set_boxed (&params[1], source);
1040
1041   g_value_init (&params[2], G_TYPE_VALUE);
1042   g_value_set_boxed (&params[2], target);
1043
1044   g_value_init (&retval, G_TYPE_BOOLEAN);
1045   g_value_set_boolean (&retval, FALSE);
1046
1047   g_closure_invoke (t_data->transform_to_closure, &retval, 3, params, NULL);
1048
1049   res = g_value_get_boolean (&retval);
1050   if (res)
1051     {
1052       const GValue *out_value = g_value_get_boxed (&params[2]);
1053
1054       g_assert (out_value != NULL);
1055
1056       g_value_copy (out_value, target);
1057     }
1058
1059   g_value_unset (&params[0]);
1060   g_value_unset (&params[1]);
1061   g_value_unset (&params[2]);
1062   g_value_unset (&retval);
1063
1064   return res;
1065 }
1066
1067 static gboolean
1068 bind_with_closures_transform_from (GBinding     *binding,
1069                                    const GValue *source,
1070                                    GValue       *target,
1071                                    gpointer      data)
1072 {
1073   TransformData *t_data = data;
1074   GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
1075   GValue retval = G_VALUE_INIT;
1076   gboolean res;
1077
1078   g_value_init (&params[0], G_TYPE_BINDING);
1079   g_value_set_object (&params[0], binding);
1080
1081   g_value_init (&params[1], G_TYPE_VALUE);
1082   g_value_set_boxed (&params[1], source);
1083
1084   g_value_init (&params[2], G_TYPE_VALUE);
1085   g_value_set_boxed (&params[2], target);
1086
1087   g_value_init (&retval, G_TYPE_BOOLEAN);
1088   g_value_set_boolean (&retval, FALSE);
1089
1090   g_closure_invoke (t_data->transform_from_closure, &retval, 3, params, NULL);
1091
1092   res = g_value_get_boolean (&retval);
1093   if (res)
1094     {
1095       const GValue *out_value = g_value_get_boxed (&params[2]);
1096
1097       g_assert (out_value != NULL);
1098
1099       g_value_copy (out_value, target);
1100     }
1101
1102   g_value_unset (&params[0]);
1103   g_value_unset (&params[1]);
1104   g_value_unset (&params[2]);
1105   g_value_unset (&retval);
1106
1107   return res;
1108 }
1109
1110 static void
1111 bind_with_closures_free_func (gpointer data)
1112 {
1113   TransformData *t_data = data;
1114
1115   if (t_data->transform_to_closure != NULL)
1116     g_closure_unref (t_data->transform_to_closure);
1117
1118   if (t_data->transform_from_closure != NULL)
1119     g_closure_unref (t_data->transform_from_closure);
1120
1121   g_slice_free (TransformData, t_data);
1122 }
1123
1124 /**
1125  * g_object_bind_property_with_closures:
1126  * @source: (type GObject.Object): the source #GObject
1127  * @source_property: the property on @source to bind
1128  * @target: (type GObject.Object): the target #GObject
1129  * @target_property: the property on @target to bind
1130  * @flags: flags to pass to #GBinding
1131  * @transform_to: a #GClosure wrapping the transformation function
1132  *   from the @source to the @target, or %NULL to use the default
1133  * @transform_from: a #GClosure wrapping the transformation function
1134  *   from the @target to the @source, or %NULL to use the default
1135  *
1136  * Creates a binding between @source_property on @source and @target_property
1137  * on @target, allowing you to set the transformation functions to be used by
1138  * the binding.
1139  *
1140  * This function is the language bindings friendly version of
1141  * g_object_bind_property_full(), using #GClosure<!-- -->s instead of
1142  * function pointers.
1143  *
1144  * Rename to: g_object_bind_property_full
1145  *
1146  * Return value: (transfer none): the #GBinding instance representing the
1147  *   binding between the two #GObject instances. The binding is released
1148  *   whenever the #GBinding reference count reaches zero.
1149  *
1150  * Since: 2.26
1151  */
1152 GBinding *
1153 g_object_bind_property_with_closures (gpointer       source,
1154                                       const gchar   *source_property,
1155                                       gpointer       target,
1156                                       const gchar   *target_property,
1157                                       GBindingFlags  flags,
1158                                       GClosure      *transform_to,
1159                                       GClosure      *transform_from)
1160 {
1161   TransformData *data;
1162
1163   data = g_slice_new0 (TransformData);
1164
1165   if (transform_to != NULL)
1166     {
1167       if (G_CLOSURE_NEEDS_MARSHAL (transform_to))
1168         g_closure_set_marshal (transform_to, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1169
1170       data->transform_to_closure = g_closure_ref (transform_to);
1171       g_closure_sink (data->transform_to_closure);
1172     }
1173
1174   if (transform_from != NULL)
1175     {
1176       if (G_CLOSURE_NEEDS_MARSHAL (transform_from))
1177         g_closure_set_marshal (transform_from, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1178
1179       data->transform_from_closure = g_closure_ref (transform_from);
1180       g_closure_sink (data->transform_from_closure);
1181     }
1182
1183   return g_object_bind_property_full (source, source_property,
1184                                       target, target_property,
1185                                       flags,
1186                                       transform_to != NULL ? bind_with_closures_transform_to : NULL,
1187                                       transform_from != NULL ? bind_with_closures_transform_from : NULL,
1188                                       data,
1189                                       bind_with_closures_free_func);
1190 }