Mercurial > pidgin
diff src/dbus-server.c @ 11146:1c5398ccbeb0
[gaim-migrate @ 13217]
Gaim-DBUS signal export works with DBUS >= 0.35
Various gaim API functions available through DBUS
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Fri, 22 Jul 2005 19:47:29 +0000 |
parents | f54740547c95 |
children | ebb02ea3c789 |
line wrap: on
line diff
--- a/src/dbus-server.c Fri Jul 22 07:11:08 2005 +0000 +++ b/src/dbus-server.c Fri Jul 22 19:47:29 2005 +0000 @@ -21,7 +21,10 @@ * */ +#define DBUS_API_SUBJECT_TO_CHANGE + #include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-bindings.h> #include <stdio.h> #include <stdlib.h> @@ -36,12 +39,11 @@ #include "conversation.h" #include "dbus-gaim.h" #include "dbus-server.h" +#include "dbus-useful.h" #include "debug.h" #include "core.h" #include "value.h" -static gint gaim_dbus_pointer_to_id(gpointer node); -static gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type); /**************************************************************************/ @@ -51,9 +53,8 @@ GType gaim_object_get_type(void); struct _GaimObject { - GObject parent; - - int ping_signal_id; + GObject parent; + DBusGProxy *proxy; }; typedef struct { @@ -61,7 +62,6 @@ } GaimObjectClass; - #define GAIM_DBUS_TYPE_OBJECT (gaim_object_get_type ()) #define GAIM_DBUS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GAIM_DBUS_TYPE_OBJECT, GaimObject)) #define GAIM_DBUS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIM_DBUS_TYPE_OBJECT, GaimObjectClass)) @@ -74,6 +74,15 @@ GaimObject *gaim_dbus_object; static GQuark gaim_object_error_quark; +#define NULLIFY(id) id = empty_to_null(id) + +static const char* empty_to_null(const char *str) { + if (str == NULL || str[0] == 0) + return NULL; + else + return str; +} + static const char* null_to_empty(const char *s) { if (s) return s; @@ -87,517 +96,39 @@ { } - - -/**************************************************************************/ -/** @name Signals */ -/**************************************************************************/ - -/* used in #gaim_values_to_gvalues, undefined afterwards */ -#define my_arg(type) (ptr != NULL ? * ((type *)ptr) : va_arg(data, type)) - -/** - Converts from a list of data into an GValue array. - - @param gvalus Array of empty gvalues to be filled. - @param number The number of data items. - @param gaim_value Array of #number pointers to GaimValues. - The types of of these GaimValues determine the type - of data items. The values do not matter. - @param mainptr A pointer to a single data item. If this pointer is not #NULL, - then #number must be 1. - @param data A va_list containing data items. If - - Exactly one of #mainptr and #data must be not #NULL. If #mainptr - is not #NULL, then there is a single piece of data at the address - pointed at by #mainptr. If #data is not #NULL, then there are - #number data items in the #va_list #data. - */ -static void gaim_values_to_gvalues(GValue *gvalue, int number, - GaimValue **gaim_values, gpointer mainptr, va_list data) -{ - int i; - gpointer ptr; - - g_assert(mainptr == NULL || data == NULL); - g_assert(mainptr != NULL || data != NULL); - g_assert(number == 1 || data != NULL); - - for(i=0; i<number; i++, gvalue++) { - ptr = mainptr; - if (gaim_value_is_outgoing(gaim_values[i])) { - ptr = my_arg(gpointer); - g_assert(ptr); - } - - switch(gaim_values[i]->type) { - case GAIM_TYPE_CHAR: - g_value_init(gvalue, G_TYPE_CHAR); - g_value_set_char(gvalue, (char) my_arg(int)); - break; - case GAIM_TYPE_INT: - g_value_init(gvalue, G_TYPE_INT); - g_value_set_int(gvalue, my_arg(gint)); - break; - case GAIM_TYPE_UINT: - g_value_init(gvalue, G_TYPE_UINT); - g_value_set_uint(gvalue, my_arg(guint)); - break; - case GAIM_TYPE_BOOLEAN: - g_value_init(gvalue, G_TYPE_BOOLEAN); - g_value_set_boolean(gvalue, my_arg(gboolean)); - break; - case GAIM_TYPE_STRING: - g_value_init(gvalue, G_TYPE_STRING); - g_value_set_string(gvalue, null_to_empty(my_arg(char*))); - break; - case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ - g_value_init(gvalue, G_TYPE_INT); - g_value_set_int(gvalue, - gaim_dbus_pointer_to_id(my_arg(gpointer))); - break; - case GAIM_TYPE_POINTER: - case GAIM_TYPE_OBJECT: - case GAIM_TYPE_BOXED: - my_arg(gpointer); /* cannot pass general pointers */ - g_value_init(gvalue, G_TYPE_INT); - g_value_set_int(gvalue, 0); - break; - - default: /* no conversion implemented */ - g_assert_not_reached(); - } - } - - if (data) - va_end(data); -} - -#undef my_arg /* my_arg was only used in gaim_values_to_gvalues */ - - - -/** - Converts from GaimTypes to GTypes. - - @param type A GaimType to be converted. - @result The result of the conversion (GType). -*/ -static GType gaim_type_to_g_type(GaimType type) +static void gaim_object_init(GaimObject *object) { - switch(type) { - case GAIM_TYPE_CHAR: - return G_TYPE_CHAR; - case GAIM_TYPE_INT: - return G_TYPE_INT; - case GAIM_TYPE_UINT: - return G_TYPE_UINT; - case GAIM_TYPE_BOOLEAN: - return G_TYPE_BOOLEAN; - case GAIM_TYPE_STRING: - return G_TYPE_STRING; - case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ - return G_TYPE_INT; - case GAIM_TYPE_POINTER: - case GAIM_TYPE_BOXED: - case GAIM_TYPE_OBJECT: - return G_TYPE_INT; /* always 0 */ - default: /* no conversion implemented */ - g_assert_not_reached(); - } -} - - -static const char *gaim_dbus_convert_signal_name(const char *gaim_name) -{ - int gaim_index, g_index; - char *g_name = g_new(char, strlen(gaim_name)+1); - gboolean capitalize_next = TRUE; - - for(gaim_index = g_index = 0; gaim_name[gaim_index]; gaim_index++) - if (gaim_name[gaim_index] != '-' && gaim_name[gaim_index] != '_') { - if (capitalize_next) - g_name[g_index++] = g_ascii_toupper(gaim_name[gaim_index]); - else - g_name[g_index++] = gaim_name[gaim_index]; - capitalize_next = FALSE; - } else - capitalize_next = TRUE; - g_name[g_index] = 0; - - return g_name; -} - -/* Public signal-related functions */ - - -void gaim_dbus_invalid_marshaller(GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - g_assert_not_reached(); -} - -int gaim_dbus_signal_register(GaimObject *object, const char *name, - GSignalCMarshaller marshaller, - int num_values, ...) -{ - va_list args; - - va_start(args, num_values); - - return g_signal_new_valist(name, G_OBJECT_TYPE(object), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - NULL, NULL, NULL, marshaller, - G_TYPE_NONE, num_values, args); -} - -void gaim_dbus_signal_emit(GaimObject *object, int dbus_id, ...) { - va_list args; - - va_start(args, dbus_id); - - gaim_dbus_signal_emit_valist(object, dbus_id, args); -} - -void gaim_dbus_signal_emit_valist(GaimObject *object, int dbus_id, va_list args) { - g_signal_emit_valist(object, dbus_id, 0, args); -} - -int gaim_dbus_signal_register_gaim(GaimObject *object, const char *name, - GSignalCMarshaller marshaller, - int num_values, GaimValue **values) -{ - int i; - int dbus_id; - GType *types; - - types = g_new0(GType, num_values); - - for(i=0; i<num_values; i++) - types[i] = gaim_type_to_g_type(values[i]->type); - - dbus_id = - g_signal_newv(gaim_dbus_convert_signal_name(name), - G_OBJECT_TYPE(object), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - NULL, NULL, NULL, marshaller, - G_TYPE_NONE, num_values, types); - - g_free(types); - - return dbus_id; -} - - -void gaim_dbus_signal_emit_gaim(GaimObject *object, int dbus_id, int num_values, - GaimValue **values, va_list vargs) -{ - GValue *args; - int i; - - g_return_if_fail(dbus_id); - - args = g_new0(GValue, num_values + 1); - - g_value_init(args + 0, G_OBJECT_TYPE(object)); - g_value_set_object(args + 0, object); - - gaim_values_to_gvalues(args + 1, num_values, values, NULL, vargs); - - g_signal_emitv(args, dbus_id, 0, NULL); - - for(i = 1; i <= num_values; i++) - g_value_unset(args + i); - - g_free(args); } - -/**************************************************************************/ -/** @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; \ - } - -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 *object, GError **error) -{ - gaim_dbus_signal_emit(object, object->ping_signal_id, "Ping Pong!"); - return TRUE; -} - -static gboolean -gaim_object_quit(GaimObject *obj, GError **error) -{ - g_timeout_add(0, gaim_core_quit_cb, NULL); - return TRUE; -} - -static gboolean -gaim_object_connect_all(GaimObject *obj, GError **error) -{ - GList *cur; - - for (cur = gaim_accounts_get_all(); cur != NULL; cur = cur->next) - gaim_account_connect((GaimAccount*) cur->data); - - 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 *object, - 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 *object, 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 *object, 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; - GaimValue gaim_value, *gaim_value_ptr; - - ptr = G_STRUCT_MEMBER_P(data, list[i].offset); - gaim_value.type = list[i].type; - gaim_value.flags = 0; - gaim_value_ptr = &gaim_value; - - gaim_values_to_gvalues(value, 1, &gaim_value_ptr, - ptr, NULL); - 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_SUBTYPE) -}; - -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_SUBTYPE), - 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_SUBTYPE), -}; - - -#define DECLARE_PROPERTY_HANDLER(type, gaim_type) \ - static gboolean \ - gaim_object_get_##type##_property (GaimObject *object, \ - gint id, const char *property_name, \ - GValue *value, GError **error) \ - { \ - gpointer ptr = gaim_dbus_id_to_pointer(id, gaim_type); \ - \ - error_unless_1(ptr, "Invalid " #type " id: %i", id); \ - \ - return gaim_dbus_get_property(type##_properties, \ - G_N_ELEMENTS(type##_properties), \ - ptr, property_name, value, error); \ - } - -DECLARE_PROPERTY_HANDLER(buddy, DBUS_POINTER_BUDDY) -DECLARE_PROPERTY_HANDLER(account, DBUS_POINTER_ACCOUNT) -DECLARE_PROPERTY_HANDLER(contact, DBUS_POINTER_CONTACT) -DECLARE_PROPERTY_HANDLER(group, DBUS_POINTER_GROUP) -DECLARE_PROPERTY_HANDLER(chat, DBUS_POINTER_CHAT) - -#include "dbus-server-bindings.c" - - - /**************************************************************************/ /** @name Gaim DBUS pointer registration mechanism */ /**************************************************************************/ +GaimDBusPointerType dbus_type_parent[DBUS_POINTER_LASTTYPE]; + static GHashTable *map_id_node; static GHashTable *map_id_type; static GHashTable *map_node_id; + +#define DECLARE_TYPE(type, parent) \ + dbus_type_parent[DBUS_POINTER_##type] = DBUS_POINTER_##parent + void gaim_dbus_init_ids(void) { - + int i; 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); + + for (i = 0; i < DBUS_POINTER_LASTTYPE; i++) + dbus_type_parent[i] = DBUS_POINTER_NONE; + + /* some manual corrections */ + DECLARE_TYPE(GaimBuddy, GaimBlistNode); + DECLARE_TYPE(GaimContact, GaimBlistNode); + DECLARE_TYPE(GaimChat, GaimBlistNode); + DECLARE_TYPE(GaimGroup, GaimBlistNode); } void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type) @@ -625,20 +156,221 @@ } static gint gaim_dbus_pointer_to_id(gpointer node) { - g_assert(map_node_id); - gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); g_return_val_if_fail(id, 0); return id; } static 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)))) + GaimDBusPointerType objtype = + GPOINTER_TO_INT(g_hash_table_lookup(map_id_type, + GINT_TO_POINTER(id))); + + while (objtype != type && objtype != DBUS_POINTER_NONE) + objtype = dbus_type_parent[objtype]; + + if (objtype == type) + return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); + else return NULL; - return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); } +/**************************************************************************/ +/** @name Useful 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; \ + } + +#define GAIM_DBUS_ID_TO_POINTER(ptr, id, type) \ + G_STMT_START { \ + ptr = ((type*) gaim_dbus_id_to_pointer \ + (id, DBUS_POINTER_##type)); \ + error_unless_2(ptr != NULL || id == 0, \ + "%s object with ID = %i not found", \ + #type, id); \ + } G_STMT_END + + +#define GAIM_DBUS_POINTER_TO_ID(id, ptr) \ + G_STMT_START { \ + gpointer _ptr = ptr; \ + id = gaim_dbus_pointer_to_id(_ptr); \ + error_unless_1(ptr == NULL || id != 0, \ + "Result object not registered (%i)", \ + id); \ + } G_STMT_END + + +/**************************************************************************/ +/** @name Signals */ +/**************************************************************************/ + + + +static char *gaim_dbus_convert_signal_name(const char *gaim_name) +{ + int gaim_index, g_index; + char *g_name = g_new(char, strlen(gaim_name)+1); + gboolean capitalize_next = TRUE; + + for(gaim_index = g_index = 0; gaim_name[gaim_index]; gaim_index++) + if (gaim_name[gaim_index] != '-' && gaim_name[gaim_index] != '_') { + if (capitalize_next) + g_name[g_index++] = g_ascii_toupper(gaim_name[gaim_index]); + else + g_name[g_index++] = gaim_name[gaim_index]; + capitalize_next = FALSE; + } else + capitalize_next = TRUE; + g_name[g_index] = 0; + + return g_name; +} + +#define my_arg(type) (ptr != NULL ? * ((type *)ptr) : va_arg(data, type)) + +static void gaim_dbus_message_append_gaim_values(DBusMessageIter *iter, + int number, + GaimValue **gaim_values, + va_list data) +{ + int i; + + for(i=0; i<number; i++) { + const char *str; + int id; + gint xint; + guint xuint; + gboolean xboolean; + gpointer ptr = NULL; + if (gaim_value_is_outgoing(gaim_values[i])) { + ptr = my_arg(gpointer); + g_assert(ptr); + } + + switch(gaim_values[i]->type) { + case GAIM_TYPE_INT: + g_print("appending int\n"); + xint = my_arg(gint); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint); + break; + case GAIM_TYPE_UINT: + xuint = my_arg(guint); + g_print("appending uint\n"); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &xuint); + break; + case GAIM_TYPE_BOOLEAN: + g_print("appending boolean\n"); + xboolean = my_arg(gboolean); + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &xboolean); + break; + case GAIM_TYPE_STRING: + g_print("appending string\n"); + str = null_to_empty(my_arg(char*)); + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str); + break; + case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ + case GAIM_TYPE_POINTER: + case GAIM_TYPE_OBJECT: + case GAIM_TYPE_BOXED: + g_print("appending obj\n"); + id = gaim_dbus_pointer_to_id(my_arg(gpointer)); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &id); + break; + default: /* no conversion implemented */ + g_assert_not_reached(); + } + } +} + +#undef my_arg + +void gaim_dbus_signal_emit_gaim(GaimObject *object, char *name, int num_values, + GaimValue **values, va_list vargs) +{ + /* pass name */ + DBusMessage *signal; + DBusMessageIter iter; + char *newname; + + g_print("Emitting %s\n", name); + g_return_if_fail(object->proxy); + + newname = gaim_dbus_convert_signal_name(name); + signal = dbus_message_new_signal(DBUS_PATH_GAIM, DBUS_INTERFACE_GAIM, newname); + dbus_message_iter_init_append(signal, &iter); + + gaim_dbus_message_append_gaim_values(&iter, num_values, values, vargs); + + dbus_g_proxy_send(object->proxy, signal, NULL); + + g_free(newname); + dbus_message_unref(signal); +} + + +/**************************************************************/ +/* DBus bindings ... */ +/**************************************************************/ + + + +GArray* gaim_dbusify_GList(GList *list, gboolean free_memory) { + GArray *array; + GList *elem; + + array = g_array_new (FALSE, TRUE, sizeof (guint32)); + for(elem = list; elem != NULL; elem = elem->next) { + int objectid; + + objectid = gaim_dbus_pointer_to_id(elem->data); + g_array_append_val(array, objectid); + } + + if (free_memory) + g_list_free(list); + + return array; +} + +GArray* gaim_dbusify_GSList(GSList *list, gboolean free_memory) { + GArray *array; + GSList *elem; + + array = g_array_new (FALSE, TRUE, sizeof (guint32)); + for(elem = list; elem != NULL; elem = elem->next) { + int objectid; + + objectid = gaim_dbus_pointer_to_id(elem->data); + g_array_append_val(array, objectid); + } + + if (free_memory) + g_slist_free(list); + return array; +} + +#include "dbus-generated-code.c" + +#include "dbus-server-bindings.c" + + + /**************************************************************************/ @@ -646,6 +378,8 @@ /**************************************************************************/ +/* fixme: why do we need two functions here instead of one? */ + gboolean gaim_dbus_connect(GaimObject *object) { DBusGConnection *connection; @@ -653,10 +387,10 @@ DBusGProxy *driver_proxy; guint32 request_name_ret; - gaim_debug_misc("dbus", "launching dbus server\n"); - /* Connect to the bus */ + dbus_g_object_type_install_info (GAIM_DBUS_TYPE_OBJECT, + &dbus_glib_gaim_object_object_info); /* Connect to the bus */ error = NULL; connection = dbus_g_bus_get(DBUS_BUS_STARTER, &error); @@ -674,13 +408,6 @@ - dbus_g_object_type_install_info (GAIM_DBUS_TYPE_OBJECT, - &dbus_glib_gaim_object_object_info); - - dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, - (GObject*) object); - - /* Obtain a proxy for the DBus object */ driver_proxy = dbus_g_proxy_new_for_name (connection, @@ -710,29 +437,37 @@ gaim_debug_misc ("dbus", "GLib test service has name '%s'\n", DBUS_SERVICE_GAIM); + + + + dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, + (GObject*) object); + + object->proxy = dbus_g_proxy_new_for_name (connection, + DBUS_SERVICE_GAIM, + DBUS_PATH_GAIM, + DBUS_INTERFACE_GAIM); + gaim_debug_misc ("dbus", "GLib test service entering main loop\n"); return TRUE; } -static void gaim_object_init(GaimObject *object) -{ - - object->ping_signal_id = - gaim_dbus_signal_register(object, "PingSignal", - g_cclosure_marshal_VOID__STRING, - 1, G_TYPE_STRING); -} gboolean gaim_dbus_init(void) { - gaim_dbus_init_ids(); - gaim_object_error_quark = - g_quark_from_static_string("org.gaim.GaimError"); + gaim_dbus_init_ids(); + gaim_object_error_quark = + g_quark_from_static_string("org.gaim.GaimError"); + + gaim_dbus_object = GAIM_DBUS_OBJECT(g_object_new (GAIM_DBUS_TYPE_OBJECT, NULL)); + gaim_dbus_object->proxy = NULL; return TRUE; } + +