GObject signals

Sadrul Habib Chowdhury imadil at gmail.com
Wed Jun 25 20:11:27 EDT 2008


* Gary Kramlich had this to say on [24 Jun 2008, 17:24:11 -0500]:
[snip]
> 
> g_signal_add_emission_hook
> 

That's terrific! Thanks!

(I missed the previous discussion(s) on this, and I can't find it in
 the archives either. So I am going to bother everyone some more!)

To keep things plain and simple, we can have g_signal_connect_type,
which will have a very similar signature as g_signal_connect, the only
difference being the first parameter, which will be a GType, instead of
a GObject *. To elaborate:

	g_signal_connect_type(PURPLE_TYPE_ACCOUNT, "enabled",
		G_CALLBACK(account_enabled_cb), gtkblist);

will replace

	purple_signal_connect(handle, "account-enabled", gtkblist,
		PURPLE_CALLBACK(account_enabled_cb), gtkblist);

I tested the attached patch, which seems to work OK. Anyone has any
comments/suggestions? Is there an even simpler way of doing it? (perhaps
a g_signal_sadrul_cant_find_things ;) )

Sadrul

-------------- next part --------------
#
# old_revision [54a3f6c27532f476dfd8b1725f7166ba84ff2fce]
#
# patch "libpurple/pobject.c"
#  from [b59936961f6309c69a306a519247081b0f4f1977]
#    to [8533e75385455c99b1655104fa7f0b2b238423b6]
# 
# patch "libpurple/pobject.h"
#  from [18fe9cec069e515633b56a33dea53ecdc2b83f88]
#    to [ca9f1fa4849a62bfcfe03c07d057572389a876c3]
#
============================================================
--- libpurple/pobject.c	b59936961f6309c69a306a519247081b0f4f1977
+++ libpurple/pobject.c	8533e75385455c99b1655104fa7f0b2b238423b6
@@ -122,3 +122,57 @@ int purple_object_get_int(PurpleObject *
 	return ret;
 }
 
+/**
+ * Signal emission hooks utility function
+ */
+typedef struct
+{
+	GCallback callback;
+	gpointer user_data;
+	GConnectFlags flags;
+} PObjectConnectHook;
+
+static gboolean
+signal_emission_hook_fn(GSignalInvocationHint *hint, guint nparams,
+		const GValue *pvalues, gpointer data)
+{
+	PObjectConnectHook *hook = data;
+	PurpleObject *obj = PURPLE_OBJECT(g_value_get_object(pvalues + 0));
+	if (g_signal_handler_find(obj,
+				G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+				hint->signal_id, 0, NULL,
+				hook->callback, hook->user_data) == 0) {
+		gboolean swap = (hook->flags & G_CONNECT_SWAPPED);
+		gboolean after = (hook->flags & G_CONNECT_AFTER);
+
+		GClosure *closure = (swap ? g_cclosure_new_swap : g_cclosure_new)
+					(hook->callback, hook->user_data, NULL);
+		g_signal_connect_closure_by_id(obj, hint->signal_id, 0, closure, after);
+		g_closure_invoke(closure, NULL, nparams, pvalues, hint);
+	}
+	return TRUE;
+}
+
+gulong
+g_signal_connect_type(GType type, const char *signal, GCallback callback,
+		gpointer data)
+{
+	return g_signal_connect_type_flags(type, signal, callback, data, 0);
+}
+
+gulong
+g_signal_connect_type_flags(GType type, const char *signal, GCallback callback,
+		gpointer data, GConnectFlags flags)
+{
+	PObjectConnectHook *hook;
+	guint signal_id = g_signal_lookup(signal, type);
+
+	hook = g_new0(PObjectConnectHook, 1);
+	hook->callback = callback;
+	hook->user_data = data;
+	hook->flags = flags;
+
+	return g_signal_add_emission_hook(signal_id, 0,
+			signal_emission_hook_fn, hook, g_free);
+}
+
============================================================
--- libpurple/pobject.h	18fe9cec069e515633b56a33dea53ecdc2b83f88
+++ libpurple/pobject.h	ca9f1fa4849a62bfcfe03c07d057572389a876c3
@@ -63,6 +63,12 @@ int purple_object_get_int(PurpleObject *
 
 int purple_object_get_int(PurpleObject *pobj, const char *prop);
 
+gulong g_signal_connect_type(GType type, const char *signal, GCallback callback,
+		gpointer data);
+
+gulong g_signal_connect_type_flags(GType type, const char *signal, GCallback callback,
+		gpointer data, GConnectFlags flags);
+
 G_END_DECLS
 
 #endif /* PURPLE_OBJECT_H */


More information about the Devel mailing list