Mercurial > pidgin
changeset 11067:2eca9ed49469
[gaim-migrate @ 13048]
Modified configure.ac so that it rejects dbus builds with the dbus
library older than 0.34
Added a simple object registration system to the dbus implementation
so that it is possible to query object properties remotely (eg. give
me property "name" of buddy with id = 5).
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Thu, 07 Jul 2005 15:43:48 +0000 |
parents | 2507d20c3d0b |
children | 9bd0aac996f4 |
files | COPYRIGHT README.dbus configure.ac src/Makefile.am src/account.c src/blist.c src/dbus-client.c src/dbus-maybe.h src/dbus-server.c src/dbus-server.h src/dbus-service.xml src/gaim-send src/gtkmain.c |
diffstat | 13 files changed, 558 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Thu Jul 07 15:43:05 2005 +0000 +++ b/COPYRIGHT Thu Jul 07 15:43:48 2005 +0000 @@ -230,4 +230,5 @@ Timmy Yee Nickolai Zeldovich Marco Ziech +Piotr Zielinski Jaroen Zwartepoorte
--- a/README.dbus Thu Jul 07 15:43:05 2005 +0000 +++ b/README.dbus Thu Jul 07 15:43:48 2005 +0000 @@ -34,7 +34,7 @@ executable. -4. Start DBUS if you haven't done it already +4. Start Session DBUS if you haven't done it already eval `dbus-launch --session` export DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID @@ -42,12 +42,7 @@ These commands will set the two above shell variables. These variables must be set before running any dbus-aware programs. - -Now you can start gaim as usual. A new program, gaim-client can be -used to issue commands to a running gaim process +Start gaim as usual. To communicate with it, use "gaim-send". When +you execute gaim-send, the dbus system will automatically start a gaim +process if one is not running already. - gaim-client command1 command2 ... - -At the moment there are only three commands: ping, quit, and connect. -When you execute gaim-client, the dbus system will automatically start -a gaim process if one is not running already.
--- a/configure.ac Thu Jul 07 15:43:05 2005 +0000 +++ b/configure.ac Thu Jul 07 15:43:48 2005 +0000 @@ -318,14 +318,19 @@ if test "x$enable_dbus" = "xyes"; then PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.34 dbus-glib-1 >= 0.34], [ - AC_DEFINE(HAVE_DBUS, 1, [Define if we're using DBUS.]) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) - echo "Building with DBUS support" + ], + [ + enable_dbus=no ]) +fi + +if test "x$enable_dbus" = "xyes"; then + AC_DEFINE(HAVE_DBUS, 1, [Define if we're using DBUS.]) + echo "Building with DBUS support" else echo "Building without DBUS support" - enable_dbus=no fi AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes")
--- a/src/Makefile.am Thu Jul 07 15:43:05 2005 +0000 +++ b/src/Makefile.am Thu Jul 07 15:43:48 2005 +0000 @@ -148,7 +148,9 @@ gaim_coresources += dbus-server.c gaim_coreheaders += dbus-server.h -bin_PROGRAMS += gaim-client + +# do not use gaim-client, use gaim-send instead +# bin_PROGRAMS += gaim-client dbus-client-bindings.c: dbus-service.xml dbus-binding-tool --prefix=gaim_object --mode=glib-client --output=$@ $<
--- a/src/account.c Thu Jul 07 15:43:05 2005 +0000 +++ b/src/account.c Thu Jul 07 15:43:48 2005 +0000 @@ -25,6 +25,7 @@ #include "internal.h" #include "account.h" #include "core.h" +#include "dbus-maybe.h" #include "debug.h" #include "notify.h" #include "pounce.h" @@ -701,6 +702,7 @@ gaim_presence_set_status_active(account->presence, "offline", TRUE); + GAIM_DBUS_REGISTER_POINTER(account, DBUS_POINTER_ACCOUNT); return account; } @@ -742,6 +744,7 @@ if(account->system_log) gaim_log_free(account->system_log); + GAIM_DBUS_UNREGISTER_POINTER(account); g_free(account); }
--- a/src/blist.c Thu Jul 07 15:43:05 2005 +0000 +++ b/src/blist.c Thu Jul 07 15:43:48 2005 +0000 @@ -23,6 +23,7 @@ #include "internal.h" #include "blist.h" #include "conversation.h" +#include "dbus-maybe.h" #include "debug.h" #include "notify.h" #include "prefs.h" @@ -1053,6 +1054,7 @@ if (ops != NULL && ops->new_node != NULL) ops->new_node((GaimBlistNode *)chat); + GAIM_DBUS_REGISTER_POINTER(chat, DBUS_POINTER_CHAT); return chat; } @@ -1078,6 +1080,7 @@ if (ops && ops->new_node) ops->new_node((GaimBlistNode *)buddy); + GAIM_DBUS_REGISTER_POINTER(buddy, DBUS_POINTER_BUDDY); return buddy; } @@ -1346,6 +1349,7 @@ if (ops && ops->new_node) ops->new_node((GaimBlistNode *)contact); + GAIM_DBUS_REGISTER_POINTER(contact, DBUS_POINTER_CONTACT); return contact; } @@ -1425,6 +1429,7 @@ if (ops && ops->new_node) ops->new_node((GaimBlistNode *)group); + GAIM_DBUS_REGISTER_POINTER(group, DBUS_POINTER_GROUP); return group; } @@ -1681,6 +1686,7 @@ /* Delete the node */ g_hash_table_destroy(contact->node.settings); + GAIM_DBUS_UNREGISTER_POINTER(contact); g_free(contact); } } @@ -1753,6 +1759,8 @@ g_free(buddy->name); g_free(buddy->alias); g_free(buddy->server_alias); + + GAIM_DBUS_UNREGISTER_POINTER(buddy); g_free(buddy); /* If the contact is empty then remove it */ @@ -1797,6 +1805,7 @@ g_hash_table_destroy(chat->components); g_hash_table_destroy(chat->node.settings); g_free(chat->alias); + GAIM_DBUS_UNREGISTER_POINTER(chat); g_free(chat); } @@ -1859,6 +1868,7 @@ /* Delete the node */ g_hash_table_destroy(group->node.settings); g_free(group->name); + GAIM_DBUS_UNREGISTER_POINTER(group); g_free(group); }
--- a/src/dbus-client.c Thu Jul 07 15:43:05 2005 +0000 +++ b/src/dbus-client.c Thu Jul 07 15:43:48 2005 +0000 @@ -21,6 +21,8 @@ * */ +/* Do not use this program. Use gaim-send instead. */ + #define DBUS_API_SUBJECT_TO_CHANGE #include <string.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dbus-maybe.h Thu Jul 07 15:43:48 2005 +0000 @@ -0,0 +1,23 @@ +/* This file contains macros that wrap calls to the gaim dbus module. + These macros call the appropriate functions if the build includes + dbus support and do nothing otherwise. See "dbus-server.h" for + documentation. */ + +#ifndef _GAIM_DBUS_MAYBE_H_ +#define _GAIM_DBUS_MAYBE_H_ + +#ifdef HAVE_DBUS + +#include "dbus-server.h" + +#define GAIM_DBUS_REGISTER_POINTER(ptr, type) gaim_dbus_register_pointer(ptr, type) +#define GAIM_DBUS_UNREGISTER_POINTER(ptr) gaim_dbus_unregister_pointer(ptr) + +#else /* !HAVE_DBUS */ + +#define GAIM_DBUS_REGISTER_POINTER(ptr, type) +#define GAIM_DBUS_UNREGISTER_POINTER(ptr) + +#endif /* HAVE_DBUS */ + +#endif
--- a/src/dbus-server.c Thu Jul 07 15:43:05 2005 +0000 +++ b/src/dbus-server.c Thu Jul 07 15:43:48 2005 +0000 @@ -31,12 +31,17 @@ #include <glib/gquark.h> #include "account.h" +#include "blist.h" +#include "conversation.h" #include "dbus-gaim.h" #include "dbus-server.h" #include "debug.h" #include "core.h" +#include "value.h" -/* GaimObject, basic definitions*/ +/**************************************************************************/ +/** @name Lots of GObject crap I don't understand */ +/**************************************************************************/ typedef struct GaimObject GaimObject; typedef struct GaimObjectClass GaimObjectClass; @@ -72,10 +77,79 @@ } static GObject *gaim_object; +static GQuark gaim_object_error_quark; + -/* Implementations of remote DBUS calls */ +/**************************************************************************/ +/** @name Utility functions */ +/**************************************************************************/ + +#define error_unless_1(condition, str, parameter) \ + if (!(condition)) { \ + g_set_error(error, gaim_object_error_quark, \ + DBUS_ERROR_NOT_FOUND, \ + str, parameter); \ + return FALSE; \ + } + +#define error_unless_2(condition, str, a,b) \ + if (!(condition)) { \ + g_set_error(error, gaim_object_error_quark, \ + DBUS_ERROR_NOT_FOUND, \ + str, a,b); \ + return FALSE; \ + } + +static const char* null_to_empty(const char *s) { + if (s) + return s; + else + return ""; +} + +typedef gboolean (*GaimNodeFilter)(GaimBlistNode *node, gpointer *user_data); + +static gboolean +filter_is_buddy(GaimBlistNode *node, gpointer *user_data) +{ + return GAIM_BLIST_NODE_IS_BUDDY(node); +} +static gboolean +filter_is_online_buddy(GaimBlistNode *node, + gpointer *user_data) +{ + return GAIM_BLIST_NODE_IS_BUDDY(node) && + GAIM_BUDDY_IS_ONLINE((GaimBuddy *)node); +} + + +static GList* +get_buddy_list (GList *created_list, /**< can be NULL */ + GaimBlistNode *gaim_buddy_list, /**< can be NULL */ + GaimNodeFilter filter, + gpointer user_data) +{ + GaimBlistNode *node; + + for(node = gaim_buddy_list; node; node = node->next) + { + if ((*filter)(node, user_data)) + created_list = g_list_prepend(created_list, node); + + created_list = get_buddy_list(created_list, node->child, + filter, user_data); + } + + return created_list; +} + + + +/**************************************************************************/ +/** @name Implementations of remote DBUS calls */ +/**************************************************************************/ static gboolean gaim_object_ping(GaimObject *obj, GError **error) @@ -101,19 +175,269 @@ return TRUE; } + + +static gboolean +gaim_object_get_buddy_list (GaimObject *obj, GArray **out_buddy_ids, + GError **error) +{ + GList *node; + GList *buddy_list = get_buddy_list(NULL, gaim_get_blist()->root, + &filter_is_buddy, NULL); + GArray *buddy_ids = g_array_new(FALSE, TRUE, sizeof(gint32));; + + buddy_list = g_list_reverse(buddy_list); + + for (node = buddy_list; node; node = node->next) { + gint32 id = gaim_dbus_pointer_to_id(node->data); + g_array_append_val(buddy_ids, id); + } + + g_list_free(buddy_list); + *out_buddy_ids = buddy_ids; + + return TRUE; +} + + + + + +static gboolean +gaim_object_find_account(GaimObject *unused, + const char *account_name, const char *protocol_name, + gint *account_id, GError **error) +{ + GaimAccount *account = gaim_accounts_find(account_name, protocol_name); + + error_unless_2(account, "Account '%s' with protocol '%s' not found", + account_name, protocol_name); + + *account_id = gaim_dbus_pointer_to_id(account); + return TRUE; +} + +static gboolean +gaim_object_find_buddy(GaimObject *unused, gint account_id, const char *buddy_name, + gint *buddy_id, GError **error) +{ + GaimAccount *account; + GaimBuddy *buddy; + + account = gaim_dbus_id_to_pointer(account_id, DBUS_POINTER_ACCOUNT); + error_unless_1(account, "Invalid account id: %i", account_id); + + buddy = gaim_find_buddy(account, buddy_name); + error_unless_1(account, "Buddy '%s' not found.", buddy_name); + + *buddy_id = gaim_dbus_pointer_to_id(buddy); + return TRUE; +} + +static gboolean +gaim_object_start_im_conversation (GaimObject *obj, gint buddy_id, GError **error) +{ + GaimBuddy *buddy = (GaimBuddy*) gaim_dbus_id_to_pointer(buddy_id, + DBUS_POINTER_BUDDY); + + error_unless_1(buddy, "Invalid buddy id: %i", buddy_id); + + gaim_conversation_new(GAIM_CONV_IM, buddy->account, buddy->name); + + return TRUE; +} + + + +/**************************************************************************/ +/** @name Gaim DBUS property handling functions */ +/**************************************************************************/ + + +typedef struct _GaimDBusProperty { + char *name; + gint offset; + GaimType type; +} GaimDBusProperty; + +/* change GAIM_TYPE into G_TYPE */ + +static gboolean +gaim_dbus_get_property(GaimDBusProperty *list, int list_len, + gpointer data, const char *name, + GValue *value, GError **error) +{ + int i; + + for(i=0; i<list_len; i++) { + if (!strcmp(list[i].name, name)) { + gpointer ptr = G_STRUCT_MEMBER_P(data, list[i].offset); + switch(list[i].type) { + case GAIM_TYPE_STRING: + g_value_init(value, G_TYPE_STRING); + g_value_set_string (value, g_strdup(null_to_empty(*(char **)ptr))); + break; + + case GAIM_TYPE_INT: + g_value_init(value, G_TYPE_INT); + g_value_set_int (value, *(int*) ptr); + break; + + case GAIM_TYPE_BOOLEAN: + g_value_init(value, G_TYPE_BOOLEAN); + g_value_set_int (value, *(gboolean*) ptr); + break; + + case GAIM_TYPE_POINTER: /* registered pointers only! */ + g_value_init(value, G_TYPE_INT); + g_value_set_int (value, + gaim_dbus_pointer_to_id (*(gpointer *)ptr)); + break; + default: + g_assert_not_reached(); + } + return TRUE; + } + } + + g_value_init(value, G_TYPE_INT); + g_value_set_int(value, 0); + error_unless_1(FALSE, "Invalid property '%s'", name); +} + + +#define DECLARE_PROPERTY(maintype, name, type) {#name, G_STRUCT_OFFSET(maintype, name), type} + +GaimDBusProperty buddy_properties [] = { + DECLARE_PROPERTY(GaimBuddy, name, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimBuddy, alias, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimBuddy, server_alias, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimBuddy, account, GAIM_TYPE_POINTER) +}; + +GaimDBusProperty account_properties [] = { + DECLARE_PROPERTY(GaimAccount, username, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimAccount, alias, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimAccount, user_info, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimAccount, protocol_id, GAIM_TYPE_STRING), +}; + +GaimDBusProperty contact_properties [] = { + DECLARE_PROPERTY(GaimContact, alias, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimContact, totalsize, GAIM_TYPE_INT), + DECLARE_PROPERTY(GaimContact, currentsize, GAIM_TYPE_INT), + DECLARE_PROPERTY(GaimContact, online, GAIM_TYPE_INT), + DECLARE_PROPERTY(GaimContact, priority, GAIM_TYPE_POINTER), + DECLARE_PROPERTY(GaimContact, priority_valid, GAIM_TYPE_BOOLEAN), +}; + +GaimDBusProperty group_properties [] = { + DECLARE_PROPERTY(GaimGroup, name, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimGroup, totalsize, GAIM_TYPE_INT), + DECLARE_PROPERTY(GaimGroup, currentsize, GAIM_TYPE_INT), + DECLARE_PROPERTY(GaimGroup, online, GAIM_TYPE_INT), +}; + +GaimDBusProperty chat_properties [] = { + DECLARE_PROPERTY(GaimChat, alias, GAIM_TYPE_STRING), + DECLARE_PROPERTY(GaimChat, account, GAIM_TYPE_POINTER), +}; + + +#define DECLARE_PROPERTY_HANDLER(type, gaim_type) \ + static gboolean \ + gaim_object_get_##type##_property (GaimObject *unused, \ + gint id, const char *property_name, \ + GValue *value, GError **error) \ + { \ + gpointer object = gaim_dbus_id_to_pointer(id, gaim_type); \ + \ + error_unless_1(object, "Invalid " #type " id: %i", id); \ + \ + return gaim_dbus_get_property(type##_properties, \ + G_N_ELEMENTS(type##_properties), \ + object, property_name, value, error); \ + } + +DECLARE_PROPERTY_HANDLER(buddy, DBUS_POINTER_BUDDY) +DECLARE_PROPERTY_HANDLER(account, DBUS_POINTER_ACCOUNT) +DECLARE_PROPERTY_HANDLER(contact, DBUS_POINTER_ACCOUNT) +DECLARE_PROPERTY_HANDLER(group, DBUS_POINTER_ACCOUNT) +DECLARE_PROPERTY_HANDLER(chat, DBUS_POINTER_ACCOUNT) + #include "dbus-server-bindings.c" + +/**************************************************************************/ +/** @name Gaim DBUS pointer registration mechanism */ +/**************************************************************************/ + +static GHashTable *map_id_node; +static GHashTable *map_id_type; +static GHashTable *map_node_id; + +void gaim_dbus_init_ids(void) { + map_id_node = g_hash_table_new (g_direct_hash, g_direct_equal); + map_id_type = g_hash_table_new (g_direct_hash, g_direct_equal); + map_node_id = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type) +{ + static gint last_id = 0; + g_assert(g_hash_table_lookup(map_node_id, node) == NULL); + + + last_id++; + g_hash_table_insert(map_node_id, node, GINT_TO_POINTER(last_id)); + g_hash_table_insert(map_id_node, GINT_TO_POINTER(last_id), node); + g_hash_table_insert(map_id_type, GINT_TO_POINTER(last_id), + GINT_TO_POINTER(type)); +} + + +void gaim_dbus_unregister_pointer(gpointer node) { + gpointer id = g_hash_table_lookup(map_node_id, node); + + g_hash_table_remove(map_node_id, node); + g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); + g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); +} + +gint gaim_dbus_pointer_to_id(gpointer node) { + gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); + g_assert(id); + return id; +} + +gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type) { + if (type != GPOINTER_TO_INT(g_hash_table_lookup(map_id_type, + GINT_TO_POINTER(id)))) + return NULL; + return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); +} + + + +/**************************************************************************/ +/** @name Gaim DBUS init function */ +/**************************************************************************/ + + gboolean dbus_server_init(void) { DBusGConnection *connection; - GError *error; + GError *error = NULL; DBusGProxy *driver_proxy; guint32 request_name_ret; + gaim_object_error_quark = + g_quark_from_static_string("org.gaim.GaimError"); + gaim_debug_misc("dbus", "launching dbus server\n"); - + /* Connect to the bus */ error = NULL; @@ -121,21 +445,21 @@ if (connection == NULL) { g_assert(error); - gaim_debug_error("dbus", "Failed to open connection to bus: %s\n", + gaim_debug_error("dbus", "Failed to open connection to bus: %s\n", error->message); g_error_free (error); return FALSE; } - /* Instantiate the gaim dbus object and register it */ gaim_object = g_object_new (GAIM_TYPE_OBJECT, NULL); - dbus_g_object_type_install_info (GAIM_TYPE_OBJECT, + + dbus_g_object_type_install_info (GAIM_TYPE_OBJECT, &dbus_glib_gaim_object_object_info); - dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, + dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, gaim_object); @@ -146,11 +470,12 @@ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + g_assert(driver_proxy); /* Test whether the registration was successful */ org_freedesktop_DBus_request_name(driver_proxy, DBUS_SERVICE_GAIM, - 0, &request_name_ret, &error); + DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &request_name_ret, &error); if (error) { gaim_debug_error("dbus", "Failed to get name: %s\n", error->message); @@ -160,7 +485,7 @@ if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - gaim_debug_error ("dbus", "Got result code %u from requesting name\n", + gaim_debug_error ("dbus", "Got result code %u from requesting name\n", request_name_ret); return FALSE; } @@ -168,6 +493,6 @@ gaim_debug_misc ("dbus", "GLib test service has name '%s'\n", DBUS_SERVICE_GAIM); gaim_debug_misc ("dbus", "GLib test service entering main loop\n"); - + return TRUE; }
--- a/src/dbus-server.h Thu Jul 07 15:43:05 2005 +0000 +++ b/src/dbus-server.h Thu Jul 07 15:43:48 2005 +0000 @@ -27,8 +27,28 @@ #ifndef _GAIM_DBUS_SERVER_H_ #define _GAIM_DBUS_SERVER_H_ + G_BEGIN_DECLS +/* These are the categories of codes used by gaim dbus implementation + for remote calls. In practice, they don't matter + */ +typedef enum { + DBUS_ERROR_NONE = 0, + DBUS_ERROR_NOT_FOUND = 1 +} DbusErrorCodes; + +/* Types of pointers that can be registered with the gaim dbus pointer + registration engine. See below */ +typedef enum { + DBUS_POINTER_GROUP, + DBUS_POINTER_CONTACT, + DBUS_POINTER_BUDDY, + DBUS_POINTER_CHAT, + DBUS_POINTER_ACCOUNT +} GaimDBusPointerType; + + /** * Starts the gaim DBUS server. It is responsible for handling DBUS * requests from other applications. @@ -37,6 +57,52 @@ */ gboolean dbus_server_init(void); +/** + Initializes gaim dbus pointer registration engine. + + Remote dbus applications need a way of addressing objects exposed + by gaim to the outside world. In gaim itself, these objects (such + as GaimBuddy and company) are identified by pointers. The gaim + dbus pointer registration engine converts pointers to handles and + back. + + In order for an object to participate in the scheme, it must + register itself and its type with the engine. This registration + allocates an integer id which can be resolved to the pointer and + back. + + Handles are not persistent. They are reissued every time gaim is + started. This is not good; external applications that use gaim + should work even whether gaim was restarted in the middle of the + interaction. + + Pointer registration is only a temporary solution. When GaimBuddy + and similar structures have been converted into gobjects, this + registration will be done automatically by objects themselves. + + By the way, this kind of object-handle translation should be so + common that there must be a library (maybe even glib) that + implements it. I feel a bit like reinventing the wheel here. +*/ +void gaim_dbus_init_ids(void); + +/** + Registers a typed pointer. + + @node The pointer to register. + @type Type of that pointer. + */ +void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type); + +/** + Unregisters a pointer previously registered with + gaim_dbus_register_pointer. + + @node The pointer to register. + */ +void gaim_dbus_unregister_pointer(gpointer node); + + G_END_DECLS #endif /* _GAIM_DBUS_SERVER_H_ */
--- a/src/dbus-service.xml Thu Jul 07 15:43:05 2005 +0000 +++ b/src/dbus-service.xml Thu Jul 07 15:43:48 2005 +0000 @@ -8,6 +8,67 @@ </method> <method name="ConnectAll"> </method> + + <method name="GetBuddyList"> + <arg type="ai" name="buddy_ids" direction="out" /> + </method> + + + <method name="GetBuddyProperty"> + <arg type="i" name="buddy_id" /> + <arg type="s" name="property_name" /> + <arg type="v" name="value" direction="out"/> + </method> + <method name="GetAccountProperty"> + <arg type="i" name="account_id" /> + <arg type="s" name="property_name" /> + <arg type="v" name="value" direction="out"/> + </method> + <method name="GetGroupProperty"> + <arg type="i" name="group_id" /> + <arg type="s" name="property_name" /> + <arg type="v" name="value" direction="out"/> + </method> + <method name="GetContactProperty"> + <arg type="i" name="contact_id" /> + <arg type="s" name="property_name" /> + <arg type="v" name="value" direction="out"/> + </method> + <method name="GetChatProperty"> + <arg type="i" name="chat_id" /> + <arg type="s" name="property_name" /> + <arg type="v" name="value" direction="out"/> + </method> + + <method name="StartIMConversation"> + <arg type="i" name="buddy_id" /> + </method> + + <method name="FindAccount"> + <arg type="s" name="account_name" /> + <arg type="s" name="protocol_name" /> + <arg type="i" name="account_id" direction="out"/> + </method> + <method name="FindBuddy"> + <arg type="i" name="account_id" /> + <arg type="s" name="buddy_name" /> + <arg type="i" name="buddy_id" direction="out"/> + </method> + </interface> + + + <interface name="org.freedesktop.DBus.Properties"> + <!-- We implement properties ourselves rather than relying on + GObject property access. This is because currently in gaim + we have one GObject that represents many dbus objects such as + buddies, accounts, etc. Not for long! --> + +<!-- <method name="Get"> > --> +<!-- <arg type="s" name="interface_name" /> --> +<!-- <arg type="s" name="property_name" /> --> +<!-- <arg type="v" name="value" direction="out" /> --> +<!-- </method> --> + </interface> </node>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gaim-send Thu Jul 07 15:43:48 2005 +0000 @@ -0,0 +1,35 @@ +#!/bin/bash +# +# A little shell script for communicating with gaim using dbus + +METHOD_NAME=$1 + +if test -z "$METHOD_NAME" +then + cat <<EOF +This program uses dbus to talk to gaim. If the gaim is not running and +the dbus engine is set up correctly, a new instance of gaim will be started. + + Syntax: gaim-send method-name parameter1 parameter2 ..." + +This shell script just invokes dbus-send, see man dbus-send for how +to specify the parameters. + +Examples: + + gaim-send Ping + gaim-send Quit + gaim-send GetBuddyList + gaim-send GetBuddyProperty int32:5 string:alias + gaim-send StartIMConversation int32:5 + +See src/dbus-services.xml for the list of supported operations. +EOF + + exit 1 +fi + +shift +dbus-send --dest=org.gaim.GaimService --print-reply --type=method_call /org/gaim/GaimObject org.gaim.GaimInterface.$METHOD_NAME "$@" + +echo
--- a/src/gtkmain.c Thu Jul 07 15:43:05 2005 +0000 +++ b/src/gtkmain.c Thu Jul 07 15:43:48 2005 +0000 @@ -615,6 +615,12 @@ #ifdef _WIN32 wgaim_init(hint); #endif + +#ifdef HAVE_DBUS + /* start dbus pointer registration system */ + gaim_dbus_init_ids(); +#endif + gaim_core_set_ui_ops(gaim_gtk_core_get_ui_ops()); gaim_eventloop_set_ui_ops(gaim_gtk_eventloop_get_ui_ops());