#include "gvaluetypes.h"
#include "gobjectnotifyqueue.c"
#include <string.h>
+#include <signal.h>
#define PREALLOC_CPARAMS (8)
/* --- signals --- */
enum {
- PROPERTIES_CHANGED,
NOTIFY,
LAST_SIGNAL
};
GObjectNotifyQueue *nqueue);
-/* --- structures --- */
-
-
/* --- variables --- */
static GQuark quark_closure_array = 0;
static GQuark quark_weak_refs = 0;
{
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);
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");
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,
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)
{
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)
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)
{
return object;
}
-gpointer
+GObject*
g_object_new_valist (GType object_type,
const gchar *first_property_name,
va_list var_args)
g_object_unref (object);
}
-gpointer
+void
g_object_set (gpointer _object,
const gchar *first_property_name,
...)
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
}
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));
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;
return object;
}
-gpointer
+void
g_object_disconnect (gpointer _object,
const gchar *signal_spec,
...)
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;
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;
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);
}
else
{
wstack = g_renew (WeakRefStack, NULL, 1);
+ wstack->object = object;
wstack->n_weak_refs = 1;
i = 0;
}
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)
{
}
}
+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)
{
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,
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,
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);
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);