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