changeset 27373:3a0552df3379

Add auto-generated D-Bus signals introspection, though parameter names are not included at the moment. Closes #3243.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 05 Jul 2009 05:41:00 +0000
parents c900484e41c0
children a6d84d9de605
files ChangeLog.API libpurple/Makefile.am libpurple/dbus-analyze-signals.py libpurple/dbus-server.c
diffstat 4 files changed, 91 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Sun Jul 05 03:32:34 2009 +0000
+++ b/ChangeLog.API	Sun Jul 05 05:41:00 2009 +0000
@@ -69,6 +69,7 @@
 		  emitted), but this signal was not emitted.
 		* Added a client_type field in the get_ui_info core UI op. See
 		  core.h for details.
+		* Added introspection of signals exposed via the D-Bus API.
 
 		Deprecated:
 		* buddy-added and buddy-removed blist signals
--- a/libpurple/Makefile.am	Sun Jul 05 03:32:34 2009 +0000
+++ b/libpurple/Makefile.am	Sun Jul 05 05:41:00 2009 +0000
@@ -1,5 +1,6 @@
 EXTRA_DIST = \
 		dbus-analyze-functions.py \
+		dbus-analyze-signals.py \
 		dbus-analyze-types.py \
 		marshallers.list \
 		purple-notifications-example \
@@ -169,6 +170,7 @@
 	dbus-bindings.c \
 	dbus-client-binding.c \
 	dbus-client-binding.h \
+	dbus-signals.c \
 	dbus-types.c \
 	dbus-types.h \
 	marshallers.c \
@@ -189,6 +191,10 @@
 purple_build_coreheaders = $(addprefix $(srcdir)/, $(purple_coreheaders)) \
 		$(purple_builtheaders)
 dbus_build_exported = $(addprefix $(srcdir)/, $(dbus_exported))
+# We should probably make this better
+dbus_signals = $(purple_coresources) \
+	protocols/irc/irc.c \
+	protocols/jabber/libxmpp.c
 
 dbus-types.c: dbus-analyze-types.py $(purple_build_coreheaders)
 	cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --pattern=PURPLE_DBUS_DEFINE_TYPE\(%s\) > $@
@@ -199,8 +205,11 @@
 dbus-bindings.c: dbus-analyze-functions.py $(dbus_exported)
 	cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py > $@
 
-dbus-server.$(OBJEXT): dbus-bindings.c dbus-types.c dbus-types.h
-dbus-server.lo: dbus-bindings.c dbus-types.c dbus-types.h
+dbus-signals.c: dbus-analyze-signals.py $(dbus_signals)
+	cat $(dbus_signals) | $(PYTHON) $(srcdir)/dbus-analyze-signals.py > $@
+
+dbus-server.$(OBJEXT): dbus-bindings.c dbus-signals.c dbus-types.c dbus-types.h
+dbus-server.lo: dbus-bindings.c dbus-signals.c dbus-types.c dbus-types.h
 $(libpurple_la_OBJECTS): dbus-types.h
 
 # libpurple-client
@@ -240,9 +249,10 @@
 bin_SCRIPTS = purple-remote purple-send purple-send-async purple-url-handler
 
 BUILT_SOURCES = $(purple_builtheaders) \
+	dbus-bindings.c \
+	dbus-signals.c \
 	dbus-types.c \
 	dbus-types.h \
-	dbus-bindings.c \
 	marshallers.c \
 	marshallers.h \
 	purple-client-bindings.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/dbus-analyze-signals.py	Sun Jul 05 05:41:00 2009 +0000
@@ -0,0 +1,60 @@
+# This program takes a C source as the input and produces the list of
+# all signals registered.
+#
+# Output is:
+#   <signal name="Changed">
+#       <arg name="new_value" type="b"/>
+#   </signal>
+
+import re
+import sys
+
+# List "excluded" contains signals that shouldn't be exported via
+# DBus.  If you remove a signal from this list, please make sure
+# that it does not break "make" with the configure option
+# "--enable-dbus" turned on.
+
+excluded = [\
+    # purple_dbus_signal_emit_purple prevents our "dbus-method-called"
+    # signal from being propagated to dbus.
+	"dbus-method-called",
+    ]
+
+registerregex = re.compile("purple_signal_register[^;]+\"([\w\-]+)\"[^;]+(purple_marshal_\w+)[^;]+;")
+nameregex = re.compile('[-_][a-z]')
+
+print "/* Generated by %s.  Do not edit! */" % sys.argv[0]
+print "const char *dbus_signals = "
+for match in registerregex.finditer(sys.stdin.read()):
+    signal = match.group(1)
+    marshal = match.group(2)
+    if signal in excluded:
+        continue
+
+    signal = nameregex.sub(lambda x:x.group()[1].upper(), '-'+signal)
+    print "\"<signal name='%s'>\\n\""%signal
+
+    args = marshal.split('_')
+    # ['purple', 'marshal', <return type>, '', args...]
+    if len(args) > 4:
+        for arg in args[4:]:
+            if arg == "POINTER":
+                type = 'p'
+            elif arg == "ENUM":
+                type = 'i'
+            elif arg == "INT":
+                type = 'i'
+            elif arg == "UINT":
+                type = 'u'
+            elif arg == "INT64":
+                type = 'x'
+            elif arg == "UINT64":
+                type = 't'
+            elif arg == "BOOLEAN":
+                type = 'b'
+            print "\"<arg type='%s'/>\\n\""%type
+
+    print "\"</signal>\\n\""
+
+print ";"
+
--- a/libpurple/dbus-server.c	Sun Jul 05 03:32:34 2009 +0000
+++ b/libpurple/dbus-server.c	Sun Jul 05 05:41:00 2009 +0000
@@ -421,6 +421,7 @@
 }
 
 #include "dbus-bindings.c"
+#include "dbus-signals.c"
 
 static gboolean
 purple_dbus_dispatch_cb(DBusConnection *connection,
@@ -489,6 +490,9 @@
 	DBusMessage *reply;
 	GString *str;
 	GList *bindings_list, *node;
+	const char *signals;
+	const char *type;
+	const char *pointer_type;
 
 	str = g_string_sized_new(0x1000); /* TODO: why this size? */
 
@@ -529,6 +533,19 @@
 		}
 	}
 
+	if (sizeof(int) == sizeof(dbus_int32_t))
+		pointer_type = "type='i'";
+	else
+		pointer_type = "type='x'";
+
+	signals = dbus_signals;
+	while ((type = strstr(signals, "type='p'")) != NULL) {
+		g_string_append_len(str, signals, type - signals);
+		g_string_append(str, pointer_type);
+		signals = type + sizeof("type='p'") - 1;
+	}
+	g_string_append(str, signals);
+
 	g_string_append(str, "</interface>\n</node>\n");
 
 	reply = dbus_message_new_method_return(message);