Mercurial > pidgin
diff src/dbus-server.c @ 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 | ebb02ea3c789 |
children | 744c0708d11f |
line wrap: on
line diff
--- 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 */ + + +