changeset 11175:57af14280b5f

[gaim-migrate @ 13280] added DBus introspection support committer: Tailor Script <tailor@pidgin.im>
author Piotr Zielinski <zielaj>
date Sat, 30 Jul 2005 17:05:38 +0000
parents 9aae0a11de03
children 6932df31225f
files src/dbus-analyze-functions.py src/dbus-server.c
diffstat 2 files changed, 124 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/dbus-analyze-functions.py	Sat Jul 30 16:38:19 2005 +0000
+++ b/src/dbus-analyze-functions.py	Sat Jul 30 17:05:38 2005 +0000
@@ -53,6 +53,7 @@
 
 functions = []
 
+dparams = ""
 cparams = []
 cparamsout = []
 cdecls  = []
@@ -101,10 +102,11 @@
 
     print "return reply_DBUS;\n}\n"
 
-    functions.append(function)
+    functions.append((function, dparams))
 
 def c_clear():
-    global cparams, cdecls, ccode, cparamsout, ccodeout
+    global cparams, cdecls, ccode, cparamsout, ccodeout, dparams
+    dparams = ""
     cparams = []
     cdecls  = []
     ccode  = []
@@ -112,10 +114,21 @@
     ccodeout = []
 
 
+def addstring(*items):
+    global dparams
+    for item in items:
+        dparams += item + r"\0"
+
+def addintype(type, name):
+    addstring("in", type, name)
+
+def addouttype(type, name):
+    addstring("out", type, name)
+
 def printdispatchtable():
     print "static GaimDBusBinding bindings_DBUS[] = { "
-    for function in functions:
-        print '{"%s", %s_DBUS},' % (ctopascal(function), function)
+    for function, params in functions:
+        print '{"%s", "%s", %s_DBUS},' % (ctopascal(function), params, function)
     print "{NULL, NULL}"
     print "};"
     
@@ -135,6 +148,7 @@
            ((mytype[0] in simpletypes) or (mytype[0].startswith("Gaim"))):
         cdecls.append("dbus_int32_t %s;" % name)
         cparams.append(("INT32", name))
+        addintype("i", name)
         return
 
     # pointers ...
@@ -146,6 +160,7 @@
                 cdecls.append("const char *%s;" % name)
                 cparams.append(("STRING", name))
                 ccode  .append("NULLIFY(%s);" % name)
+                addintype("s", name)
                 return
             else:
                 raise myexception
@@ -157,6 +172,7 @@
             cparams.append(("INT32", name + "_ID"))
             ccode.append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s, error_DBUS);"  % \
                            (name, name, mytype[0]))
+            addintype("i", name)
             return
 
         # unknown pointers are always replaced with NULL
@@ -165,6 +181,7 @@
             cdecls .append("%s *%s;" % (mytype[0], name))
             cparams.append(("INT32", name + "_NULL"))
             ccode  .append("%s = NULL;" % name)
+            addintype("i", name)
             return
 
     raise myexception
@@ -184,6 +201,7 @@
         cdecls.append("const char *%s;" % name)
         ccode.append("%s = null_to_empty(%s);" % (name, call))
         cparamsout.append(("STRING", name))
+        addouttype("s", name)
         return
 
     # simple types (ints, booleans, enums, ...)
@@ -192,6 +210,7 @@
         cdecls.append("dbus_int32_t %s;" % name)
         ccode.append("%s = %s;" % (name, call))
         cparamsout.append(("INT32", name))
+        addouttype("i", name)
         return
             
     # pointers ...
@@ -202,6 +221,7 @@
             cdecls.append("dbus_int32_t %s;" % name)
             ccode .append("GAIM_DBUS_POINTER_TO_ID(%s, %s, error_DBUS);" % (name, call))
             cparamsout.append(("INT32", name))
+            addouttype("i", name)
             return
 
         # GList*, GSList*, assume that list is a list of objects
@@ -215,6 +235,7 @@
             cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
                               % (name, name))
             ccodeout.append("g_free(%s);" % name)
+            addouttype("ai", name)
             return
 
     raise myexception
--- a/src/dbus-server.c	Sat Jul 30 16:38:19 2005 +0000
+++ b/src/dbus-server.c	Sat Jul 30 17:05:38 2005 +0000
@@ -194,7 +194,6 @@
 	return array;
 }
 
-
 /**************************************************************/
 /* DBus bindings ...                                          */
 /**************************************************************/
@@ -224,15 +223,15 @@
 
     bindings = (GaimDBusBinding*) user_data;
 
-    if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
-	return FALSE;
-
-    if (!dbus_message_has_path(message, DBUS_PATH_GAIM))
+    if (!dbus_message_has_path(message, DBUS_PATH_GAIM)) 
 	return FALSE;
 
     name = dbus_message_get_member(message);
 
-    if (name == NULL)
+    if (name == NULL) 
+	return FALSE;
+
+    if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) 
 	return FALSE;
 
     for(i=0; bindings[i].name; i++)
@@ -260,6 +259,74 @@
     return FALSE;
 }
 
+
+/* Introspection */
+
+static const char *gettext(const char **ptr) {
+    const char *text = *ptr;
+    *ptr += strlen(text) + 1;
+    return text;
+}
+
+static void
+gaim_dbus_introspect_cb(GList **bindings_list, void *bindings) {
+    *bindings_list = g_list_prepend(*bindings_list, bindings);
+}
+
+static DBusMessage *gaim_dbus_introspect(DBusMessage *message) 
+{
+    DBusMessage *reply;
+    GString *str;
+    GList *bindings_list, *node;
+
+    str = g_string_sized_new(0x1000); /* fixme: why this size? */
+
+    g_string_append(str, "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n");
+    g_string_append_printf(str, "<node name='%s'>\n", DBUS_PATH_GAIM);
+    g_string_append_printf(str, "<interface name='%s'>\n", DBUS_INTERFACE_GAIM);
+
+    bindings_list = NULL;
+    gaim_signal_emit(gaim_dbus_get_handle(), "dbus-introspect", &bindings_list); 
+
+    for(node = bindings_list; node; node = node->next) {
+	GaimDBusBinding *bindings;
+	int i;
+
+	bindings = (GaimDBusBinding*) node->data;
+    
+	for(i=0; bindings[i].name; i++) {
+	    const char *text;
+
+	    g_string_append_printf(str, "<method name='%s'>\n", bindings[i].name);
+	
+	    text = bindings[i].parameters;
+	    while (*text) {		
+		const char *name, *direction, *type;
+		
+		direction = gettext(&text);
+		type = gettext(&text);
+		name = gettext(&text);
+		
+	    g_string_append_printf(str, 
+				   "<arg name='%s' type='%s' direction='%s'/>\n",
+				   name, type, direction);
+	    }
+	    g_string_append(str, "</method>\n");
+	}
+    }
+
+    g_string_append(str, "</interface>\n</node>\n");
+
+    reply = dbus_message_new_method_return (message);
+    dbus_message_append_args(reply,  DBUS_TYPE_STRING, &(str->str),  
+			     DBUS_TYPE_INVALID);
+    g_string_free(str, TRUE);	
+    g_list_free(bindings_list);
+
+    return reply;
+
+}
+
 static DBusHandlerResult gaim_dbus_dispatch(DBusConnection *connection,
 					    DBusMessage *message,
 					    void *user_data)
@@ -268,8 +335,20 @@
 				  "dbus-method-called", 
 				  connection, message))
 	return DBUS_HANDLER_RESULT_HANDLED;
-    else 
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
+	dbus_message_has_path(message, DBUS_PATH_GAIM) &&
+	dbus_message_has_interface(message, DBUS_INTERFACE_INTROSPECTABLE) &&
+	dbus_message_has_member(message, "Introspect"))
+    {
+	DBusMessage *reply;
+	reply = gaim_dbus_introspect(message);
+	dbus_connection_send (connection, reply, NULL);
+	dbus_message_unref(reply);
+	return DBUS_HANDLER_RESULT_HANDLED;
+    }
+	
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 void gaim_dbus_register_bindings(void *handle, GaimDBusBinding *bindings) {
@@ -277,6 +356,10 @@
 			handle, 
 			GAIM_CALLBACK(gaim_dbus_dispatch_cb),
 			bindings);
+    gaim_signal_connect(gaim_dbus_get_handle(), "dbus-introspect",
+			handle, 
+			GAIM_CALLBACK(gaim_dbus_introspect_cb),
+			bindings);
 }
 
 
@@ -326,6 +409,10 @@
 			 gaim_value_new(GAIM_TYPE_POINTER),
 			 gaim_value_new(GAIM_TYPE_POINTER));
 
+    gaim_signal_register(gaim_dbus_get_handle(), "dbus-introspect",
+			 gaim_marshal_VOID__POINTER, NULL, 1,
+			 gaim_value_new_outgoing(GAIM_TYPE_POINTER));
+
     GAIM_DBUS_REGISTER_BINDINGS(gaim_dbus_get_handle());
 
     return TRUE;
@@ -448,3 +535,7 @@
 }
 
 
+/* Introspection support */
+
+
+