[kdbus] sync with kdbus (kdbus.h - commit: 5ae1ecac44cb)
[platform/upstream/glib.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, see <http://www.gnu.org/licenses/>.
17  *
18  * Author: Emmanuele Bassi <ebassi@linux.intel.com>
19  */
20
21 /**
22  * SECTION:gbinding
23  * @Title: GBinding
24  * @Short_Description: Bind two object properties
25  *
26  * #GBinding is the representation of a binding between a property on a
27  * #GObject instance (or source) and another property on another #GObject
28  * instance (or target). Whenever the source property changes, the same
29  * value is applied to the target property; for instance, the following
30  * binding:
31  *
32  * |[<!-- language="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 g_object_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  * |[<!-- language="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  * |[<!-- language="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 g_signal_stop_emission()
91  * or g_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  * g_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  * #GBinding is available since GObject 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 volatile gsize g_define_type_id__volatile = 0;
124
125   if (g_once_init_enter (&g_define_type_id__volatile))
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 (&g_define_type_id__volatile, g_define_type_id);
137     }
138
139   return g_define_type_id__volatile;
140 }
141
142 #define G_BINDING_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass))
143 #define G_IS_BINDING_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_BINDING))
144 #define G_BINDING_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_BINDING, GBindingClass))
145
146 typedef struct _GBindingClass           GBindingClass;
147
148 struct _GBinding
149 {
150   GObject parent_instance;
151
152   /* no reference is held on the objects, to avoid cycles */
153   GObject *source;
154   GObject *target;
155
156   /* the property names are interned, so they should not be freed */
157   const gchar *source_property;
158   const gchar *target_property;
159
160   GParamSpec *source_pspec;
161   GParamSpec *target_pspec;
162
163   GBindingTransformFunc transform_s2t;
164   GBindingTransformFunc transform_t2s;
165
166   GBindingFlags flags;
167
168   guint source_notify;
169   guint target_notify;
170
171   gpointer transform_data;
172   GDestroyNotify notify;
173
174   /* a guard, to avoid loops */
175   guint is_frozen : 1;
176 };
177
178 struct _GBindingClass
179 {
180   GObjectClass parent_class;
181 };
182
183 enum
184 {
185   PROP_0,
186
187   PROP_SOURCE,
188   PROP_TARGET,
189   PROP_SOURCE_PROPERTY,
190   PROP_TARGET_PROPERTY,
191   PROP_FLAGS
192 };
193
194 static GQuark quark_gbinding = 0;
195
196 G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT);
197
198 static inline void
199 add_binding_qdata (GObject  *gobject,
200                    GBinding *binding)
201 {
202   GHashTable *bindings;
203
204   bindings = g_object_get_qdata (gobject, quark_gbinding);
205   if (bindings == NULL)
206     {
207       bindings = g_hash_table_new (NULL, NULL);
208
209       g_object_set_qdata_full (gobject, quark_gbinding,
210                                bindings,
211                                (GDestroyNotify) g_hash_table_unref);
212     }
213
214   g_hash_table_add (bindings, binding);
215 }
216
217 static inline void
218 remove_binding_qdata (GObject  *gobject,
219                       GBinding *binding)
220 {
221   GHashTable *bindings;
222
223   bindings = g_object_get_qdata (gobject, quark_gbinding);
224   if (binding != NULL)
225     g_hash_table_remove (bindings, binding);
226 }
227
228 /* the basic assumption is that if either the source or the target
229  * goes away then the binding does not exist any more and it should
230  * be reaped as well
231  */
232 static void
233 weak_unbind (gpointer  user_data,
234              GObject  *where_the_object_was)
235 {
236   GBinding *binding = user_data;
237
238   /* if what went away was the source, unset it so that GBinding::finalize
239    * does not try to access it; otherwise, disconnect everything and remove
240    * the GBinding instance from the object's qdata
241    */
242   if (binding->source == where_the_object_was)
243     binding->source = NULL;
244   else
245     {
246       if (binding->source_notify != 0)
247         g_signal_handler_disconnect (binding->source, binding->source_notify);
248
249       g_object_weak_unref (binding->source, weak_unbind, user_data);
250       remove_binding_qdata (binding->source, binding);
251
252       binding->source_notify = 0;
253       binding->source = NULL;
254     }
255
256   /* as above, but with the target */
257   if (binding->target == where_the_object_was)
258     binding->target = NULL;
259   else
260     {
261       if (binding->target_notify != 0)
262         g_signal_handler_disconnect (binding->target, binding->target_notify);
263
264       g_object_weak_unref (binding->target, weak_unbind, user_data);
265       remove_binding_qdata (binding->target, binding);
266
267       binding->target_notify = 0;
268       binding->target = NULL;
269     }
270
271   /* this will take care of the binding itself */
272   g_object_unref (binding);
273 }
274
275 static inline gboolean
276 default_transform (const GValue *value_a,
277                    GValue       *value_b)
278 {
279   /* if it's not the same type, try to convert it using the GValue
280    * transformation API; otherwise just copy it
281    */
282   if (!g_type_is_a (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
283     {
284       /* are these two types compatible (can be directly copied)? */
285       if (g_value_type_compatible (G_VALUE_TYPE (value_a),
286                                    G_VALUE_TYPE (value_b)))
287         {
288           g_value_copy (value_a, value_b);
289           goto done;
290         }
291
292       if (g_value_type_transformable (G_VALUE_TYPE (value_a),
293                                       G_VALUE_TYPE (value_b)))
294         {
295           if (g_value_transform (value_a, value_b))
296             goto done;
297         }
298
299       g_warning ("%s: Unable to convert a value of type %s to a "
300                  "value of type %s",
301                  G_STRLOC,
302                  g_type_name (G_VALUE_TYPE (value_a)),
303                  g_type_name (G_VALUE_TYPE (value_b)));
304
305       return FALSE;
306     }
307   else
308     g_value_copy (value_a, value_b);
309
310 done:
311   return TRUE;
312 }
313
314 static inline gboolean
315 default_invert_boolean_transform (const GValue *value_a,
316                                   GValue       *value_b)
317 {
318   gboolean value;
319
320   g_assert (G_VALUE_HOLDS_BOOLEAN (value_a));
321   g_assert (G_VALUE_HOLDS_BOOLEAN (value_b));
322
323   value = g_value_get_boolean (value_a);
324   value = !value;
325
326   g_value_set_boolean (value_b, value);
327
328   return TRUE;
329 }
330
331 static gboolean
332 default_transform_to (GBinding     *binding,
333                       const GValue *value_a,
334                       GValue       *value_b,
335                       gpointer      user_data G_GNUC_UNUSED)
336 {
337   if (binding->flags & G_BINDING_INVERT_BOOLEAN)
338     return default_invert_boolean_transform (value_a, value_b);
339
340   return default_transform (value_a, value_b);
341 }
342
343 static gboolean
344 default_transform_from (GBinding     *binding,
345                         const GValue *value_a,
346                         GValue       *value_b,
347                         gpointer      user_data G_GNUC_UNUSED)
348 {
349   if (binding->flags & G_BINDING_INVERT_BOOLEAN)
350     return default_invert_boolean_transform (value_a, value_b);
351
352   return default_transform (value_a, value_b);
353 }
354
355 static void
356 on_source_notify (GObject    *gobject,
357                   GParamSpec *pspec,
358                   GBinding   *binding)
359 {
360   const gchar *p_name;
361   GValue from_value = G_VALUE_INIT;
362   GValue to_value = G_VALUE_INIT;
363   gboolean res;
364
365   if (binding->is_frozen)
366     return;
367
368   p_name = g_intern_string (pspec->name);
369
370   if (p_name != binding->source_property)
371     return;
372
373   g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
374   g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
375
376   g_object_get_property (binding->source, binding->source_pspec->name, &from_value);
377
378   res = binding->transform_s2t (binding,
379                                 &from_value,
380                                 &to_value,
381                                 binding->transform_data);
382   if (res)
383     {
384       binding->is_frozen = TRUE;
385
386       g_param_value_validate (binding->target_pspec, &to_value);
387       g_object_set_property (binding->target, binding->target_pspec->name, &to_value);
388
389       binding->is_frozen = FALSE;
390     }
391
392   g_value_unset (&from_value);
393   g_value_unset (&to_value);
394 }
395
396 static void
397 on_target_notify (GObject    *gobject,
398                   GParamSpec *pspec,
399                   GBinding   *binding)
400 {
401   const gchar *p_name;
402   GValue from_value = G_VALUE_INIT;
403   GValue to_value = G_VALUE_INIT;
404   gboolean res;
405
406   if (binding->is_frozen)
407     return;
408
409   p_name = g_intern_string (pspec->name);
410
411   if (p_name != binding->target_property)
412     return;
413
414   g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
415   g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
416
417   g_object_get_property (binding->target, binding->target_pspec->name, &from_value);
418
419   res = binding->transform_t2s (binding,
420                                 &from_value,
421                                 &to_value,
422                                 binding->transform_data);
423   if (res)
424     {
425       binding->is_frozen = TRUE;
426
427       g_param_value_validate (binding->source_pspec, &to_value);
428       g_object_set_property (binding->source, binding->source_pspec->name, &to_value);
429
430       binding->is_frozen = FALSE;
431     }
432
433   g_value_unset (&from_value);
434   g_value_unset (&to_value);
435 }
436
437 static inline void
438 g_binding_unbind_internal (GBinding *binding,
439                            gboolean  unref_binding)
440 {
441   /* dispose of the transformation data */
442   if (binding->notify != NULL)
443     {
444       binding->notify (binding->transform_data);
445
446       binding->transform_data = NULL;
447       binding->notify = NULL;
448     }
449
450   if (binding->source != NULL)
451     {
452       if (binding->source_notify != 0)
453         g_signal_handler_disconnect (binding->source, binding->source_notify);
454
455       g_object_weak_unref (binding->source, weak_unbind, binding);
456       remove_binding_qdata (binding->source, binding);
457
458       binding->source_notify = 0;
459       binding->source = NULL;
460     }
461
462   if (binding->target != NULL)
463     {
464       if (binding->target_notify != 0)
465         g_signal_handler_disconnect (binding->target, binding->target_notify);
466
467       g_object_weak_unref (binding->target, weak_unbind, binding);
468       remove_binding_qdata (binding->target, binding);
469
470       binding->target_notify = 0;
471       binding->target = NULL;
472     }
473
474   if (unref_binding)
475     g_object_unref (binding);
476 }
477
478 static void
479 g_binding_finalize (GObject *gobject)
480 {
481   GBinding *binding = G_BINDING (gobject);
482
483   g_binding_unbind_internal (binding, FALSE);
484
485   G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
486 }
487
488 static void
489 g_binding_set_property (GObject      *gobject,
490                         guint         prop_id,
491                         const GValue *value,
492                         GParamSpec   *pspec)
493 {
494   GBinding *binding = G_BINDING (gobject);
495
496   switch (prop_id)
497     {
498     case PROP_SOURCE:
499       binding->source = g_value_get_object (value);
500       break;
501
502     case PROP_SOURCE_PROPERTY:
503       binding->source_property = g_intern_string (g_value_get_string (value));
504       break;
505
506     case PROP_TARGET:
507       binding->target = g_value_get_object (value);
508       break;
509
510     case PROP_TARGET_PROPERTY:
511       binding->target_property = g_intern_string (g_value_get_string (value));
512       break;
513
514     case PROP_FLAGS:
515       binding->flags = g_value_get_flags (value);
516       break;
517
518     default:
519       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
520       break;
521     }
522 }
523
524 static void
525 g_binding_get_property (GObject    *gobject,
526                         guint       prop_id,
527                         GValue     *value,
528                         GParamSpec *pspec)
529 {
530   GBinding *binding = G_BINDING (gobject);
531
532   switch (prop_id)
533     {
534     case PROP_SOURCE:
535       g_value_set_object (value, binding->source);
536       break;
537
538     case PROP_SOURCE_PROPERTY:
539       g_value_set_string (value, binding->source_property);
540       break;
541
542     case PROP_TARGET:
543       g_value_set_object (value, binding->target);
544       break;
545
546     case PROP_TARGET_PROPERTY:
547       g_value_set_string (value, binding->target_property);
548       break;
549
550     case PROP_FLAGS:
551       g_value_set_flags (value, binding->flags);
552       break;
553
554     default:
555       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
556       break;
557     }
558 }
559
560 static void
561 g_binding_constructed (GObject *gobject)
562 {
563   GBinding *binding = G_BINDING (gobject);
564
565   /* assert that we were constructed correctly */
566   g_assert (binding->source != NULL);
567   g_assert (binding->target != NULL);
568   g_assert (binding->source_property != NULL);
569   g_assert (binding->target_property != NULL);
570
571   /* we assume a check was performed prior to construction - since
572    * g_object_bind_property_full() does it; we cannot fail construction
573    * anyway, so it would be hard for use to properly warn here
574    */
575   binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->source), binding->source_property);
576   binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (binding->target), binding->target_property);
577   g_assert (binding->source_pspec != NULL);
578   g_assert (binding->target_pspec != NULL);
579
580   /* set the default transformation functions here */
581   binding->transform_s2t = default_transform_to;
582   binding->transform_t2s = default_transform_from;
583
584   binding->transform_data = NULL;
585   binding->notify = NULL;
586
587   binding->source_notify = g_signal_connect (binding->source, "notify",
588                                              G_CALLBACK (on_source_notify),
589                                              binding);
590
591   g_object_weak_ref (binding->source, weak_unbind, binding);
592   add_binding_qdata (binding->source, binding);
593
594   if (binding->flags & G_BINDING_BIDIRECTIONAL)
595     binding->target_notify = g_signal_connect (binding->target, "notify",
596                                                G_CALLBACK (on_target_notify),
597                                                binding);
598
599   if (binding->target != binding->source)
600     {
601       g_object_weak_ref (binding->target, weak_unbind, binding);
602       add_binding_qdata (binding->target, binding);
603     }
604 }
605
606 static void
607 g_binding_class_init (GBindingClass *klass)
608 {
609   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
610
611   quark_gbinding = g_quark_from_static_string ("g-binding");
612
613   gobject_class->constructed = g_binding_constructed;
614   gobject_class->set_property = g_binding_set_property;
615   gobject_class->get_property = g_binding_get_property;
616   gobject_class->finalize = g_binding_finalize;
617
618   /**
619    * GBinding:source:
620    *
621    * The #GObject that should be used as the source of the binding
622    *
623    * Since: 2.26
624    */
625   g_object_class_install_property (gobject_class, PROP_SOURCE,
626                                    g_param_spec_object ("source",
627                                                         P_("Source"),
628                                                         P_("The source of the binding"),
629                                                         G_TYPE_OBJECT,
630                                                         G_PARAM_CONSTRUCT_ONLY |
631                                                         G_PARAM_READWRITE |
632                                                         G_PARAM_STATIC_STRINGS));
633   /**
634    * GBinding:target:
635    *
636    * The #GObject that should be used as the target of the binding
637    *
638    * Since: 2.26
639    */
640   g_object_class_install_property (gobject_class, PROP_TARGET,
641                                    g_param_spec_object ("target",
642                                                         P_("Target"),
643                                                         P_("The target of the binding"),
644                                                         G_TYPE_OBJECT,
645                                                         G_PARAM_CONSTRUCT_ONLY |
646                                                         G_PARAM_READWRITE |
647                                                         G_PARAM_STATIC_STRINGS));
648   /**
649    * GBinding:source-property:
650    *
651    * The name of the property of #GBinding:source that should be used
652    * as the source of the binding
653    *
654    * Since: 2.26
655    */
656   g_object_class_install_property (gobject_class, PROP_SOURCE_PROPERTY,
657                                    g_param_spec_string ("source-property",
658                                                         P_("Source Property"),
659                                                         P_("The property on the source to bind"),
660                                                         NULL,
661                                                         G_PARAM_CONSTRUCT_ONLY |
662                                                         G_PARAM_READWRITE |
663                                                         G_PARAM_STATIC_STRINGS));
664   /**
665    * GBinding:target-property:
666    *
667    * The name of the property of #GBinding:target that should be used
668    * as the target of the binding
669    *
670    * Since: 2.26
671    */
672   g_object_class_install_property (gobject_class, PROP_TARGET_PROPERTY,
673                                    g_param_spec_string ("target-property",
674                                                         P_("Target Property"),
675                                                         P_("The property on the target to bind"),
676                                                         NULL,
677                                                         G_PARAM_CONSTRUCT_ONLY |
678                                                         G_PARAM_READWRITE |
679                                                         G_PARAM_STATIC_STRINGS));
680   /**
681    * GBinding:flags:
682    *
683    * Flags to be used to control the #GBinding
684    *
685    * Since: 2.26
686    */
687   g_object_class_install_property (gobject_class, PROP_FLAGS,
688                                    g_param_spec_flags ("flags",
689                                                        P_("Flags"),
690                                                        P_("The binding flags"),
691                                                        G_TYPE_BINDING_FLAGS,
692                                                        G_BINDING_DEFAULT,
693                                                        G_PARAM_CONSTRUCT_ONLY |
694                                                        G_PARAM_READWRITE |
695                                                        G_PARAM_STATIC_STRINGS));
696 }
697
698 static void
699 g_binding_init (GBinding *binding)
700 {
701 }
702
703 /**
704  * g_binding_get_flags:
705  * @binding: a #GBinding
706  *
707  * Retrieves the flags passed when constructing the #GBinding.
708  *
709  * Returns: the #GBindingFlags used by the #GBinding
710  *
711  * Since: 2.26
712  */
713 GBindingFlags
714 g_binding_get_flags (GBinding *binding)
715 {
716   g_return_val_if_fail (G_IS_BINDING (binding), G_BINDING_DEFAULT);
717
718   return binding->flags;
719 }
720
721 /**
722  * g_binding_get_source:
723  * @binding: a #GBinding
724  *
725  * Retrieves the #GObject instance used as the source of the binding.
726  *
727  * Returns: (transfer none): the source #GObject
728  *
729  * Since: 2.26
730  */
731 GObject *
732 g_binding_get_source (GBinding *binding)
733 {
734   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
735
736   return binding->source;
737 }
738
739 /**
740  * g_binding_get_target:
741  * @binding: a #GBinding
742  *
743  * Retrieves the #GObject instance used as the target of the binding.
744  *
745  * Returns: (transfer none): the target #GObject
746  *
747  * Since: 2.26
748  */
749 GObject *
750 g_binding_get_target (GBinding *binding)
751 {
752   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
753
754   return binding->target;
755 }
756
757 /**
758  * g_binding_get_source_property:
759  * @binding: a #GBinding
760  *
761  * Retrieves the name of the property of #GBinding:source used as the source
762  * of the binding.
763  *
764  * Returns: the name of the source property
765  *
766  * Since: 2.26
767  */
768 const gchar *
769 g_binding_get_source_property (GBinding *binding)
770 {
771   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
772
773   return binding->source_property;
774 }
775
776 /**
777  * g_binding_get_target_property:
778  * @binding: a #GBinding
779  *
780  * Retrieves the name of the property of #GBinding:target used as the target
781  * of the binding.
782  *
783  * Returns: the name of the target property
784  *
785  * Since: 2.26
786  */
787 const gchar *
788 g_binding_get_target_property (GBinding *binding)
789 {
790   g_return_val_if_fail (G_IS_BINDING (binding), NULL);
791
792   return binding->target_property;
793 }
794
795 /**
796  * g_binding_unbind:
797  * @binding: a #GBinding
798  *
799  * Explicitly releases the binding between the source and the target
800  * property expressed by @binding.
801  *
802  * This function will release the reference that is being held on
803  * the @binding instance; if you want to hold on to the #GBinding instance
804  * after calling g_binding_unbind(), you will need to hold a reference
805  * to it.
806  *
807  * Since: 2.38
808  */
809 void
810 g_binding_unbind (GBinding *binding)
811 {
812   g_return_if_fail (G_IS_BINDING (binding));
813
814   g_binding_unbind_internal (binding, TRUE);
815 }
816
817 /**
818  * g_object_bind_property_full:
819  * @source: (type GObject.Object): the source #GObject
820  * @source_property: the property on @source to bind
821  * @target: (type GObject.Object): the target #GObject
822  * @target_property: the property on @target to bind
823  * @flags: flags to pass to #GBinding
824  * @transform_to: (scope notified) (allow-none): the transformation function
825  *     from the @source to the @target, or %NULL to use the default
826  * @transform_from: (scope notified) (allow-none): the transformation function
827  *     from the @target to the @source, or %NULL to use the default
828  * @user_data: custom data to be passed to the transformation functions,
829  *     or %NULL
830  * @notify: function to be called when disposing the binding, to free the
831  *     resources used by the transformation functions
832  *
833  * Complete version of g_object_bind_property().
834  *
835  * Creates a binding between @source_property on @source and @target_property
836  * on @target, allowing you to set the transformation functions to be used by
837  * the binding.
838  *
839  * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
840  * if @target_property on @target changes then the @source_property on @source
841  * will be updated as well. The @transform_from function is only used in case
842  * of bidirectional bindings, otherwise it will be ignored
843  *
844  * The binding will automatically be removed when either the @source or the
845  * @target instances are finalized. To remove the binding without affecting the
846  * @source and the @target you can just call g_object_unref() on the returned
847  * #GBinding instance.
848  *
849  * A #GObject can have multiple bindings.
850  *
851  * The same @user_data parameter will be used for both @transform_to
852  * and @transform_from transformation functions; the @notify function will
853  * be called once, when the binding is removed. If you need different data
854  * for each transformation function, please use
855  * g_object_bind_property_with_closures() instead.
856  *
857  * Returns: (transfer none): the #GBinding instance representing the
858  *     binding between the two #GObject instances. The binding is released
859  *     whenever the #GBinding reference count reaches zero.
860  *
861  * Since: 2.26
862  */
863 GBinding *
864 g_object_bind_property_full (gpointer               source,
865                              const gchar           *source_property,
866                              gpointer               target,
867                              const gchar           *target_property,
868                              GBindingFlags          flags,
869                              GBindingTransformFunc  transform_to,
870                              GBindingTransformFunc  transform_from,
871                              gpointer               user_data,
872                              GDestroyNotify         notify)
873 {
874   GParamSpec *pspec;
875   GBinding *binding;
876
877   g_return_val_if_fail (G_IS_OBJECT (source), NULL);
878   g_return_val_if_fail (source_property != NULL, NULL);
879   g_return_val_if_fail (G_IS_OBJECT (target), NULL);
880   g_return_val_if_fail (target_property != NULL, NULL);
881
882   if (source == target && g_strcmp0 (source_property, target_property) == 0)
883     {
884       g_warning ("Unable to bind the same property on the same instance");
885       return NULL;
886     }
887
888   /* remove the G_BINDING_INVERT_BOOLEAN flag in case we have
889    * custom transformation functions
890    */
891   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
892       (transform_to != NULL || transform_from != NULL))
893     {
894       flags &= ~G_BINDING_INVERT_BOOLEAN;
895     }
896
897   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), source_property);
898   if (pspec == NULL)
899     {
900       g_warning ("%s: The source object of type %s has no property called '%s'",
901                  G_STRLOC,
902                  G_OBJECT_TYPE_NAME (source),
903                  source_property);
904       return NULL;
905     }
906
907   if (!(pspec->flags & G_PARAM_READABLE))
908     {
909       g_warning ("%s: The source object of type %s has no readable property called '%s'",
910                  G_STRLOC,
911                  G_OBJECT_TYPE_NAME (source),
912                  source_property);
913       return NULL;
914     }
915
916   if ((flags & G_BINDING_BIDIRECTIONAL) &&
917       ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE)))
918     {
919       g_warning ("%s: The source object of type %s has no writable property called '%s'",
920                  G_STRLOC,
921                  G_OBJECT_TYPE_NAME (source),
922                  source_property);
923       return NULL;
924     }
925
926   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
927       !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
928     {
929       g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
930                  "when binding boolean properties; the source property '%s' "
931                  "is of type '%s'",
932                  G_STRLOC,
933                  source_property,
934                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
935       return NULL;
936     }
937
938   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), target_property);
939   if (pspec == NULL)
940     {
941       g_warning ("%s: The target object of type %s has no property called '%s'",
942                  G_STRLOC,
943                  G_OBJECT_TYPE_NAME (target),
944                  target_property);
945       return NULL;
946     }
947
948   if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE))
949     {
950       g_warning ("%s: The target object of type %s has no writable property called '%s'",
951                  G_STRLOC,
952                  G_OBJECT_TYPE_NAME (target),
953                  target_property);
954       return NULL;
955     }
956
957   if ((flags & G_BINDING_BIDIRECTIONAL) &&
958       !(pspec->flags & G_PARAM_READABLE))
959     {
960       g_warning ("%s: The target object of type %s has no readable property called '%s'",
961                  G_STRLOC,
962                  G_OBJECT_TYPE_NAME (target),
963                  target_property);
964       return NULL;
965     }
966
967   if ((flags & G_BINDING_INVERT_BOOLEAN) &&
968       !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
969     {
970       g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
971                  "when binding boolean properties; the target property '%s' "
972                  "is of type '%s'",
973                  G_STRLOC,
974                  target_property,
975                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
976       return NULL;
977     }
978
979   binding = g_object_new (G_TYPE_BINDING,
980                           "source", source,
981                           "source-property", source_property,
982                           "target", target,
983                           "target-property", target_property,
984                           "flags", flags,
985                           NULL);
986
987   if (transform_to != NULL)
988     binding->transform_s2t = transform_to;
989
990   if (transform_from != NULL)
991     binding->transform_t2s = transform_from;
992
993   binding->transform_data = user_data;
994   binding->notify = notify;
995
996   /* synchronize the target with the source by faking an emission of
997    * the ::notify signal for the source property; this will also take
998    * care of the bidirectional binding case because the eventual change
999    * will emit a notification on the target
1000    */
1001   if (flags & G_BINDING_SYNC_CREATE)
1002     on_source_notify (binding->source, binding->source_pspec, binding);
1003
1004   return binding;
1005 }
1006
1007 /**
1008  * g_object_bind_property:
1009  * @source: (type GObject.Object): the source #GObject
1010  * @source_property: the property on @source to bind
1011  * @target: (type GObject.Object): the target #GObject
1012  * @target_property: the property on @target to bind
1013  * @flags: flags to pass to #GBinding
1014  *
1015  * Creates a binding between @source_property on @source and @target_property
1016  * on @target. Whenever the @source_property is changed the @target_property is
1017  * updated using the same value. For instance:
1018  *
1019  * |[
1020  *   g_object_bind_property (action, "active", widget, "sensitive", 0);
1021  * ]|
1022  *
1023  * Will result in the "sensitive" property of the widget #GObject instance to be
1024  * updated with the same value of the "active" property of the action #GObject
1025  * instance.
1026  *
1027  * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
1028  * if @target_property on @target changes then the @source_property on @source
1029  * will be updated as well.
1030  *
1031  * The binding will automatically be removed when either the @source or the
1032  * @target instances are finalized. To remove the binding without affecting the
1033  * @source and the @target you can just call g_object_unref() on the returned
1034  * #GBinding instance.
1035  *
1036  * A #GObject can have multiple bindings.
1037  *
1038  * Returns: (transfer none): the #GBinding instance representing the
1039  *     binding between the two #GObject instances. The binding is released
1040  *     whenever the #GBinding reference count reaches zero.
1041  *
1042  * Since: 2.26
1043  */
1044 GBinding *
1045 g_object_bind_property (gpointer       source,
1046                         const gchar   *source_property,
1047                         gpointer       target,
1048                         const gchar   *target_property,
1049                         GBindingFlags  flags)
1050 {
1051   /* type checking is done in g_object_bind_property_full() */
1052
1053   return g_object_bind_property_full (source, source_property,
1054                                       target, target_property,
1055                                       flags,
1056                                       NULL,
1057                                       NULL,
1058                                       NULL, NULL);
1059 }
1060
1061 typedef struct _TransformData
1062 {
1063   GClosure *transform_to_closure;
1064   GClosure *transform_from_closure;
1065 } TransformData;
1066
1067 static gboolean
1068 bind_with_closures_transform_to (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_to_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 gboolean
1111 bind_with_closures_transform_from (GBinding     *binding,
1112                                    const GValue *source,
1113                                    GValue       *target,
1114                                    gpointer      data)
1115 {
1116   TransformData *t_data = data;
1117   GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
1118   GValue retval = G_VALUE_INIT;
1119   gboolean res;
1120
1121   g_value_init (&params[0], G_TYPE_BINDING);
1122   g_value_set_object (&params[0], binding);
1123
1124   g_value_init (&params[1], G_TYPE_VALUE);
1125   g_value_set_boxed (&params[1], source);
1126
1127   g_value_init (&params[2], G_TYPE_VALUE);
1128   g_value_set_boxed (&params[2], target);
1129
1130   g_value_init (&retval, G_TYPE_BOOLEAN);
1131   g_value_set_boolean (&retval, FALSE);
1132
1133   g_closure_invoke (t_data->transform_from_closure, &retval, 3, params, NULL);
1134
1135   res = g_value_get_boolean (&retval);
1136   if (res)
1137     {
1138       const GValue *out_value = g_value_get_boxed (&params[2]);
1139
1140       g_assert (out_value != NULL);
1141
1142       g_value_copy (out_value, target);
1143     }
1144
1145   g_value_unset (&params[0]);
1146   g_value_unset (&params[1]);
1147   g_value_unset (&params[2]);
1148   g_value_unset (&retval);
1149
1150   return res;
1151 }
1152
1153 static void
1154 bind_with_closures_free_func (gpointer data)
1155 {
1156   TransformData *t_data = data;
1157
1158   if (t_data->transform_to_closure != NULL)
1159     g_closure_unref (t_data->transform_to_closure);
1160
1161   if (t_data->transform_from_closure != NULL)
1162     g_closure_unref (t_data->transform_from_closure);
1163
1164   g_slice_free (TransformData, t_data);
1165 }
1166
1167 /**
1168  * g_object_bind_property_with_closures:
1169  * @source: (type GObject.Object): the source #GObject
1170  * @source_property: the property on @source to bind
1171  * @target: (type GObject.Object): the target #GObject
1172  * @target_property: the property on @target to bind
1173  * @flags: flags to pass to #GBinding
1174  * @transform_to: a #GClosure wrapping the transformation function
1175  *     from the @source to the @target, or %NULL to use the default
1176  * @transform_from: a #GClosure wrapping the transformation function
1177  *     from the @target to the @source, or %NULL to use the default
1178  *
1179  * Creates a binding between @source_property on @source and @target_property
1180  * on @target, allowing you to set the transformation functions to be used by
1181  * the binding.
1182  *
1183  * This function is the language bindings friendly version of
1184  * g_object_bind_property_full(), using #GClosures instead of
1185  * function pointers.
1186  *
1187  * Rename to: g_object_bind_property_full
1188  *
1189  * Returns: (transfer none): the #GBinding instance representing the
1190  *     binding between the two #GObject instances. The binding is released
1191  *     whenever the #GBinding reference count reaches zero.
1192  *
1193  * Since: 2.26
1194  */
1195 GBinding *
1196 g_object_bind_property_with_closures (gpointer       source,
1197                                       const gchar   *source_property,
1198                                       gpointer       target,
1199                                       const gchar   *target_property,
1200                                       GBindingFlags  flags,
1201                                       GClosure      *transform_to,
1202                                       GClosure      *transform_from)
1203 {
1204   TransformData *data;
1205
1206   data = g_slice_new0 (TransformData);
1207
1208   if (transform_to != NULL)
1209     {
1210       if (G_CLOSURE_NEEDS_MARSHAL (transform_to))
1211         g_closure_set_marshal (transform_to, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1212
1213       data->transform_to_closure = g_closure_ref (transform_to);
1214       g_closure_sink (data->transform_to_closure);
1215     }
1216
1217   if (transform_from != NULL)
1218     {
1219       if (G_CLOSURE_NEEDS_MARSHAL (transform_from))
1220         g_closure_set_marshal (transform_from, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1221
1222       data->transform_from_closure = g_closure_ref (transform_from);
1223       g_closure_sink (data->transform_from_closure);
1224     }
1225
1226   return g_object_bind_property_full (source, source_property,
1227                                       target, target_property,
1228                                       flags,
1229                                       transform_to != NULL ? bind_with_closures_transform_to : NULL,
1230                                       transform_from != NULL ? bind_with_closures_transform_from : NULL,
1231                                       data,
1232                                       bind_with_closures_free_func);
1233 }