=== Released 2.2.0 ===
[platform/upstream/glib.git] / gobject / gobject.c
index 7e68087..308c440 100644 (file)
@@ -28,6 +28,7 @@
 #include       "gvaluetypes.h"
 #include       "gobjectnotifyqueue.c"
 #include       <string.h>
+#include       <signal.h>
 
 
 #define        PREALLOC_CPARAMS        (8)
@@ -40,7 +41,6 @@
 
 /* --- signals --- */
 enum {
-  PROPERTIES_CHANGED,
   NOTIFY,
   LAST_SIGNAL
 };
@@ -98,9 +98,6 @@ static inline void       object_set_property          (GObject        *object,
                                                         GObjectNotifyQueue *nqueue);
 
 
-/* --- structures --- */
-
-
 /* --- variables --- */
 static GQuark              quark_closure_array = 0;
 static GQuark              quark_weak_refs = 0;
@@ -207,8 +204,6 @@ g_object_base_class_finalize (GObjectClass *class)
 {
   GList *list, *node;
   
-  g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
-
   _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
 
   g_slist_free (class->construct_properties);
@@ -236,7 +231,9 @@ g_object_notify_dispatcher (GObject     *object,
 static void
 g_object_do_class_init (GObjectClass *class)
 {
+  /* read the comment about typedef struct CArray; on why not to change this quark */
   quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
+
   quark_weak_refs = g_quark_from_static_string ("GObject-weak-references");
   pspec_pool = g_param_spec_pool_new (TRUE);
   property_notify_context.quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
@@ -261,6 +258,14 @@ g_object_do_class_init (GObjectClass *class)
                  1, G_TYPE_PARAM);
 }
 
+/**
+ * g_object_class_install_property:
+ * @class: a #GObjectClass
+ * @property_id: the id for the new property
+ * @pspec: the #GParamSpec for the new property
+ * 
+ * Installs a new property. This is usually done in the class initializer.
+ **/
 void
 g_object_class_install_property (GObjectClass *class,
                                 guint         property_id,
@@ -470,6 +475,13 @@ g_object_run_dispose (GObject *object)
   g_object_unref (object);
 }
 
+/**
+ * g_object_freeze_notify:
+ * @object: a #GObject
+ * 
+ * Stops emission of "notify" signals on @object. The signals are
+ * queued until g_object_thaw_notify() is called on @object. 
+ **/
 void
 g_object_freeze_notify (GObject *object)
 {
@@ -482,6 +494,13 @@ g_object_freeze_notify (GObject *object)
   g_object_unref (object);
 }
 
+/**
+ * g_object_notify:
+ * @object: a #GObject
+ * @property_name: the name of a property installed on the class of @object.
+ * 
+ * Emits a "notify" signal for the property @property_name on @object. 
+ **/
 void
 g_object_notify (GObject     *object,
                 const gchar *property_name)
@@ -513,6 +532,14 @@ g_object_notify (GObject     *object,
   g_object_unref (object);
 }
 
+/**
+ * g_object_thaw_notify:
+ * @object: a #GObject
+ * 
+ * Reverts the effect of a previous call to g_object_freeze_notify().
+ * This causes all queued "notify" signals on @object to be emitted.
+
+ **/
 void
 g_object_thaw_notify (GObject *object)
 {
@@ -720,7 +747,7 @@ g_object_newv (GType       object_type,
   return object;
 }
 
-gpointer
+GObject*
 g_object_new_valist (GType       object_type,
                     const gchar *first_property_name,
                     va_list      var_args)
@@ -949,7 +976,7 @@ g_object_get_valist (GObject         *object,
   g_object_unref (object);
 }
 
-gpointer
+void
 g_object_set (gpointer     _object,
              const gchar *first_property_name,
              ...)
@@ -957,13 +984,11 @@ g_object_set (gpointer     _object,
   GObject *object = _object;
   va_list var_args;
   
-  g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+  g_return_if_fail (G_IS_OBJECT (object));
   
   va_start (var_args, first_property_name);
   g_object_set_valist (object, first_property_name, var_args);
   va_end (var_args);
-
-  return object;
 }
 
 void
@@ -1047,7 +1072,7 @@ g_object_get_property (GObject       *object,
        }
       else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
        {
-         g_warning ("can't retrive property `%s' of type `%s' as value of type `%s'",
+         g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
                     pspec->name,
                     g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
                     G_VALUE_TYPE_NAME (value));
@@ -1084,7 +1109,7 @@ g_object_connect (gpointer     _object,
   va_start (var_args, signal_spec);
   while (signal_spec)
     {
-      gpointer callback = va_arg (var_args, gpointer);
+      GCallback callback = va_arg (var_args, GCallback);
       gpointer data = va_arg (var_args, gpointer);
       gulong sid;
 
@@ -1132,7 +1157,7 @@ g_object_connect (gpointer     _object,
   return object;
 }
 
-gpointer
+void
 g_object_disconnect (gpointer     _object,
                     const gchar *signal_spec,
                     ...)
@@ -1140,13 +1165,13 @@ g_object_disconnect (gpointer     _object,
   GObject *object = _object;
   va_list var_args;
 
-  g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, object);
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (object->ref_count > 0);
 
   va_start (var_args, signal_spec);
   while (signal_spec)
     {
-      gpointer callback = va_arg (var_args, gpointer);
+      GCallback callback = va_arg (var_args, GCallback);
       gpointer data = va_arg (var_args, gpointer);
       guint sid = 0, detail = 0, mask = 0;
 
@@ -1171,16 +1196,15 @@ g_object_disconnect (gpointer     _object,
        g_warning ("%s: invalid signal name \"%s\"", G_STRLOC, signal_spec);
       else if (!g_signal_handlers_disconnect_matched (object, mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0),
                                                      sid, detail,
-                                                     NULL, callback, data))
+                                                     NULL, (gpointer)callback, data))
        g_warning (G_STRLOC ": signal handler %p(%p) is not connected", callback, data);
       signal_spec = va_arg (var_args, gchar*);
     }
   va_end (var_args);
-
-  return object;
 }
 
 typedef struct {
+  GObject *object;
   guint n_weak_refs;
   struct {
     GWeakNotify notify;
@@ -1195,7 +1219,7 @@ weak_refs_notify (gpointer data)
   guint i;
 
   for (i = 0; i < wstack->n_weak_refs; i++)
-    wstack->weak_refs[i].notify (wstack->weak_refs[i].data);
+    wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
   g_free (wstack);
 }
 
@@ -1220,6 +1244,7 @@ g_object_weak_ref (GObject    *object,
   else
     {
       wstack = g_renew (WeakRefStack, NULL, 1);
+      wstack->object = object;
       wstack->n_weak_refs = 1;
       i = 0;
     }
@@ -1262,6 +1287,30 @@ g_object_weak_unref (GObject    *object,
     g_warning (G_STRLOC ": couldn't find weak ref %p(%p)", notify, data);
 }
 
+void
+g_object_add_weak_pointer (GObject  *object, 
+                           gpointer *weak_pointer_location)
+{
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (weak_pointer_location != NULL);
+
+  g_object_weak_ref (object, 
+                     (GWeakNotify) g_nullify_pointer, 
+                     weak_pointer_location);
+}
+
+void
+g_object_remove_weak_pointer (GObject  *object, 
+                              gpointer *weak_pointer_location)
+{
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (weak_pointer_location != NULL);
+
+  g_object_weak_unref (object, 
+                       (GWeakNotify) g_nullify_pointer, 
+                       weak_pointer_location);
+}
+
 gpointer
 g_object_ref (gpointer _object)
 {
@@ -1507,6 +1556,27 @@ g_value_set_object (GValue   *value,
     }
 }
 
+void
+g_value_set_object_take_ownership (GValue  *value,
+                                  gpointer v_object)
+{
+  g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
+
+  if (value->data[0].v_pointer)
+    {
+      g_object_unref (value->data[0].v_pointer);
+      value->data[0].v_pointer = NULL;
+    }
+
+  if (v_object)
+    {
+      g_return_if_fail (G_IS_OBJECT (v_object));
+      g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
+
+      value->data[0].v_pointer = v_object; /* we take over the reference count */
+    }
+}
+
 gpointer
 g_value_get_object (const GValue *value)
 {
@@ -1523,7 +1593,20 @@ g_value_dup_object (const GValue *value)
   return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
 }
 
-guint
+/**
+ * g_signal_connect_object:
+ * @instance: the instance to connect to.
+ * @detailed_signal: a string of the form "signal-name::detail".
+ * @c_handler: the #GCallback to connect.
+ * @gobject: the object to pass as data to @c_handler.
+ * @connect_flags: a combination of #GConnnectFlags.
+ * 
+ * This is similar to g_signal_connect_data(), but uses a closure which
+ * ensures that the object stays alive during the call to @c_handler.
+ * 
+ * Return value: the handler id.
+ **/
+gulong
 g_signal_connect_object (gpointer      instance,
                         const gchar  *detailed_signal,
                         GCallback     c_handler,
@@ -1553,6 +1636,24 @@ typedef struct {
   guint     n_closures;
   GClosure *closures[1]; /* flexible array */
 } CArray;
+/* don't change this structure without supplying an accessor for
+ * watched closures, e.g.:
+ * GSList* g_object_list_watched_closures (GObject *object)
+ * {
+ *   CArray *carray;
+ *   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+ *   carray = g_object_get_data (object, "GObject-closure-array");
+ *   if (carray)
+ *     {
+ *       GSList *slist = NULL;
+ *       guint i;
+ *       for (i = 0; i < carray->n_closures; i++)
+ *         slist = g_slist_prepend (slist, carray->closures[i]);
+ *       return slist;
+ *     }
+ *   return NULL;
+ * }
+ */
 
 static void
 object_remove_closure (gpointer  data,
@@ -1644,9 +1745,8 @@ g_closure_new_object (guint    sizeof_closure,
 
 GClosure*
 g_cclosure_new_object (GCallback callback_func,
-                      gpointer  _object)
+                      GObject  *object)
 {
-  GObject *object = _object;
   GClosure *closure;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
@@ -1661,9 +1761,8 @@ g_cclosure_new_object (GCallback callback_func,
 
 GClosure*
 g_cclosure_new_object_swap (GCallback callback_func,
-                           gpointer  _object)
+                           GObject  *object)
 {
-  GObject *object = _object;
   GClosure *closure;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);