# HG changeset patch # User Piotr Zielinski # Date 1122743138 0 # Node ID 57af14280b5fc27242f4d202c2a866745c3fdf7f # Parent 9aae0a11de03ed7aee5c902bf6eaa7663b01b65f [gaim-migrate @ 13280] added DBus introspection support committer: Tailor Script diff -r 9aae0a11de03 -r 57af14280b5f src/dbus-analyze-functions.py --- 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 diff -r 9aae0a11de03 -r 57af14280b5f src/dbus-server.c --- 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, "\n"); + g_string_append_printf(str, "\n", DBUS_PATH_GAIM); + g_string_append_printf(str, "\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, "\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, + "\n", + name, type, direction); + } + g_string_append(str, "\n"); + } + } + + g_string_append(str, "\n\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 */ + + +