1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gobjectalias.h"
21 #include <glib/gdatasetprivate.h>
24 * MT safe with regards to reference counting.
27 #include "gvaluecollector.h"
29 #include "gparamspecs.h"
30 #include "gvaluetypes.h"
31 #include "gobjectnotifyqueue.c"
36 #define PREALLOC_CPARAMS (8)
40 #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
41 #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
43 #define OBJECT_HAS_TOGGLE_REF_FLAG 0x1
44 #define OBJECT_HAS_TOGGLE_REF(object) \
45 ((G_DATALIST_GET_FLAGS (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
46 #define OBJECT_FLOATING_FLAG 0x2
56 /* --- properties --- */
62 /* --- prototypes --- */
63 static void g_object_base_class_init (GObjectClass
*class);
64 static void g_object_base_class_finalize (GObjectClass
*class);
65 static void g_object_do_class_init (GObjectClass
*class);
66 static void g_object_init (GObject
*object
);
67 static GObject
* g_object_constructor (GType type
,
68 guint n_construct_properties
,
69 GObjectConstructParam
*construct_params
);
70 static void g_object_real_dispose (GObject
*object
);
71 static void g_object_finalize (GObject
*object
);
72 static void g_object_do_set_property (GObject
*object
,
76 static void g_object_do_get_property (GObject
*object
,
80 static void g_value_object_init (GValue
*value
);
81 static void g_value_object_free_value (GValue
*value
);
82 static void g_value_object_copy_value (const GValue
*src_value
,
84 static void g_value_object_transform_value (const GValue
*src_value
,
86 static gpointer
g_value_object_peek_pointer (const GValue
*value
);
87 static gchar
* g_value_object_collect_value (GValue
*value
,
88 guint n_collect_values
,
89 GTypeCValue
*collect_values
,
91 static gchar
* g_value_object_lcopy_value (const GValue
*value
,
92 guint n_collect_values
,
93 GTypeCValue
*collect_values
,
95 static void g_object_dispatch_properties_changed (GObject
*object
,
98 static inline void object_get_property (GObject
*object
,
101 static inline void object_set_property (GObject
*object
,
104 GObjectNotifyQueue
*nqueue
);
105 static guint
object_floating_flag_handler (GObject
*object
,
108 static void object_interface_check_properties (gpointer func_data
,
112 /* --- variables --- */
113 static GQuark quark_closure_array
= 0;
114 static GQuark quark_weak_refs
= 0;
115 static GQuark quark_toggle_refs
= 0;
116 static GParamSpecPool
*pspec_pool
= NULL
;
117 static GObjectNotifyContext property_notify_context
= { 0, };
118 static gulong gobject_signals
[LAST_SIGNAL
] = { 0, };
119 G_LOCK_DEFINE_STATIC (construct_objects_lock
);
120 static GSList
*construct_objects
= NULL
;
121 static guint (*floating_flag_handler
) (GObject
*, gint
) = object_floating_flag_handler
;
123 /* --- functions --- */
124 #ifdef G_ENABLE_DEBUG
125 #define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
126 G_LOCK_DEFINE_STATIC (debug_objects
);
127 static volatile GObject
*g_trap_object_ref
= NULL
;
128 static guint debug_objects_count
= 0;
129 static GHashTable
*debug_objects_ht
= NULL
;
131 debug_objects_foreach (gpointer key
,
135 GObject
*object
= value
;
137 g_message ("[%p] stale %s\tref_count=%u",
139 G_OBJECT_TYPE_NAME (object
),
143 debug_objects_atexit (void)
147 G_LOCK (debug_objects
);
148 g_message ("stale GObjects: %u", debug_objects_count
);
149 g_hash_table_foreach (debug_objects_ht
, debug_objects_foreach
, NULL
);
150 G_UNLOCK (debug_objects
);
153 #endif /* G_ENABLE_DEBUG */
156 g_object_type_init (void)
158 static gboolean initialized
= FALSE
;
159 static const GTypeFundamentalInfo finfo
= {
160 G_TYPE_FLAG_CLASSED
| G_TYPE_FLAG_INSTANTIATABLE
| G_TYPE_FLAG_DERIVABLE
| G_TYPE_FLAG_DEEP_DERIVABLE
,
162 static GTypeInfo info
= {
163 sizeof (GObjectClass
),
164 (GBaseInitFunc
) g_object_base_class_init
,
165 (GBaseFinalizeFunc
) g_object_base_class_finalize
,
166 (GClassInitFunc
) g_object_do_class_init
,
167 NULL
/* class_destroy */,
168 NULL
/* class_data */,
171 (GInstanceInitFunc
) g_object_init
,
172 NULL
, /* value_table */
174 static const GTypeValueTable value_table
= {
175 g_value_object_init
, /* value_init */
176 g_value_object_free_value
, /* value_free */
177 g_value_object_copy_value
, /* value_copy */
178 g_value_object_peek_pointer
, /* value_peek_pointer */
179 "p", /* collect_format */
180 g_value_object_collect_value
, /* collect_value */
181 "p", /* lcopy_format */
182 g_value_object_lcopy_value
, /* lcopy_value */
186 g_return_if_fail (initialized
== FALSE
);
191 info
.value_table
= &value_table
;
192 type
= g_type_register_fundamental (G_TYPE_OBJECT
, g_intern_static_string ("GObject"), &info
, &finfo
, 0);
193 g_assert (type
== G_TYPE_OBJECT
);
194 g_value_register_transform_func (G_TYPE_OBJECT
, G_TYPE_OBJECT
, g_value_object_transform_value
);
196 #ifdef G_ENABLE_DEBUG
199 debug_objects_ht
= g_hash_table_new (g_direct_hash
, NULL
);
200 g_atexit (debug_objects_atexit
);
202 #endif /* G_ENABLE_DEBUG */
206 g_object_base_class_init (GObjectClass
*class)
208 GObjectClass
*pclass
= g_type_class_peek_parent (class);
210 /* reset instance specific fields and methods that don't get inherited */
211 class->construct_properties
= pclass
? g_slist_copy (pclass
->construct_properties
) : NULL
;
212 class->get_property
= NULL
;
213 class->set_property
= NULL
;
217 g_object_base_class_finalize (GObjectClass
*class)
221 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
223 g_slist_free (class->construct_properties
);
224 class->construct_properties
= NULL
;
225 list
= g_param_spec_pool_list_owned (pspec_pool
, G_OBJECT_CLASS_TYPE (class));
226 for (node
= list
; node
; node
= node
->next
)
228 GParamSpec
*pspec
= node
->data
;
230 g_param_spec_pool_remove (pspec_pool
, pspec
);
231 PARAM_SPEC_SET_PARAM_ID (pspec
, 0);
232 g_param_spec_unref (pspec
);
238 g_object_notify_dispatcher (GObject
*object
,
242 G_OBJECT_GET_CLASS (object
)->dispatch_properties_changed (object
, n_pspecs
, pspecs
);
246 g_object_do_class_init (GObjectClass
*class)
248 /* read the comment about typedef struct CArray; on why not to change this quark */
249 quark_closure_array
= g_quark_from_static_string ("GObject-closure-array");
251 quark_weak_refs
= g_quark_from_static_string ("GObject-weak-references");
252 quark_toggle_refs
= g_quark_from_static_string ("GObject-toggle-references");
253 pspec_pool
= g_param_spec_pool_new (TRUE
);
254 property_notify_context
.quark_notify_queue
= g_quark_from_static_string ("GObject-notify-queue");
255 property_notify_context
.dispatcher
= g_object_notify_dispatcher
;
257 class->constructor
= g_object_constructor
;
258 class->set_property
= g_object_do_set_property
;
259 class->get_property
= g_object_do_get_property
;
260 class->dispose
= g_object_real_dispose
;
261 class->finalize
= g_object_finalize
;
262 class->dispatch_properties_changed
= g_object_dispatch_properties_changed
;
263 class->notify
= NULL
;
265 gobject_signals
[NOTIFY
] =
266 g_signal_new (g_intern_static_string ("notify"),
267 G_TYPE_FROM_CLASS (class),
268 G_SIGNAL_RUN_FIRST
| G_SIGNAL_NO_RECURSE
| G_SIGNAL_DETAILED
| G_SIGNAL_NO_HOOKS
| G_SIGNAL_ACTION
,
269 G_STRUCT_OFFSET (GObjectClass
, notify
),
271 g_cclosure_marshal_VOID__PARAM
,
275 /* Install a check function that we'll use to verify that classes that
276 * implement an interface implement all properties for that interface
278 g_type_add_interface_check (NULL
, object_interface_check_properties
);
282 install_property_internal (GType g_type
,
286 if (g_param_spec_pool_lookup (pspec_pool
, pspec
->name
, g_type
, FALSE
))
288 g_warning ("When installing property: type `%s' already has a property named `%s'",
289 g_type_name (g_type
),
294 g_param_spec_ref (pspec
);
295 g_param_spec_sink (pspec
);
296 PARAM_SPEC_SET_PARAM_ID (pspec
, property_id
);
297 g_param_spec_pool_insert (pspec_pool
, pspec
, g_type
);
301 g_object_class_install_property (GObjectClass
*class,
305 g_return_if_fail (G_IS_OBJECT_CLASS (class));
306 g_return_if_fail (G_IS_PARAM_SPEC (pspec
));
307 if (pspec
->flags
& G_PARAM_WRITABLE
)
308 g_return_if_fail (class->set_property
!= NULL
);
309 if (pspec
->flags
& G_PARAM_READABLE
)
310 g_return_if_fail (class->get_property
!= NULL
);
311 g_return_if_fail (property_id
> 0);
312 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec
) == 0); /* paranoid */
313 if (pspec
->flags
& G_PARAM_CONSTRUCT
)
314 g_return_if_fail ((pspec
->flags
& G_PARAM_CONSTRUCT_ONLY
) == 0);
315 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
316 g_return_if_fail (pspec
->flags
& G_PARAM_WRITABLE
);
318 install_property_internal (G_OBJECT_CLASS_TYPE (class), property_id
, pspec
);
320 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
321 class->construct_properties
= g_slist_prepend (class->construct_properties
, pspec
);
323 /* for property overrides of construct poperties, we have to get rid
324 * of the overidden inherited construct property
326 pspec
= g_param_spec_pool_lookup (pspec_pool
, pspec
->name
, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE
);
327 if (pspec
&& pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
328 class->construct_properties
= g_slist_remove (class->construct_properties
, pspec
);
332 g_object_interface_install_property (gpointer g_iface
,
335 GTypeInterface
*iface_class
= g_iface
;
337 g_return_if_fail (G_TYPE_IS_INTERFACE (iface_class
->g_type
));
338 g_return_if_fail (G_IS_PARAM_SPEC (pspec
));
339 g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec
)); /* paranoid */
340 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec
) == 0); /* paranoid */
342 install_property_internal (iface_class
->g_type
, 0, pspec
);
346 g_object_class_find_property (GObjectClass
*class,
347 const gchar
*property_name
)
350 GParamSpec
*redirect
;
352 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL
);
353 g_return_val_if_fail (property_name
!= NULL
, NULL
);
355 pspec
= g_param_spec_pool_lookup (pspec_pool
,
357 G_OBJECT_CLASS_TYPE (class),
361 redirect
= g_param_spec_get_redirect_target (pspec
);
372 g_object_interface_find_property (gpointer g_iface
,
373 const gchar
*property_name
)
375 GTypeInterface
*iface_class
= g_iface
;
377 g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class
->g_type
), NULL
);
378 g_return_val_if_fail (property_name
!= NULL
, NULL
);
380 return g_param_spec_pool_lookup (pspec_pool
,
387 g_object_class_override_property (GObjectClass
*oclass
,
391 GParamSpec
*overridden
= NULL
;
395 g_return_if_fail (G_IS_OBJECT_CLASS (oclass
));
396 g_return_if_fail (property_id
> 0);
397 g_return_if_fail (name
!= NULL
);
399 /* Find the overridden property; first check parent types
401 parent_type
= g_type_parent (G_OBJECT_CLASS_TYPE (oclass
));
402 if (parent_type
!= G_TYPE_NONE
)
403 overridden
= g_param_spec_pool_lookup (pspec_pool
,
412 /* Now check interfaces
414 ifaces
= g_type_interfaces (G_OBJECT_CLASS_TYPE (oclass
), &n_ifaces
);
415 while (n_ifaces
-- && !overridden
)
417 overridden
= g_param_spec_pool_lookup (pspec_pool
,
428 g_warning ("%s: Can't find property to override for '%s::%s'",
429 G_STRFUNC
, G_OBJECT_CLASS_NAME (oclass
), name
);
433 new = g_param_spec_override (name
, overridden
);
434 g_object_class_install_property (oclass
, property_id
, new);
437 GParamSpec
** /* free result */
438 g_object_class_list_properties (GObjectClass
*class,
439 guint
*n_properties_p
)
444 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL
);
446 pspecs
= g_param_spec_pool_list (pspec_pool
,
447 G_OBJECT_CLASS_TYPE (class),
455 GParamSpec
** /* free result */
456 g_object_interface_list_properties (gpointer g_iface
,
457 guint
*n_properties_p
)
459 GTypeInterface
*iface_class
= g_iface
;
463 g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class
->g_type
), NULL
);
465 pspecs
= g_param_spec_pool_list (pspec_pool
,
475 g_object_init (GObject
*object
)
477 object
->ref_count
= 1;
478 g_datalist_init (&object
->qdata
);
480 /* freeze object's notification queue, g_object_newv() preserves pairedness */
481 g_object_notify_queue_freeze (object
, &property_notify_context
);
483 /* allow construct-only properties to be set */
484 G_LOCK (construct_objects_lock
);
485 construct_objects
= g_slist_prepend (construct_objects
, object
);
486 G_UNLOCK (construct_objects_lock
);
488 #ifdef G_ENABLE_DEBUG
491 G_LOCK (debug_objects
);
492 debug_objects_count
++;
493 g_hash_table_insert (debug_objects_ht
, object
, object
);
494 G_UNLOCK (debug_objects
);
496 #endif /* G_ENABLE_DEBUG */
500 g_object_do_set_property (GObject
*object
,
508 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
514 g_object_do_get_property (GObject
*object
,
522 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
528 g_object_real_dispose (GObject
*object
)
530 g_signal_handlers_destroy (object
);
531 g_datalist_id_set_data (&object
->qdata
, quark_closure_array
, NULL
);
532 g_datalist_id_set_data (&object
->qdata
, quark_weak_refs
, NULL
);
536 g_object_finalize (GObject
*object
)
538 g_datalist_clear (&object
->qdata
);
540 #ifdef G_ENABLE_DEBUG
543 G_LOCK (debug_objects
);
544 g_assert (g_hash_table_lookup (debug_objects_ht
, object
) == object
);
545 g_hash_table_remove (debug_objects_ht
, object
);
546 debug_objects_count
--;
547 G_UNLOCK (debug_objects
);
549 #endif /* G_ENABLE_DEBUG */
554 g_object_dispatch_properties_changed (GObject
*object
,
560 for (i
= 0; i
< n_pspecs
; i
++)
561 g_signal_emit (object
, gobject_signals
[NOTIFY
], g_quark_from_string (pspecs
[i
]->name
), pspecs
[i
]);
565 g_object_run_dispose (GObject
*object
)
567 g_return_if_fail (G_IS_OBJECT (object
));
568 g_return_if_fail (object
->ref_count
> 0);
570 g_object_ref (object
);
571 G_OBJECT_GET_CLASS (object
)->dispose (object
);
572 g_object_unref (object
);
576 g_object_freeze_notify (GObject
*object
)
578 g_return_if_fail (G_IS_OBJECT (object
));
580 if (g_atomic_int_get (&object
->ref_count
) == 0)
583 g_object_ref (object
);
584 g_object_notify_queue_freeze (object
, &property_notify_context
);
585 g_object_unref (object
);
589 g_object_notify (GObject
*object
,
590 const gchar
*property_name
)
594 g_return_if_fail (G_IS_OBJECT (object
));
595 g_return_if_fail (property_name
!= NULL
);
596 if (g_atomic_int_get (&object
->ref_count
) == 0)
599 g_object_ref (object
);
600 /* We don't need to get the redirect target
601 * (by, e.g. calling g_object_class_find_property())
602 * because g_object_notify_queue_add() does that
604 pspec
= g_param_spec_pool_lookup (pspec_pool
,
606 G_OBJECT_TYPE (object
),
610 g_warning ("%s: object class `%s' has no property named `%s'",
612 G_OBJECT_TYPE_NAME (object
),
616 GObjectNotifyQueue
*nqueue
;
618 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
619 g_object_notify_queue_add (object
, nqueue
, pspec
);
620 g_object_notify_queue_thaw (object
, nqueue
);
622 g_object_unref (object
);
626 g_object_thaw_notify (GObject
*object
)
628 GObjectNotifyQueue
*nqueue
;
630 g_return_if_fail (G_IS_OBJECT (object
));
631 if (g_atomic_int_get (&object
->ref_count
) == 0)
634 g_object_ref (object
);
635 nqueue
= g_object_notify_queue_from_object (object
, &property_notify_context
);
636 if (!nqueue
|| !nqueue
->freeze_count
)
637 g_warning ("%s: property-changed notification for %s(%p) is not frozen",
638 G_STRFUNC
, G_OBJECT_TYPE_NAME (object
), object
);
640 g_object_notify_queue_thaw (object
, nqueue
);
641 g_object_unref (object
);
645 object_get_property (GObject
*object
,
649 GObjectClass
*class = g_type_class_peek (pspec
->owner_type
);
650 guint param_id
= PARAM_SPEC_PARAM_ID (pspec
);
651 GParamSpec
*redirect
;
653 redirect
= g_param_spec_get_redirect_target (pspec
);
657 class->get_property (object
, param_id
, value
, pspec
);
661 object_set_property (GObject
*object
,
664 GObjectNotifyQueue
*nqueue
)
666 GValue tmp_value
= { 0, };
667 GObjectClass
*class = g_type_class_peek (pspec
->owner_type
);
668 guint param_id
= PARAM_SPEC_PARAM_ID (pspec
);
669 GParamSpec
*redirect
;
671 redirect
= g_param_spec_get_redirect_target (pspec
);
675 /* provide a copy to work from, convert (if necessary) and validate */
676 g_value_init (&tmp_value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
677 if (!g_value_transform (value
, &tmp_value
))
678 g_warning ("unable to set property `%s' of type `%s' from value of type `%s'",
680 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)),
681 G_VALUE_TYPE_NAME (value
));
682 else if (g_param_value_validate (pspec
, &tmp_value
) && !(pspec
->flags
& G_PARAM_LAX_VALIDATION
))
684 gchar
*contents
= g_strdup_value_contents (value
);
686 g_warning ("value \"%s\" of type `%s' is invalid or out of range for property `%s' of type `%s'",
688 G_VALUE_TYPE_NAME (value
),
690 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)));
695 class->set_property (object
, param_id
, &tmp_value
, pspec
);
696 g_object_notify_queue_add (object
, nqueue
, pspec
);
698 g_value_unset (&tmp_value
);
702 object_interface_check_properties (gpointer func_data
,
705 GTypeInterface
*iface_class
= g_iface
;
706 GObjectClass
*class = g_type_class_peek (iface_class
->g_instance_type
);
707 GType iface_type
= iface_class
->g_type
;
711 if (!G_IS_OBJECT_CLASS (class))
714 pspecs
= g_param_spec_pool_list (pspec_pool
, iface_type
, &n
);
718 GParamSpec
*class_pspec
= g_param_spec_pool_lookup (pspec_pool
,
720 G_OBJECT_CLASS_TYPE (class),
725 g_critical ("Object class %s doesn't implement property "
726 "'%s' from interface '%s'",
727 g_type_name (G_OBJECT_CLASS_TYPE (class)),
729 g_type_name (iface_type
));
734 /* The implementation paramspec must have a less restrictive
735 * type than the interface parameter spec for set() and a
736 * more restrictive type for get(). We just require equality,
737 * rather than doing something more complicated checking
738 * the READABLE and WRITABLE flags. We also simplify here
739 * by only checking the value type, not the G_PARAM_SPEC_TYPE.
742 !g_type_is_a (G_PARAM_SPEC_VALUE_TYPE (pspecs
[n
]),
743 G_PARAM_SPEC_VALUE_TYPE (class_pspec
)))
745 g_critical ("Property '%s' on class '%s' has type '%s' "
746 "which is different from the type '%s', "
747 "of the property on interface '%s'\n",
749 g_type_name (G_OBJECT_CLASS_TYPE (class)),
750 g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec
)),
751 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs
[n
])),
752 g_type_name (iface_type
));
755 #define SUBSET(a,b,mask) (((a) & ~(b) & (mask)) == 0)
757 /* CONSTRUCT and CONSTRUCT_ONLY add restrictions.
758 * READABLE and WRITABLE remove restrictions. The implementation
759 * paramspec must have less restrictive flags.
762 (!SUBSET (class_pspec
->flags
,
764 G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
) ||
765 !SUBSET (pspecs
[n
]->flags
,
767 G_PARAM_READABLE
| G_PARAM_WRITABLE
)))
769 g_critical ("Flags for property '%s' on class '%s' "
770 "are not compatible with the property on"
773 g_type_name (G_OBJECT_CLASS_TYPE (class)),
774 g_type_name (iface_type
));
783 g_object_new (GType object_type
,
784 const gchar
*first_property_name
,
790 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
792 va_start (var_args
, first_property_name
);
793 object
= g_object_new_valist (object_type
, first_property_name
, var_args
);
800 object_in_construction (GObject
*object
)
802 gboolean in_construction
;
803 G_LOCK (construct_objects_lock
);
804 in_construction
= g_slist_find (construct_objects
, object
) != NULL
;
805 G_UNLOCK (construct_objects_lock
);
806 return in_construction
;
810 g_object_newv (GType object_type
,
812 GParameter
*parameters
)
814 GObjectConstructParam
*cparams
, *oparams
;
815 GObjectNotifyQueue
*nqueue
;
817 GObjectClass
*class, *unref_class
= NULL
;
819 guint n_total_cparams
= 0, n_cparams
= 0, n_oparams
= 0, n_cvalues
;
824 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
826 class = g_type_class_peek_static (object_type
);
828 class = unref_class
= g_type_class_ref (object_type
);
829 for (slist
= class->construct_properties
; slist
; slist
= slist
->next
)
831 clist
= g_list_prepend (clist
, slist
->data
);
832 n_total_cparams
+= 1;
835 /* collect parameters, sort into construction and normal ones */
836 oparams
= g_new (GObjectConstructParam
, n_parameters
);
837 cparams
= g_new (GObjectConstructParam
, n_total_cparams
);
838 for (i
= 0; i
< n_parameters
; i
++)
840 GValue
*value
= ¶meters
[i
].value
;
841 GParamSpec
*pspec
= g_param_spec_pool_lookup (pspec_pool
,
847 g_warning ("%s: object class `%s' has no property named `%s'",
849 g_type_name (object_type
),
853 if (!(pspec
->flags
& G_PARAM_WRITABLE
))
855 g_warning ("%s: property `%s' of object class `%s' is not writable",
858 g_type_name (object_type
));
861 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
863 GList
*list
= g_list_find (clist
, pspec
);
867 g_warning ("%s: construct property \"%s\" for object `%s' can't be set twice",
868 G_STRFUNC
, pspec
->name
, g_type_name (object_type
));
871 cparams
[n_cparams
].pspec
= pspec
;
872 cparams
[n_cparams
].value
= value
;
877 list
->prev
->next
= list
->next
;
879 list
->next
->prev
= list
->prev
;
880 g_list_free_1 (list
);
884 oparams
[n_oparams
].pspec
= pspec
;
885 oparams
[n_oparams
].value
= value
;
890 /* set remaining construction properties to default values */
891 n_cvalues
= n_total_cparams
- n_cparams
;
892 cvalues
= g_new (GValue
, n_cvalues
);
895 GList
*tmp
= clist
->next
;
896 GParamSpec
*pspec
= clist
->data
;
897 GValue
*value
= cvalues
+ n_total_cparams
- n_cparams
- 1;
900 g_value_init (value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
901 g_param_value_set_default (pspec
, value
);
903 cparams
[n_cparams
].pspec
= pspec
;
904 cparams
[n_cparams
].value
= value
;
907 g_list_free_1 (clist
);
911 /* construct object from construction parameters */
912 object
= class->constructor (object_type
, n_total_cparams
, cparams
);
913 G_LOCK (construct_objects_lock
);
914 construct_objects
= g_slist_remove (construct_objects
, object
);
915 G_UNLOCK (construct_objects_lock
);
917 /* free construction values */
920 g_value_unset (cvalues
+ n_cvalues
);
923 /* release g_object_init() notification queue freeze_count */
924 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
925 g_object_notify_queue_thaw (object
, nqueue
);
927 /* set remaining properties */
928 for (i
= 0; i
< n_oparams
; i
++)
929 object_set_property (object
, oparams
[i
].pspec
, oparams
[i
].value
, nqueue
);
933 g_type_class_unref (unref_class
);
935 /* release our own freeze count and handle notifications */
936 g_object_notify_queue_thaw (object
, nqueue
);
942 g_object_new_valist (GType object_type
,
943 const gchar
*first_property_name
,
950 guint n_params
= 0, n_alloced_params
= 16;
952 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
954 if (!first_property_name
)
955 return g_object_newv (object_type
, 0, NULL
);
957 class = g_type_class_ref (object_type
);
959 params
= g_new (GParameter
, n_alloced_params
);
960 name
= first_property_name
;
964 GParamSpec
*pspec
= g_param_spec_pool_lookup (pspec_pool
,
970 g_warning ("%s: object class `%s' has no property named `%s'",
972 g_type_name (object_type
),
976 if (n_params
>= n_alloced_params
)
978 n_alloced_params
+= 16;
979 params
= g_renew (GParameter
, params
, n_alloced_params
);
981 params
[n_params
].name
= name
;
982 params
[n_params
].value
.g_type
= 0;
983 g_value_init (¶ms
[n_params
].value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
984 G_VALUE_COLLECT (¶ms
[n_params
].value
, var_args
, 0, &error
);
987 g_warning ("%s: %s", G_STRFUNC
, error
);
989 g_value_unset (¶ms
[n_params
].value
);
993 name
= va_arg (var_args
, gchar
*);
996 object
= g_object_newv (object_type
, n_params
, params
);
999 g_value_unset (¶ms
[n_params
].value
);
1002 g_type_class_unref (class);
1008 g_object_constructor (GType type
,
1009 guint n_construct_properties
,
1010 GObjectConstructParam
*construct_params
)
1015 object
= (GObject
*) g_type_create_instance (type
);
1017 /* set construction parameters */
1018 if (n_construct_properties
)
1020 GObjectNotifyQueue
*nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
1022 /* set construct properties */
1023 while (n_construct_properties
--)
1025 GValue
*value
= construct_params
->value
;
1026 GParamSpec
*pspec
= construct_params
->pspec
;
1029 object_set_property (object
, pspec
, value
, nqueue
);
1031 g_object_notify_queue_thaw (object
, nqueue
);
1032 /* the notification queue is still frozen from g_object_init(), so
1033 * we don't need to handle it here, g_object_newv() takes
1042 g_object_set_valist (GObject
*object
,
1043 const gchar
*first_property_name
,
1046 GObjectNotifyQueue
*nqueue
;
1049 g_return_if_fail (G_IS_OBJECT (object
));
1051 g_object_ref (object
);
1052 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
1054 name
= first_property_name
;
1057 GValue value
= { 0, };
1059 gchar
*error
= NULL
;
1061 pspec
= g_param_spec_pool_lookup (pspec_pool
,
1063 G_OBJECT_TYPE (object
),
1067 g_warning ("%s: object class `%s' has no property named `%s'",
1069 G_OBJECT_TYPE_NAME (object
),
1073 if (!(pspec
->flags
& G_PARAM_WRITABLE
))
1075 g_warning ("%s: property `%s' of object class `%s' is not writable",
1078 G_OBJECT_TYPE_NAME (object
));
1081 if ((pspec
->flags
& G_PARAM_CONSTRUCT_ONLY
) && !object_in_construction (object
))
1083 g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
1084 G_STRFUNC
, pspec
->name
, G_OBJECT_TYPE_NAME (object
));
1088 g_value_init (&value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
1090 G_VALUE_COLLECT (&value
, var_args
, 0, &error
);
1093 g_warning ("%s: %s", G_STRFUNC
, error
);
1095 g_value_unset (&value
);
1099 object_set_property (object
, pspec
, &value
, nqueue
);
1100 g_value_unset (&value
);
1102 name
= va_arg (var_args
, gchar
*);
1105 g_object_notify_queue_thaw (object
, nqueue
);
1106 g_object_unref (object
);
1110 g_object_get_valist (GObject
*object
,
1111 const gchar
*first_property_name
,
1116 g_return_if_fail (G_IS_OBJECT (object
));
1118 g_object_ref (object
);
1120 name
= first_property_name
;
1124 GValue value
= { 0, };
1128 pspec
= g_param_spec_pool_lookup (pspec_pool
,
1130 G_OBJECT_TYPE (object
),
1134 g_warning ("%s: object class `%s' has no property named `%s'",
1136 G_OBJECT_TYPE_NAME (object
),
1140 if (!(pspec
->flags
& G_PARAM_READABLE
))
1142 g_warning ("%s: property `%s' of object class `%s' is not readable",
1145 G_OBJECT_TYPE_NAME (object
));
1149 g_value_init (&value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
1151 object_get_property (object
, pspec
, &value
);
1153 G_VALUE_LCOPY (&value
, var_args
, 0, &error
);
1156 g_warning ("%s: %s", G_STRFUNC
, error
);
1158 g_value_unset (&value
);
1162 g_value_unset (&value
);
1164 name
= va_arg (var_args
, gchar
*);
1167 g_object_unref (object
);
1171 g_object_set (gpointer _object
,
1172 const gchar
*first_property_name
,
1175 GObject
*object
= _object
;
1178 g_return_if_fail (G_IS_OBJECT (object
));
1180 va_start (var_args
, first_property_name
);
1181 g_object_set_valist (object
, first_property_name
, var_args
);
1186 g_object_get (gpointer _object
,
1187 const gchar
*first_property_name
,
1190 GObject
*object
= _object
;
1193 g_return_if_fail (G_IS_OBJECT (object
));
1195 va_start (var_args
, first_property_name
);
1196 g_object_get_valist (object
, first_property_name
, var_args
);
1201 g_object_set_property (GObject
*object
,
1202 const gchar
*property_name
,
1203 const GValue
*value
)
1205 GObjectNotifyQueue
*nqueue
;
1208 g_return_if_fail (G_IS_OBJECT (object
));
1209 g_return_if_fail (property_name
!= NULL
);
1210 g_return_if_fail (G_IS_VALUE (value
));
1212 g_object_ref (object
);
1213 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
1215 pspec
= g_param_spec_pool_lookup (pspec_pool
,
1217 G_OBJECT_TYPE (object
),
1220 g_warning ("%s: object class `%s' has no property named `%s'",
1222 G_OBJECT_TYPE_NAME (object
),
1224 else if (!(pspec
->flags
& G_PARAM_WRITABLE
))
1225 g_warning ("%s: property `%s' of object class `%s' is not writable",
1228 G_OBJECT_TYPE_NAME (object
));
1229 else if ((pspec
->flags
& G_PARAM_CONSTRUCT_ONLY
) && !object_in_construction (object
))
1230 g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
1231 G_STRFUNC
, pspec
->name
, G_OBJECT_TYPE_NAME (object
));
1233 object_set_property (object
, pspec
, value
, nqueue
);
1235 g_object_notify_queue_thaw (object
, nqueue
);
1236 g_object_unref (object
);
1240 g_object_get_property (GObject
*object
,
1241 const gchar
*property_name
,
1246 g_return_if_fail (G_IS_OBJECT (object
));
1247 g_return_if_fail (property_name
!= NULL
);
1248 g_return_if_fail (G_IS_VALUE (value
));
1250 g_object_ref (object
);
1252 pspec
= g_param_spec_pool_lookup (pspec_pool
,
1254 G_OBJECT_TYPE (object
),
1257 g_warning ("%s: object class `%s' has no property named `%s'",
1259 G_OBJECT_TYPE_NAME (object
),
1261 else if (!(pspec
->flags
& G_PARAM_READABLE
))
1262 g_warning ("%s: property `%s' of object class `%s' is not readable",
1265 G_OBJECT_TYPE_NAME (object
));
1268 GValue
*prop_value
, tmp_value
= { 0, };
1270 /* auto-conversion of the callers value type
1272 if (G_VALUE_TYPE (value
) == G_PARAM_SPEC_VALUE_TYPE (pspec
))
1274 g_value_reset (value
);
1277 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec
), G_VALUE_TYPE (value
)))
1279 g_warning ("%s: can't retrieve property `%s' of type `%s' as value of type `%s'",
1280 G_STRFUNC
, pspec
->name
,
1281 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)),
1282 G_VALUE_TYPE_NAME (value
));
1283 g_object_unref (object
);
1288 g_value_init (&tmp_value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
1289 prop_value
= &tmp_value
;
1291 object_get_property (object
, pspec
, prop_value
);
1292 if (prop_value
!= value
)
1294 g_value_transform (prop_value
, value
);
1295 g_value_unset (&tmp_value
);
1299 g_object_unref (object
);
1303 g_object_connect (gpointer _object
,
1304 const gchar
*signal_spec
,
1307 GObject
*object
= _object
;
1310 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1311 g_return_val_if_fail (object
->ref_count
> 0, object
);
1313 va_start (var_args
, signal_spec
);
1316 GCallback callback
= va_arg (var_args
, GCallback
);
1317 gpointer data
= va_arg (var_args
, gpointer
);
1320 if (strncmp (signal_spec
, "signal::", 8) == 0)
1321 sid
= g_signal_connect_data (object
, signal_spec
+ 8,
1322 callback
, data
, NULL
,
1324 else if (strncmp (signal_spec
, "object_signal::", 15) == 0 ||
1325 strncmp (signal_spec
, "object-signal::", 15) == 0)
1326 sid
= g_signal_connect_object (object
, signal_spec
+ 15,
1329 else if (strncmp (signal_spec
, "swapped_signal::", 16) == 0 ||
1330 strncmp (signal_spec
, "swapped-signal::", 16) == 0)
1331 sid
= g_signal_connect_data (object
, signal_spec
+ 16,
1332 callback
, data
, NULL
,
1334 else if (strncmp (signal_spec
, "swapped_object_signal::", 23) == 0 ||
1335 strncmp (signal_spec
, "swapped-object-signal::", 23) == 0)
1336 sid
= g_signal_connect_object (object
, signal_spec
+ 23,
1339 else if (strncmp (signal_spec
, "signal_after::", 14) == 0 ||
1340 strncmp (signal_spec
, "signal-after::", 14) == 0)
1341 sid
= g_signal_connect_data (object
, signal_spec
+ 14,
1342 callback
, data
, NULL
,
1344 else if (strncmp (signal_spec
, "object_signal_after::", 21) == 0 ||
1345 strncmp (signal_spec
, "object-signal-after::", 21) == 0)
1346 sid
= g_signal_connect_object (object
, signal_spec
+ 21,
1349 else if (strncmp (signal_spec
, "swapped_signal_after::", 22) == 0 ||
1350 strncmp (signal_spec
, "swapped-signal-after::", 22) == 0)
1351 sid
= g_signal_connect_data (object
, signal_spec
+ 22,
1352 callback
, data
, NULL
,
1353 G_CONNECT_SWAPPED
| G_CONNECT_AFTER
);
1354 else if (strncmp (signal_spec
, "swapped_object_signal_after::", 29) == 0 ||
1355 strncmp (signal_spec
, "swapped-object-signal-after::", 29) == 0)
1356 sid
= g_signal_connect_object (object
, signal_spec
+ 29,
1358 G_CONNECT_SWAPPED
| G_CONNECT_AFTER
);
1361 g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC
, signal_spec
);
1364 signal_spec
= va_arg (var_args
, gchar
*);
1372 g_object_disconnect (gpointer _object
,
1373 const gchar
*signal_spec
,
1376 GObject
*object
= _object
;
1379 g_return_if_fail (G_IS_OBJECT (object
));
1380 g_return_if_fail (object
->ref_count
> 0);
1382 va_start (var_args
, signal_spec
);
1385 GCallback callback
= va_arg (var_args
, GCallback
);
1386 gpointer data
= va_arg (var_args
, gpointer
);
1387 guint sid
= 0, detail
= 0, mask
= 0;
1389 if (strncmp (signal_spec
, "any_signal::", 12) == 0 ||
1390 strncmp (signal_spec
, "any-signal::", 12) == 0)
1393 mask
= G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_FUNC
| G_SIGNAL_MATCH_DATA
;
1395 else if (strcmp (signal_spec
, "any_signal") == 0 ||
1396 strcmp (signal_spec
, "any-signal") == 0)
1399 mask
= G_SIGNAL_MATCH_FUNC
| G_SIGNAL_MATCH_DATA
;
1403 g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC
, signal_spec
);
1407 if ((mask
& G_SIGNAL_MATCH_ID
) &&
1408 !g_signal_parse_name (signal_spec
, G_OBJECT_TYPE (object
), &sid
, &detail
, FALSE
))
1409 g_warning ("%s: invalid signal name \"%s\"", G_STRFUNC
, signal_spec
);
1410 else if (!g_signal_handlers_disconnect_matched (object
, mask
| (detail
? G_SIGNAL_MATCH_DETAIL
: 0),
1412 NULL
, (gpointer
)callback
, data
))
1413 g_warning ("%s: signal handler %p(%p) is not connected", G_STRFUNC
, callback
, data
);
1414 signal_spec
= va_arg (var_args
, gchar
*);
1425 } weak_refs
[1]; /* flexible array */
1429 weak_refs_notify (gpointer data
)
1431 WeakRefStack
*wstack
= data
;
1434 for (i
= 0; i
< wstack
->n_weak_refs
; i
++)
1435 wstack
->weak_refs
[i
].notify (wstack
->weak_refs
[i
].data
, wstack
->object
);
1440 g_object_weak_ref (GObject
*object
,
1444 WeakRefStack
*wstack
;
1447 g_return_if_fail (G_IS_OBJECT (object
));
1448 g_return_if_fail (notify
!= NULL
);
1449 g_return_if_fail (object
->ref_count
>= 1);
1451 wstack
= g_datalist_id_remove_no_notify (&object
->qdata
, quark_weak_refs
);
1454 i
= wstack
->n_weak_refs
++;
1455 wstack
= g_realloc (wstack
, sizeof (*wstack
) + sizeof (wstack
->weak_refs
[0]) * i
);
1459 wstack
= g_renew (WeakRefStack
, NULL
, 1);
1460 wstack
->object
= object
;
1461 wstack
->n_weak_refs
= 1;
1464 wstack
->weak_refs
[i
].notify
= notify
;
1465 wstack
->weak_refs
[i
].data
= data
;
1466 g_datalist_id_set_data_full (&object
->qdata
, quark_weak_refs
, wstack
, weak_refs_notify
);
1470 g_object_weak_unref (GObject
*object
,
1474 WeakRefStack
*wstack
;
1475 gboolean found_one
= FALSE
;
1477 g_return_if_fail (G_IS_OBJECT (object
));
1478 g_return_if_fail (notify
!= NULL
);
1480 wstack
= g_datalist_id_get_data (&object
->qdata
, quark_weak_refs
);
1485 for (i
= 0; i
< wstack
->n_weak_refs
; i
++)
1486 if (wstack
->weak_refs
[i
].notify
== notify
&&
1487 wstack
->weak_refs
[i
].data
== data
)
1490 wstack
->n_weak_refs
-= 1;
1491 if (i
!= wstack
->n_weak_refs
)
1492 wstack
->weak_refs
[i
] = wstack
->weak_refs
[wstack
->n_weak_refs
];
1498 g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC
, notify
, data
);
1502 g_object_add_weak_pointer (GObject
*object
,
1503 gpointer
*weak_pointer_location
)
1505 g_return_if_fail (G_IS_OBJECT (object
));
1506 g_return_if_fail (weak_pointer_location
!= NULL
);
1508 g_object_weak_ref (object
,
1509 (GWeakNotify
) g_nullify_pointer
,
1510 weak_pointer_location
);
1514 g_object_remove_weak_pointer (GObject
*object
,
1515 gpointer
*weak_pointer_location
)
1517 g_return_if_fail (G_IS_OBJECT (object
));
1518 g_return_if_fail (weak_pointer_location
!= NULL
);
1520 g_object_weak_unref (object
,
1521 (GWeakNotify
) g_nullify_pointer
,
1522 weak_pointer_location
);
1526 object_floating_flag_handler (GObject
*object
,
1532 case +1: /* force floating if possible */
1534 oldvalue
= g_atomic_pointer_get (&object
->qdata
);
1535 while (!g_atomic_pointer_compare_and_exchange ((void**) &object
->qdata
, oldvalue
,
1536 (gpointer
) ((gsize
) oldvalue
| OBJECT_FLOATING_FLAG
)));
1537 return (gsize
) oldvalue
& OBJECT_FLOATING_FLAG
;
1538 case -1: /* sink if possible */
1540 oldvalue
= g_atomic_pointer_get (&object
->qdata
);
1541 while (!g_atomic_pointer_compare_and_exchange ((void**) &object
->qdata
, oldvalue
,
1542 (gpointer
) ((gsize
) oldvalue
& ~(gsize
) OBJECT_FLOATING_FLAG
)));
1543 return (gsize
) oldvalue
& OBJECT_FLOATING_FLAG
;
1544 default: /* check floating */
1545 return 0 != ((gsize
) g_atomic_pointer_get (&object
->qdata
) & OBJECT_FLOATING_FLAG
);
1550 g_object_is_floating (gpointer _object
)
1552 GObject
*object
= _object
;
1553 g_return_val_if_fail (G_IS_OBJECT (object
), FALSE
);
1554 return floating_flag_handler (object
, 0);
1558 g_object_ref_sink (gpointer _object
)
1560 GObject
*object
= _object
;
1561 gboolean was_floating
;
1562 g_return_val_if_fail (G_IS_OBJECT (object
), object
);
1563 g_return_val_if_fail (object
->ref_count
>= 1, object
);
1564 g_object_ref (object
);
1565 was_floating
= floating_flag_handler (object
, -1);
1567 g_object_unref (object
);
1572 g_object_force_floating (GObject
*object
)
1574 gboolean was_floating
;
1575 g_return_if_fail (G_IS_OBJECT (object
));
1576 g_return_if_fail (object
->ref_count
>= 1);
1578 was_floating
= floating_flag_handler (object
, +1);
1583 guint n_toggle_refs
;
1585 GToggleNotify notify
;
1587 } toggle_refs
[1]; /* flexible array */
1591 toggle_refs_notify (GObject
*object
,
1592 gboolean is_last_ref
)
1594 ToggleRefStack
*tstack
= g_datalist_id_get_data (&object
->qdata
, quark_toggle_refs
);
1596 /* Reentrancy here is not as tricky as it seems, because a toggle reference
1597 * will only be notified when there is exactly one of them.
1599 g_assert (tstack
->n_toggle_refs
== 1);
1600 tstack
->toggle_refs
[0].notify (tstack
->toggle_refs
[0].data
, tstack
->object
, is_last_ref
);
1604 g_object_add_toggle_ref (GObject
*object
,
1605 GToggleNotify notify
,
1608 ToggleRefStack
*tstack
;
1611 g_return_if_fail (G_IS_OBJECT (object
));
1612 g_return_if_fail (notify
!= NULL
);
1613 g_return_if_fail (object
->ref_count
>= 1);
1615 g_object_ref (object
);
1617 tstack
= g_datalist_id_remove_no_notify (&object
->qdata
, quark_toggle_refs
);
1620 i
= tstack
->n_toggle_refs
++;
1621 /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
1622 * in tstate->toggle_refs */
1623 tstack
= g_realloc (tstack
, sizeof (*tstack
) + sizeof (tstack
->toggle_refs
[0]) * i
);
1627 tstack
= g_renew (ToggleRefStack
, NULL
, 1);
1628 tstack
->object
= object
;
1629 tstack
->n_toggle_refs
= 1;
1633 /* Set a flag for fast lookup after adding the first toggle reference */
1634 if (tstack
->n_toggle_refs
== 1)
1635 g_datalist_set_flags (&object
->qdata
, OBJECT_HAS_TOGGLE_REF_FLAG
);
1637 tstack
->toggle_refs
[i
].notify
= notify
;
1638 tstack
->toggle_refs
[i
].data
= data
;
1639 g_datalist_id_set_data_full (&object
->qdata
, quark_toggle_refs
, tstack
,
1640 (GDestroyNotify
)g_free
);
1644 g_object_remove_toggle_ref (GObject
*object
,
1645 GToggleNotify notify
,
1648 ToggleRefStack
*tstack
;
1649 gboolean found_one
= FALSE
;
1651 g_return_if_fail (G_IS_OBJECT (object
));
1652 g_return_if_fail (notify
!= NULL
);
1654 tstack
= g_datalist_id_get_data (&object
->qdata
, quark_toggle_refs
);
1659 for (i
= 0; i
< tstack
->n_toggle_refs
; i
++)
1660 if (tstack
->toggle_refs
[i
].notify
== notify
&&
1661 tstack
->toggle_refs
[i
].data
== data
)
1664 tstack
->n_toggle_refs
-= 1;
1665 if (i
!= tstack
->n_toggle_refs
)
1666 tstack
->toggle_refs
[i
] = tstack
->toggle_refs
[tstack
->n_toggle_refs
];
1668 if (tstack
->n_toggle_refs
== 0)
1669 g_datalist_unset_flags (&object
->qdata
, OBJECT_HAS_TOGGLE_REF_FLAG
);
1671 g_object_unref (object
);
1678 g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC
, notify
, data
);
1682 g_object_ref (gpointer _object
)
1684 GObject
*object
= _object
;
1687 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1688 g_return_val_if_fail (object
->ref_count
> 0, NULL
);
1690 #ifdef G_ENABLE_DEBUG
1691 if (g_trap_object_ref
== object
)
1693 #endif /* G_ENABLE_DEBUG */
1696 old_val
= g_atomic_int_exchange_and_add (&object
->ref_count
, 1);
1698 if (old_val
== 1 && OBJECT_HAS_TOGGLE_REF (object
))
1699 toggle_refs_notify (object
, FALSE
);
1705 g_object_unref (gpointer _object
)
1707 GObject
*object
= _object
;
1711 g_return_if_fail (G_IS_OBJECT (object
));
1712 g_return_if_fail (object
->ref_count
> 0);
1714 #ifdef G_ENABLE_DEBUG
1715 if (g_trap_object_ref
== object
)
1717 #endif /* G_ENABLE_DEBUG */
1719 /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
1720 retry_atomic_decrement1
:
1721 old_ref
= g_atomic_int_get (&object
->ref_count
);
1724 if (!g_atomic_int_compare_and_exchange (&object
->ref_count
, old_ref
, old_ref
- 1))
1725 goto retry_atomic_decrement1
;
1727 /* if we went from 2->1 we need to notify toggle refs if any */
1728 if (old_ref
== 2 && OBJECT_HAS_TOGGLE_REF (object
))
1729 toggle_refs_notify (object
, TRUE
);
1733 /* we are about tp remove the last reference */
1734 G_OBJECT_GET_CLASS (object
)->dispose (object
);
1736 /* may have been re-referenced meanwhile */
1737 retry_atomic_decrement2
:
1738 old_ref
= g_atomic_int_get (&object
->ref_count
);
1741 if (!g_atomic_int_compare_and_exchange (&object
->ref_count
, old_ref
, old_ref
- 1))
1742 goto retry_atomic_decrement2
;
1744 /* if we went from 2->1 we need to notify toggle refs if any */
1745 if (old_ref
== 2 && OBJECT_HAS_TOGGLE_REF (object
))
1746 toggle_refs_notify (object
, TRUE
);
1751 /* we are still in the process of taking away the last ref */
1752 g_datalist_id_set_data (&object
->qdata
, quark_closure_array
, NULL
);
1753 g_signal_handlers_destroy (object
);
1754 g_datalist_id_set_data (&object
->qdata
, quark_weak_refs
, NULL
);
1756 /* decrement the last reference */
1757 is_zero
= g_atomic_int_dec_and_test (&object
->ref_count
);
1759 /* may have been re-referenced meanwhile */
1760 if (G_LIKELY (is_zero
))
1762 G_OBJECT_GET_CLASS (object
)->finalize (object
);
1763 #ifdef G_ENABLE_DEBUG
1766 /* catch objects not chaining finalize handlers */
1767 G_LOCK (debug_objects
);
1768 g_assert (g_hash_table_lookup (debug_objects_ht
, object
) == NULL
);
1769 G_UNLOCK (debug_objects
);
1771 #endif /* G_ENABLE_DEBUG */
1772 g_type_free_instance ((GTypeInstance
*) object
);
1778 g_object_get_qdata (GObject
*object
,
1781 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1783 return quark
? g_datalist_id_get_data (&object
->qdata
, quark
) : NULL
;
1787 g_object_set_qdata (GObject
*object
,
1791 g_return_if_fail (G_IS_OBJECT (object
));
1792 g_return_if_fail (quark
> 0);
1794 g_datalist_id_set_data (&object
->qdata
, quark
, data
);
1798 g_object_set_qdata_full (GObject
*object
,
1801 GDestroyNotify destroy
)
1803 g_return_if_fail (G_IS_OBJECT (object
));
1804 g_return_if_fail (quark
> 0);
1806 g_datalist_id_set_data_full (&object
->qdata
, quark
, data
,
1807 data
? destroy
: (GDestroyNotify
) NULL
);
1811 g_object_steal_qdata (GObject
*object
,
1814 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1815 g_return_val_if_fail (quark
> 0, NULL
);
1817 return g_datalist_id_remove_no_notify (&object
->qdata
, quark
);
1821 g_object_get_data (GObject
*object
,
1826 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1827 g_return_val_if_fail (key
!= NULL
, NULL
);
1829 quark
= g_quark_try_string (key
);
1831 return quark
? g_datalist_id_get_data (&object
->qdata
, quark
) : NULL
;
1835 g_object_set_data (GObject
*object
,
1839 g_return_if_fail (G_IS_OBJECT (object
));
1840 g_return_if_fail (key
!= NULL
);
1842 g_datalist_id_set_data (&object
->qdata
, g_quark_from_string (key
), data
);
1846 g_object_set_data_full (GObject
*object
,
1849 GDestroyNotify destroy
)
1851 g_return_if_fail (G_IS_OBJECT (object
));
1852 g_return_if_fail (key
!= NULL
);
1854 g_datalist_id_set_data_full (&object
->qdata
, g_quark_from_string (key
), data
,
1855 data
? destroy
: (GDestroyNotify
) NULL
);
1859 g_object_steal_data (GObject
*object
,
1864 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1865 g_return_val_if_fail (key
!= NULL
, NULL
);
1867 quark
= g_quark_try_string (key
);
1869 return quark
? g_datalist_id_remove_no_notify (&object
->qdata
, quark
) : NULL
;
1873 g_value_object_init (GValue
*value
)
1875 value
->data
[0].v_pointer
= NULL
;
1879 g_value_object_free_value (GValue
*value
)
1881 if (value
->data
[0].v_pointer
)
1882 g_object_unref (value
->data
[0].v_pointer
);
1886 g_value_object_copy_value (const GValue
*src_value
,
1889 if (src_value
->data
[0].v_pointer
)
1890 dest_value
->data
[0].v_pointer
= g_object_ref (src_value
->data
[0].v_pointer
);
1892 dest_value
->data
[0].v_pointer
= NULL
;
1896 g_value_object_transform_value (const GValue
*src_value
,
1899 if (src_value
->data
[0].v_pointer
&& g_type_is_a (G_OBJECT_TYPE (src_value
->data
[0].v_pointer
), G_VALUE_TYPE (dest_value
)))
1900 dest_value
->data
[0].v_pointer
= g_object_ref (src_value
->data
[0].v_pointer
);
1902 dest_value
->data
[0].v_pointer
= NULL
;
1906 g_value_object_peek_pointer (const GValue
*value
)
1908 return value
->data
[0].v_pointer
;
1912 g_value_object_collect_value (GValue
*value
,
1913 guint n_collect_values
,
1914 GTypeCValue
*collect_values
,
1915 guint collect_flags
)
1917 if (collect_values
[0].v_pointer
)
1919 GObject
*object
= collect_values
[0].v_pointer
;
1921 if (object
->g_type_instance
.g_class
== NULL
)
1922 return g_strconcat ("invalid unclassed object pointer for value type `",
1923 G_VALUE_TYPE_NAME (value
),
1926 else if (!g_value_type_compatible (G_OBJECT_TYPE (object
), G_VALUE_TYPE (value
)))
1927 return g_strconcat ("invalid object type `",
1928 G_OBJECT_TYPE_NAME (object
),
1929 "' for value type `",
1930 G_VALUE_TYPE_NAME (value
),
1933 /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
1934 value
->data
[0].v_pointer
= g_object_ref (object
);
1937 value
->data
[0].v_pointer
= NULL
;
1943 g_value_object_lcopy_value (const GValue
*value
,
1944 guint n_collect_values
,
1945 GTypeCValue
*collect_values
,
1946 guint collect_flags
)
1948 GObject
**object_p
= collect_values
[0].v_pointer
;
1951 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value
));
1953 if (!value
->data
[0].v_pointer
)
1955 else if (collect_flags
& G_VALUE_NOCOPY_CONTENTS
)
1956 *object_p
= value
->data
[0].v_pointer
;
1958 *object_p
= g_object_ref (value
->data
[0].v_pointer
);
1964 g_value_set_object (GValue
*value
,
1969 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value
));
1971 old
= value
->data
[0].v_pointer
;
1975 g_return_if_fail (G_IS_OBJECT (v_object
));
1976 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object
), G_VALUE_TYPE (value
)));
1978 value
->data
[0].v_pointer
= v_object
;
1979 g_object_ref (value
->data
[0].v_pointer
);
1982 value
->data
[0].v_pointer
= NULL
;
1985 g_object_unref (old
);
1989 g_value_set_object_take_ownership (GValue
*value
,
1992 g_value_take_object (value
, v_object
);
1996 g_value_take_object (GValue
*value
,
1999 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value
));
2001 if (value
->data
[0].v_pointer
)
2003 g_object_unref (value
->data
[0].v_pointer
);
2004 value
->data
[0].v_pointer
= NULL
;
2009 g_return_if_fail (G_IS_OBJECT (v_object
));
2010 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object
), G_VALUE_TYPE (value
)));
2012 value
->data
[0].v_pointer
= v_object
; /* we take over the reference count */
2017 g_value_get_object (const GValue
*value
)
2019 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value
), NULL
);
2021 return value
->data
[0].v_pointer
;
2025 g_value_dup_object (const GValue
*value
)
2027 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value
), NULL
);
2029 return value
->data
[0].v_pointer
? g_object_ref (value
->data
[0].v_pointer
) : NULL
;
2033 g_signal_connect_object (gpointer instance
,
2034 const gchar
*detailed_signal
,
2035 GCallback c_handler
,
2037 GConnectFlags connect_flags
)
2039 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance
), 0);
2040 g_return_val_if_fail (detailed_signal
!= NULL
, 0);
2041 g_return_val_if_fail (c_handler
!= NULL
, 0);
2047 g_return_val_if_fail (G_IS_OBJECT (gobject
), 0);
2049 closure
= ((connect_flags
& G_CONNECT_SWAPPED
) ? g_cclosure_new_object_swap
: g_cclosure_new_object
) (c_handler
, gobject
);
2051 return g_signal_connect_closure (instance
, detailed_signal
, closure
, connect_flags
& G_CONNECT_AFTER
);
2054 return g_signal_connect_data (instance
, detailed_signal
, c_handler
, NULL
, NULL
, connect_flags
);
2060 GClosure
*closures
[1]; /* flexible array */
2062 /* don't change this structure without supplying an accessor for
2063 * watched closures, e.g.:
2064 * GSList* g_object_list_watched_closures (GObject *object)
2067 * g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2068 * carray = g_object_get_data (object, "GObject-closure-array");
2071 * GSList *slist = NULL;
2073 * for (i = 0; i < carray->n_closures; i++)
2074 * slist = g_slist_prepend (slist, carray->closures[i]);
2082 object_remove_closure (gpointer data
,
2085 GObject
*object
= data
;
2086 CArray
*carray
= g_object_get_qdata (object
, quark_closure_array
);
2089 for (i
= 0; i
< carray
->n_closures
; i
++)
2090 if (carray
->closures
[i
] == closure
)
2092 carray
->n_closures
--;
2093 if (i
< carray
->n_closures
)
2094 carray
->closures
[i
] = carray
->closures
[carray
->n_closures
];
2097 g_assert_not_reached ();
2101 destroy_closure_array (gpointer data
)
2103 CArray
*carray
= data
;
2104 GObject
*object
= carray
->object
;
2105 guint i
, n
= carray
->n_closures
;
2107 for (i
= 0; i
< n
; i
++)
2109 GClosure
*closure
= carray
->closures
[i
];
2111 /* removing object_remove_closure() upfront is probably faster than
2112 * letting it fiddle with quark_closure_array which is empty anyways
2114 g_closure_remove_invalidate_notifier (closure
, object
, object_remove_closure
);
2115 g_closure_invalidate (closure
);
2121 g_object_watch_closure (GObject
*object
,
2127 g_return_if_fail (G_IS_OBJECT (object
));
2128 g_return_if_fail (closure
!= NULL
);
2129 g_return_if_fail (closure
->is_invalid
== FALSE
);
2130 g_return_if_fail (closure
->in_marshal
== FALSE
);
2131 g_return_if_fail (object
->ref_count
> 0); /* this doesn't work on finalizing objects */
2133 g_closure_add_invalidate_notifier (closure
, object
, object_remove_closure
);
2134 g_closure_add_marshal_guards (closure
,
2135 object
, (GClosureNotify
) g_object_ref
,
2136 object
, (GClosureNotify
) g_object_unref
);
2137 carray
= g_datalist_id_remove_no_notify (&object
->qdata
, quark_closure_array
);
2140 carray
= g_renew (CArray
, NULL
, 1);
2141 carray
->object
= object
;
2142 carray
->n_closures
= 1;
2147 i
= carray
->n_closures
++;
2148 carray
= g_realloc (carray
, sizeof (*carray
) + sizeof (carray
->closures
[0]) * i
);
2150 carray
->closures
[i
] = closure
;
2151 g_datalist_id_set_data_full (&object
->qdata
, quark_closure_array
, carray
, destroy_closure_array
);
2155 g_closure_new_object (guint sizeof_closure
,
2160 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
2161 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
2163 closure
= g_closure_new_simple (sizeof_closure
, object
);
2164 g_object_watch_closure (object
, closure
);
2170 g_cclosure_new_object (GCallback callback_func
,
2175 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
2176 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
2177 g_return_val_if_fail (callback_func
!= NULL
, NULL
);
2179 closure
= g_cclosure_new (callback_func
, object
, NULL
);
2180 g_object_watch_closure (object
, closure
);
2186 g_cclosure_new_object_swap (GCallback callback_func
,
2191 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
2192 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
2193 g_return_val_if_fail (callback_func
!= NULL
, NULL
);
2195 closure
= g_cclosure_new_swap (callback_func
, object
, NULL
);
2196 g_object_watch_closure (object
, closure
);
2202 g_object_compat_control (gsize what
,
2208 case 1: /* floating base type */
2209 return G_TYPE_INITIALLY_UNOWNED
;
2210 case 2: /* FIXME: remove this once GLib/Gtk+ break ABI again */
2211 floating_flag_handler
= (guint(*)(GObject
*,gint
)) data
;
2213 case 3: /* FIXME: remove this once GLib/Gtk+ break ABI again */
2215 *pp
= floating_flag_handler
;
2222 G_DEFINE_TYPE (GInitiallyUnowned
, g_initially_unowned
, G_TYPE_OBJECT
);
2225 g_initially_unowned_init (GInitiallyUnowned
*object
)
2227 g_object_force_floating (object
);
2231 g_initially_unowned_class_init (GInitiallyUnownedClass
*klass
)
2235 #define __G_OBJECT_C__
2236 #include "gobjectaliasdef.c"