From 680a2c82ed2be1c4e9bc90d6367ebab60c12c26e Mon Sep 17 00:00:00 2001 From: barbieri Date: Mon, 6 Apr 2009 20:55:05 +0000 Subject: [PATCH] This patch adds signals to introspect following the dbus specification: http://standards.freedesktop.org/dbus/1.0/introspect.dtd http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-introspectable By: Bruno Dilly git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/e_dbus@39884 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/dbus/E_DBus.h | 2 + src/lib/dbus/e_dbus_object.c | 112 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/src/lib/dbus/E_DBus.h b/src/lib/dbus/E_DBus.h index a134693..da8c22c 100644 --- a/src/lib/dbus/E_DBus.h +++ b/src/lib/dbus/E_DBus.h @@ -81,6 +81,8 @@ extern "C" { EAPI void e_dbus_object_interface_detach(E_DBus_Object *obj, E_DBus_Interface *iface); EAPI int e_dbus_interface_method_add(E_DBus_Interface *iface, const char *member, const char *signature, const char *reply_signature, E_DBus_Method_Cb func); + EAPI int e_dbus_interface_signal_add(E_DBus_Interface *iface, const char *name, const char *signature); + EAPI E_DBus_Object *e_dbus_object_add(E_DBus_Connection *conn, const char *object_path, void *data); EAPI void e_dbus_object_free(E_DBus_Object *obj); EAPI void *e_dbus_object_data_get(E_DBus_Object *obj); diff --git a/src/lib/dbus/e_dbus_object.c b/src/lib/dbus/e_dbus_object.c index 8119a41..1b649f5 100644 --- a/src/lib/dbus/e_dbus_object.c +++ b/src/lib/dbus/e_dbus_object.c @@ -9,6 +9,7 @@ static E_DBus_Interface *introspectable_interface = NULL; static E_DBus_Interface *properties_interface = NULL; typedef struct E_DBus_Method E_DBus_Method; +typedef struct E_DBus_Signal E_DBus_Signal; Ecore_Strbuf * e_dbus_object_introspect(E_DBus_Object *obj); @@ -20,9 +21,13 @@ static void e_dbus_interface_free(E_DBus_Interface *iface); static E_DBus_Method *e_dbus_method_new(const char *member, const char *signature, const char *reply_signature, E_DBus_Method_Cb func); static void e_dbus_object_method_free(E_DBus_Method *m); +static E_DBus_Signal *e_dbus_signal_new(const char *name, const char *signature); +static void e_dbus_object_signal_free(E_DBus_Signal *s); + static void _introspect_indent_append(Ecore_Strbuf *buf, int level); static void _introspect_interface_append(Ecore_Strbuf *buf, E_DBus_Interface *iface, int level); static void _introspect_method_append(Ecore_Strbuf *buf, E_DBus_Method *method, int level); +static void _introspect_signal_append(Ecore_Strbuf *buf, E_DBus_Signal *signal, int level); static void _introspect_arg_append(Ecore_Strbuf *buf, const char *type, const char *direction, int level); @@ -56,6 +61,7 @@ struct E_DBus_Interface { char *name; Eina_List *methods; + Eina_List *signals; int refcount; }; @@ -67,6 +73,12 @@ struct E_DBus_Method E_DBus_Method_Cb func; }; +struct E_DBus_Signal +{ + char *name; + char *signature; +}; + static DBusMessage * cb_introspect(E_DBus_Object *obj, DBusMessage *msg) { @@ -328,6 +340,7 @@ static void e_dbus_interface_free(E_DBus_Interface *iface) { E_DBus_Method *m; + E_DBus_Signal *s; if (iface->name) free(iface->name); while (iface->methods) @@ -336,6 +349,12 @@ e_dbus_interface_free(E_DBus_Interface *iface) e_dbus_object_method_free(m); iface->methods = eina_list_remove_list(iface->methods, iface->methods); } + while (iface->signals) + { + s = eina_list_data_get(iface->signals); + e_dbus_object_signal_free(s); + iface->signals = eina_list_remove_list(iface->signals, iface->signals); + } free(iface); } @@ -365,6 +384,28 @@ e_dbus_interface_method_add(E_DBus_Interface *iface, const char *member, const c return 1; } +/** + * Add a signal to an object + * + * @param iface the E_DBus_Interface to which this signal belongs + * @param name the name of the signal + * @param signature an optional message signature. + * + * @return 1 if successful, 0 if failed (e.g. no memory) + */ +EAPI int +e_dbus_interface_signal_add(E_DBus_Interface *iface, const char *name, const char *signature) +{ + E_DBus_Signal *s; + + s = e_dbus_signal_new(name, signature); + DEBUG(4, "Add signal %s: %p\n", name, s); + if (!s) return 0; + + iface->signals = eina_list_append(iface->signals, s); + return 1; +} + EAPI E_DBus_Interface * e_dbus_interface_new(const char *interface) { @@ -378,6 +419,7 @@ e_dbus_interface_new(const char *interface) iface->refcount = 1; iface->name = strdup(interface); iface->methods = NULL; + iface->signals = NULL; return iface; } @@ -415,6 +457,33 @@ e_dbus_object_method_free(E_DBus_Method *m) free(m); } +static E_DBus_Signal * +e_dbus_signal_new(const char *name, const char *signature) +{ + E_DBus_Signal *s; + + if (!name) return NULL; + + if (signature && !dbus_signature_validate(signature, NULL)) return NULL; + s = calloc(1, sizeof(E_DBus_Signal)); + if (!s) return NULL; + + s->name = strdup(name); + if (signature) + s->signature = strdup(signature); + + return s; +} + +static void +e_dbus_object_signal_free(E_DBus_Signal *s) +{ + if (!s) return; + if (s->name) free(s->name); + if (s->signature) free(s->signature); + free(s); +} + static E_DBus_Method * e_dbus_object_method_find(E_DBus_Object *obj, const char *interface, const char *member) { @@ -508,6 +577,7 @@ static void _introspect_interface_append(Ecore_Strbuf *buf, E_DBus_Interface *iface, int level) { E_DBus_Method *method; + E_DBus_Signal *signal; Eina_List *l; _introspect_indent_append(buf, level); @@ -519,6 +589,8 @@ _introspect_interface_append(Ecore_Strbuf *buf, E_DBus_Interface *iface, int lev DEBUG(4, "introspect iface: %s\n", iface->name); EINA_LIST_FOREACH(iface->methods, l, method) _introspect_method_append(buf, method, level); + EINA_LIST_FOREACH(iface->signals, l, signal) + _introspect_signal_append(buf, signal, level); level--; _introspect_indent_append(buf, level); @@ -573,13 +645,49 @@ _introspect_method_append(Ecore_Strbuf *buf, E_DBus_Method *method, int level) } static void +_introspect_signal_append(Ecore_Strbuf *buf, E_DBus_Signal *signal, int level) +{ + DBusSignatureIter iter; + char *type; + + _introspect_indent_append(buf, level); + DEBUG(4, "introspect signal: %s\n", signal->name); + ecore_strbuf_append(buf, "name); + ecore_strbuf_append(buf, "\">\n"); + level++; + + /* append args */ + if (signal->signature && + signal->signature[0] && + dbus_signature_validate(signal->signature, NULL)) + { + dbus_signature_iter_init(&iter, signal->signature); + while ((type = dbus_signature_iter_get_signature(&iter))) + { + _introspect_arg_append(buf, type, NULL, level); + + dbus_free(type); + if (!dbus_signature_iter_next(&iter)) break; + } + } + + level--; + _introspect_indent_append(buf, level); + ecore_strbuf_append(buf, "\n"); +} + +static void _introspect_arg_append(Ecore_Strbuf *buf, const char *type, const char *direction, int level) { _introspect_indent_append(buf, level); ecore_strbuf_append(buf, "\n"); } -- 2.7.4