comparison src/dbus-server.c @ 11171:ebb02ea3c789

[gaim-migrate @ 13272] Moved DBUS init call from gtkmain.c to core.c Reimplemented DBUS bindings mechamism to use low-level GLib bindings as described in my last blog entry. This way plugins can add new DBUS methods on the fly. Also wrote an example plugin that demonstrate how to do it. committer: Tailor Script <tailor@pidgin.im>
author Piotr Zielinski <zielaj>
date Sat, 30 Jul 2005 00:23:21 +0000
parents 1c5398ccbeb0
children 57af14280b5f
comparison
equal deleted inserted replaced
11170:0e9e2b923d09 11171:ebb02ea3c789
21 * 21 *
22 */ 22 */
23 23
24 #define DBUS_API_SUBJECT_TO_CHANGE 24 #define DBUS_API_SUBJECT_TO_CHANGE
25 25
26 #include <dbus/dbus-glib.h>
27 #include <dbus/dbus-glib-lowlevel.h>
28 #include <dbus/dbus-glib-bindings.h>
29 #include <stdio.h> 26 #include <stdio.h>
30 #include <stdlib.h> 27 #include <stdlib.h>
31 #include <string.h> 28 #include <string.h>
32 #include <glib/gi18n.h>
33 #include <glib-object.h>
34 #include <glib/gquark.h>
35 #include <glib.h>
36 29
37 #include "account.h" 30 #include "account.h"
38 #include "blist.h" 31 #include "blist.h"
39 #include "conversation.h" 32 #include "conversation.h"
40 #include "dbus-gaim.h" 33 #include "dbus-gaim.h"
41 #include "dbus-server.h" 34 #include "dbus-server.h"
42 #include "dbus-useful.h" 35 #include "dbus-useful.h"
36 #include "dbus-bindings.h"
43 #include "debug.h" 37 #include "debug.h"
44 #include "core.h" 38 #include "core.h"
45 #include "value.h" 39 #include "value.h"
46 40
47 41
48 42 /**************************************************************************/
49 /**************************************************************************/ 43 /** @name Gaim DBUS pointer registration mechanism */
50 /** @name Lots of GObject stuff I don't really understand */ 44 /**************************************************************************/
51 /**************************************************************************/ 45
52 46 /*
53 GType gaim_object_get_type(void); 47 Here we include the list of #GAIM_DBUS_DEFINE_TYPE statements for
54 48 all structs defined in gaim. This file has been generated by the
55 struct _GaimObject { 49 #dbus-analize-types.py script.
56 GObject parent; 50 */
57 DBusGProxy *proxy; 51
58 }; 52 #include "dbus-types.c"
59 53
60 typedef struct { 54 /* The following three hashtables map are used to translate between
61 GObjectClass parent; 55 pointers (nodes) and the corresponding handles (ids). */
62 } GaimObjectClass; 56
63 57 static GHashTable *map_node_id;
64 58 static GHashTable *map_id_node;
65 #define GAIM_DBUS_TYPE_OBJECT (gaim_object_get_type ()) 59 static GHashTable *map_id_type;
66 #define GAIM_DBUS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GAIM_DBUS_TYPE_OBJECT, GaimObject)) 60
67 #define GAIM_DBUS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIM_DBUS_TYPE_OBJECT, GaimObjectClass)) 61
68 #define GAIM_DBUS_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GAIM_DBUS_TYPE_OBJECT)) 62 /* This function initializes the pointer-id traslation system. It
69 #define GAIM_DBUS_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIM_DBUS_TYPE_OBJECT)) 63 creates the three above hashtables and defines parents of some types.
70 #define GAIM_DBUS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIM_DBUS_TYPE_OBJECT, GaimObjectClass)) 64 */
71 65 void gaim_dbus_init_ids(void) {
72 G_DEFINE_TYPE(GaimObject, gaim_object, G_TYPE_OBJECT) 66 map_id_node = g_hash_table_new (g_direct_hash, g_direct_equal);
73 67 map_id_type = g_hash_table_new (g_direct_hash, g_direct_equal);
74 GaimObject *gaim_dbus_object; 68 map_node_id = g_hash_table_new (g_direct_hash, g_direct_equal);
75 static GQuark gaim_object_error_quark; 69
76 70 GAIM_DBUS_TYPE(GaimBuddy)->parent = GAIM_DBUS_TYPE(GaimBlistNode);
77 #define NULLIFY(id) id = empty_to_null(id) 71 GAIM_DBUS_TYPE(GaimContact)->parent = GAIM_DBUS_TYPE(GaimBlistNode);
78 72 GAIM_DBUS_TYPE(GaimChat)->parent = GAIM_DBUS_TYPE(GaimBlistNode);
79 static const char* empty_to_null(const char *str) { 73 GAIM_DBUS_TYPE(GaimGroup)->parent = GAIM_DBUS_TYPE(GaimBlistNode);
74 }
75
76 void gaim_dbus_register_pointer(gpointer node, GaimDBusType *type)
77 {
78 static gint last_id = 0;
79
80 g_assert(map_node_id);
81 g_assert(g_hash_table_lookup(map_node_id, node) == NULL);
82
83 last_id++;
84 g_hash_table_insert(map_node_id, node, GINT_TO_POINTER(last_id));
85 g_hash_table_insert(map_id_node, GINT_TO_POINTER(last_id), node);
86 g_hash_table_insert(map_id_type, GINT_TO_POINTER(last_id), type);
87 }
88
89 void gaim_dbus_unregister_pointer(gpointer node) {
90 gpointer id = g_hash_table_lookup(map_node_id, node);
91
92 g_hash_table_remove(map_node_id, node);
93 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id));
94 g_hash_table_remove(map_id_type, GINT_TO_POINTER(id));
95 }
96
97 gint gaim_dbus_pointer_to_id(gpointer node) {
98 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node));
99 g_return_val_if_fail(id, 0);
100 return id;
101 }
102
103 gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusType *type) {
104 GaimDBusType *objtype =
105 (GaimDBusType*) g_hash_table_lookup(map_id_type,
106 GINT_TO_POINTER(id));
107
108 while (objtype != type && objtype != NULL)
109 objtype = objtype->parent;
110
111 if (objtype == type)
112 return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id));
113 else
114 return NULL;
115 }
116
117 gint gaim_dbus_pointer_to_id_error(gpointer ptr, DBusError *error)
118 {
119 gint id = gaim_dbus_pointer_to_id(ptr);
120
121 if (ptr != NULL && id == 0)
122 dbus_set_error(error, "org.gaim.ObjectNotFound",
123 "The return object is not mapped (this is a Gaim error)");
124
125 return id;
126 }
127
128 gpointer gaim_dbus_id_to_pointer_error(gint id, GaimDBusType *type,
129 const char *typename, DBusError *error)
130 {
131 gpointer ptr = gaim_dbus_id_to_pointer(id, type);
132
133 if (ptr == NULL && id != 0)
134 dbus_set_error(error, "org.gaim.InvalidHandle",
135 "%s object with ID = %i not found", typename, id);
136
137 return ptr;
138 }
139
140 /**************************************************************************/
141 /** @name Useful functions */
142 /**************************************************************************/
143
144 const char* empty_to_null(const char *str) {
80 if (str == NULL || str[0] == 0) 145 if (str == NULL || str[0] == 0)
81 return NULL; 146 return NULL;
82 else 147 else
83 return str; 148 return str;
84 } 149 }
85 150
86 static const char* null_to_empty(const char *s) { 151 const char* null_to_empty(const char *s) {
87 if (s) 152 if (s)
88 return s; 153 return s;
89 else 154 else
90 return ""; 155 return "";
91 } 156 }
92 157
93 158
94 159
95 static void gaim_object_class_init(GaimObjectClass *klass) 160
96 { 161 dbus_int32_t* gaim_dbusify_GList(GList *list, gboolean free_memory,
97 } 162 dbus_int32_t *len)
98 163 {
99 static void gaim_object_init(GaimObject *object) 164 dbus_int32_t *array;
100 {
101 }
102
103 /**************************************************************************/
104 /** @name Gaim DBUS pointer registration mechanism */
105 /**************************************************************************/
106
107 GaimDBusPointerType dbus_type_parent[DBUS_POINTER_LASTTYPE];
108
109 static GHashTable *map_id_node;
110 static GHashTable *map_id_type;
111 static GHashTable *map_node_id;
112
113
114 #define DECLARE_TYPE(type, parent) \
115 dbus_type_parent[DBUS_POINTER_##type] = DBUS_POINTER_##parent
116
117 void gaim_dbus_init_ids(void) {
118 int i; 165 int i;
119 166 GList *elem;
120 map_id_node = g_hash_table_new (g_direct_hash, g_direct_equal); 167
121 map_id_type = g_hash_table_new (g_direct_hash, g_direct_equal); 168 *len = g_list_length(list);
122 map_node_id = g_hash_table_new (g_direct_hash, g_direct_equal); 169 array = g_new0(dbus_int32_t, g_list_length(list));
123 170 for(i = 0, elem = list; elem != NULL; elem = elem->next, i++)
124 for (i = 0; i < DBUS_POINTER_LASTTYPE; i++) 171 array[i] = gaim_dbus_pointer_to_id(elem->data);
125 dbus_type_parent[i] = DBUS_POINTER_NONE; 172
126 173 if (free_memory)
127 /* some manual corrections */ 174 g_list_free(list);
128 DECLARE_TYPE(GaimBuddy, GaimBlistNode); 175
129 DECLARE_TYPE(GaimContact, GaimBlistNode); 176 return array;
130 DECLARE_TYPE(GaimChat, GaimBlistNode); 177 }
131 DECLARE_TYPE(GaimGroup, GaimBlistNode); 178
132 } 179 dbus_int32_t* gaim_dbusify_GSList(GSList *list, gboolean free_memory,
133 180 dbus_int32_t *len)
134 void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type) 181 {
135 { 182 dbus_int32_t *array;
136 static gint last_id = 0; 183 int i;
137 184 GSList *elem;
138 g_assert(map_node_id); 185
139 g_assert(g_hash_table_lookup(map_node_id, node) == NULL); 186 *len = g_slist_length(list);
140 187 array = g_new0(dbus_int32_t, g_slist_length(list));
141 188 for(i = 0, elem = list; elem != NULL; elem = elem->next, i++)
142 last_id++; 189 array[i] = gaim_dbus_pointer_to_id(elem->data);
143 g_hash_table_insert(map_node_id, node, GINT_TO_POINTER(last_id)); 190
144 g_hash_table_insert(map_id_node, GINT_TO_POINTER(last_id), node); 191 if (free_memory)
145 g_hash_table_insert(map_id_type, GINT_TO_POINTER(last_id), 192 g_slist_free(list);
146 GINT_TO_POINTER(type)); 193
147 } 194 return array;
148 195 }
149 196
150 void gaim_dbus_unregister_pointer(gpointer node) { 197
151 gpointer id = g_hash_table_lookup(map_node_id, node); 198 /**************************************************************/
152 199 /* DBus bindings ... */
153 g_hash_table_remove(map_node_id, node); 200 /**************************************************************/
154 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); 201
155 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); 202 static DBusConnection *gaim_dbus_connection;
156 } 203
157 204 DBusConnection *gaim_dbus_get_connection(void) {
158 static gint gaim_dbus_pointer_to_id(gpointer node) { 205 return gaim_dbus_connection;
159 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); 206 }
160 g_return_val_if_fail(id, 0); 207
161 return id; 208 #include "dbus-bindings.c"
162 } 209
163 210 void *gaim_dbus_get_handle(void) {
164 static gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type) { 211 static int handle;
165 GaimDBusPointerType objtype = 212
166 GPOINTER_TO_INT(g_hash_table_lookup(map_id_type, 213 return &handle;
167 GINT_TO_POINTER(id))); 214 }
168 215
169 while (objtype != type && objtype != DBUS_POINTER_NONE) 216 static gboolean
170 objtype = dbus_type_parent[objtype]; 217 gaim_dbus_dispatch_cb(DBusConnection *connection,
171 218 DBusMessage *message,
172 if (objtype == type) 219 void *user_data)
173 return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); 220 {
174 else 221 const char *name;
175 return NULL; 222 GaimDBusBinding *bindings;
176 } 223 int i;
177 224
178 /**************************************************************************/ 225 bindings = (GaimDBusBinding*) user_data;
179 /** @name Useful functions */ 226
180 /**************************************************************************/ 227 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
181 228 return FALSE;
182 229
183 #define error_unless_1(condition, str, parameter) \ 230 if (!dbus_message_has_path(message, DBUS_PATH_GAIM))
184 if (!(condition)) { \ 231 return FALSE;
185 g_set_error(error, gaim_object_error_quark, \ 232
186 DBUS_ERROR_NOT_FOUND, \ 233 name = dbus_message_get_member(message);
187 str, parameter); \ 234
188 return FALSE; \ 235 if (name == NULL)
236 return FALSE;
237
238 for(i=0; bindings[i].name; i++)
239 if (!strcmp(name, bindings[i].name)) {
240 DBusMessage *reply;
241 DBusError error;
242
243 dbus_error_init(&error);
244
245 reply = bindings[i].handler(message, &error);
246
247 if (reply == NULL && dbus_error_is_set(&error))
248 reply = dbus_message_new_error (message,
249 error.name,
250 error.message);
251
252 if (reply != NULL) {
253 dbus_connection_send (connection, reply, NULL);
254 dbus_message_unref(reply);
189 } 255 }
190 256
191 #define error_unless_2(condition, str, a,b) \ 257 return TRUE; /* return reply! */
192 if (!(condition)) { \ 258 }
193 g_set_error(error, gaim_object_error_quark, \ 259
194 DBUS_ERROR_NOT_FOUND, \ 260 return FALSE;
195 str, a,b); \ 261 }
196 return FALSE; \ 262
197 } 263 static DBusHandlerResult gaim_dbus_dispatch(DBusConnection *connection,
198 264 DBusMessage *message,
199 #define GAIM_DBUS_ID_TO_POINTER(ptr, id, type) \ 265 void *user_data)
200 G_STMT_START { \ 266 {
201 ptr = ((type*) gaim_dbus_id_to_pointer \ 267 if (gaim_signal_emit_return_1(gaim_dbus_get_handle(),
202 (id, DBUS_POINTER_##type)); \ 268 "dbus-method-called",
203 error_unless_2(ptr != NULL || id == 0, \ 269 connection, message))
204 "%s object with ID = %i not found", \ 270 return DBUS_HANDLER_RESULT_HANDLED;
205 #type, id); \ 271 else
206 } G_STMT_END 272 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
207 273 }
208 274
209 #define GAIM_DBUS_POINTER_TO_ID(id, ptr) \ 275 void gaim_dbus_register_bindings(void *handle, GaimDBusBinding *bindings) {
210 G_STMT_START { \ 276 gaim_signal_connect(gaim_dbus_get_handle(), "dbus-method-called",
211 gpointer _ptr = ptr; \ 277 handle,
212 id = gaim_dbus_pointer_to_id(_ptr); \ 278 GAIM_CALLBACK(gaim_dbus_dispatch_cb),
213 error_unless_1(ptr == NULL || id != 0, \ 279 bindings);
214 "Result object not registered (%i)", \ 280 }
215 id); \ 281
216 } G_STMT_END 282
283
284 gboolean gaim_dbus_dispatch_init(void)
285 {
286 static DBusObjectPathVTable vtable = {NULL, &gaim_dbus_dispatch};
287
288 DBusError error;
289 int result;
290
291 dbus_error_init (&error);
292 gaim_dbus_connection = dbus_bus_get (DBUS_BUS_STARTER, &error);
293
294 if (gaim_dbus_connection == NULL) {
295 gaim_debug_error("dbus", "Failed to get connection\n");
296 dbus_error_free(&error);
297 return FALSE;
298 }
299
300 if (!dbus_connection_register_object_path (gaim_dbus_connection,
301 DBUS_PATH_GAIM, &vtable, NULL))
302 {
303 gaim_debug_error("dbus", "Failed to get name: %s\n", error.name);
304 dbus_error_free(&error);
305 return FALSE;
306 }
307
308
309 result = dbus_bus_request_name (gaim_dbus_connection, DBUS_SERVICE_GAIM,
310 0, &error);
311
312 if (dbus_error_is_set (&error)) {
313 dbus_connection_unref(gaim_dbus_connection);
314 dbus_error_free(&error);
315 gaim_debug_error("dbus", "Failed to get serv name: %s\n", error.name);
316 return FALSE;
317 }
318
319 dbus_connection_setup_with_g_main(gaim_dbus_connection, NULL);
320
321 gaim_debug_misc ("dbus", "okkk\n");
322
323 gaim_signal_register(gaim_dbus_get_handle(), "dbus-method-called",
324 gaim_marshal_BOOLEAN__POINTER_POINTER,
325 gaim_value_new(GAIM_TYPE_BOOLEAN), 2,
326 gaim_value_new(GAIM_TYPE_POINTER),
327 gaim_value_new(GAIM_TYPE_POINTER));
328
329 GAIM_DBUS_REGISTER_BINDINGS(gaim_dbus_get_handle());
330
331 return TRUE;
332 }
333
217 334
218 335
219 /**************************************************************************/ 336 /**************************************************************************/
220 /** @name Signals */ 337 /** @name Signals */
221 /**************************************************************************/ 338 /**************************************************************************/
263 g_assert(ptr); 380 g_assert(ptr);
264 } 381 }
265 382
266 switch(gaim_values[i]->type) { 383 switch(gaim_values[i]->type) {
267 case GAIM_TYPE_INT: 384 case GAIM_TYPE_INT:
268 g_print("appending int\n");
269 xint = my_arg(gint); 385 xint = my_arg(gint);
270 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint); 386 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint);
271 break; 387 break;
272 case GAIM_TYPE_UINT: 388 case GAIM_TYPE_UINT:
273 xuint = my_arg(guint); 389 xuint = my_arg(guint);
274 g_print("appending uint\n");
275 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &xuint); 390 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &xuint);
276 break; 391 break;
277 case GAIM_TYPE_BOOLEAN: 392 case GAIM_TYPE_BOOLEAN:
278 g_print("appending boolean\n");
279 xboolean = my_arg(gboolean); 393 xboolean = my_arg(gboolean);
280 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &xboolean); 394 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &xboolean);
281 break; 395 break;
282 case GAIM_TYPE_STRING: 396 case GAIM_TYPE_STRING:
283 g_print("appending string\n");
284 str = null_to_empty(my_arg(char*)); 397 str = null_to_empty(my_arg(char*));
285 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str); 398 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
286 break; 399 break;
287 case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ 400 case GAIM_TYPE_SUBTYPE: /* registered pointers only! */
288 case GAIM_TYPE_POINTER: 401 case GAIM_TYPE_POINTER:
289 case GAIM_TYPE_OBJECT: 402 case GAIM_TYPE_OBJECT:
290 case GAIM_TYPE_BOXED: 403 case GAIM_TYPE_BOXED:
291 g_print("appending obj\n");
292 id = gaim_dbus_pointer_to_id(my_arg(gpointer)); 404 id = gaim_dbus_pointer_to_id(my_arg(gpointer));
293 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &id); 405 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &id);
294 break; 406 break;
295 default: /* no conversion implemented */ 407 default: /* no conversion implemented */
296 g_assert_not_reached(); 408 g_assert_not_reached();
298 } 410 }
299 } 411 }
300 412
301 #undef my_arg 413 #undef my_arg
302 414
303 void gaim_dbus_signal_emit_gaim(GaimObject *object, char *name, int num_values, 415 void gaim_dbus_signal_emit_gaim(char *name, int num_values,
304 GaimValue **values, va_list vargs) 416 GaimValue **values, va_list vargs)
305 { 417 {
306 /* pass name */ 418 /* pass name */
307 DBusMessage *signal; 419 DBusMessage *signal;
308 DBusMessageIter iter; 420 DBusMessageIter iter;
309 char *newname; 421 char *newname;
310 422
311 g_print("Emitting %s\n", name); 423 g_return_if_fail(gaim_dbus_connection);
312 g_return_if_fail(object->proxy);
313 424
314 newname = gaim_dbus_convert_signal_name(name); 425 newname = gaim_dbus_convert_signal_name(name);
315 signal = dbus_message_new_signal(DBUS_PATH_GAIM, DBUS_INTERFACE_GAIM, newname); 426 signal = dbus_message_new_signal(DBUS_PATH_GAIM, DBUS_INTERFACE_GAIM, newname);
316 dbus_message_iter_init_append(signal, &iter); 427 dbus_message_iter_init_append(signal, &iter);
317 428
318 gaim_dbus_message_append_gaim_values(&iter, num_values, values, vargs); 429 gaim_dbus_message_append_gaim_values(&iter, num_values, values, vargs);
319 430
320 dbus_g_proxy_send(object->proxy, signal, NULL); 431 dbus_connection_send(gaim_dbus_connection, signal, NULL);
321 432
322 g_free(newname); 433 g_free(newname);
323 dbus_message_unref(signal); 434 dbus_message_unref(signal);
324 } 435 }
325 436
326 437
327 /**************************************************************/
328 /* DBus bindings ... */
329 /**************************************************************/
330
331
332
333 GArray* gaim_dbusify_GList(GList *list, gboolean free_memory) {
334 GArray *array;
335 GList *elem;
336
337 array = g_array_new (FALSE, TRUE, sizeof (guint32));
338 for(elem = list; elem != NULL; elem = elem->next) {
339 int objectid;
340
341 objectid = gaim_dbus_pointer_to_id(elem->data);
342 g_array_append_val(array, objectid);
343 }
344
345 if (free_memory)
346 g_list_free(list);
347
348 return array;
349 }
350
351 GArray* gaim_dbusify_GSList(GSList *list, gboolean free_memory) {
352 GArray *array;
353 GSList *elem;
354
355 array = g_array_new (FALSE, TRUE, sizeof (guint32));
356 for(elem = list; elem != NULL; elem = elem->next) {
357 int objectid;
358
359 objectid = gaim_dbus_pointer_to_id(elem->data);
360 g_array_append_val(array, objectid);
361 }
362
363 if (free_memory)
364 g_slist_free(list);
365 return array;
366 }
367
368 #include "dbus-generated-code.c"
369
370 #include "dbus-server-bindings.c"
371
372
373
374
375
376 /**************************************************************************/
377 /** @name Gaim DBUS init function */
378 /**************************************************************************/
379
380
381 /* fixme: why do we need two functions here instead of one? */
382
383 gboolean gaim_dbus_connect(GaimObject *object)
384 {
385 DBusGConnection *connection;
386 GError *error = NULL;
387 DBusGProxy *driver_proxy;
388 guint32 request_name_ret;
389
390 gaim_debug_misc("dbus", "launching dbus server\n");
391
392 dbus_g_object_type_install_info (GAIM_DBUS_TYPE_OBJECT,
393 &dbus_glib_gaim_object_object_info); /* Connect to the bus */
394
395 error = NULL;
396 connection = dbus_g_bus_get(DBUS_BUS_STARTER, &error);
397
398 if (connection == NULL) {
399 g_assert(error);
400 gaim_debug_error("dbus", "Failed to open connection to bus: %s\n",
401 error->message);
402 g_error_free (error);
403 return FALSE;
404 }
405
406 /* Instantiate the gaim dbus object and register it */
407
408
409
410
411 /* Obtain a proxy for the DBus object */
412
413 driver_proxy = dbus_g_proxy_new_for_name (connection,
414 DBUS_SERVICE_DBUS,
415 DBUS_PATH_DBUS,
416 DBUS_INTERFACE_DBUS);
417
418 g_assert(driver_proxy);
419
420 /* Test whether the registration was successful */
421
422 org_freedesktop_DBus_request_name(driver_proxy, DBUS_SERVICE_GAIM,
423 DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &request_name_ret, &error);
424
425 if (error) {
426 gaim_debug_error("dbus", "Failed to get name: %s\n", error->message);
427 g_error_free (error);
428 return FALSE;
429 }
430
431 if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
432 {
433 gaim_debug_error ("dbus", "Got result code %u from requesting name\n",
434 request_name_ret);
435 return FALSE;
436 }
437
438 gaim_debug_misc ("dbus", "GLib test service has name '%s'\n",
439 DBUS_SERVICE_GAIM);
440
441
442
443 dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM,
444 (GObject*) object);
445
446 object->proxy = dbus_g_proxy_new_for_name (connection,
447 DBUS_SERVICE_GAIM,
448 DBUS_PATH_GAIM,
449 DBUS_INTERFACE_GAIM);
450
451 gaim_debug_misc ("dbus", "GLib test service entering main loop\n");
452
453 return TRUE;
454 }
455 438
456 439
457 440
458 441
459 gboolean gaim_dbus_init(void) 442 gboolean gaim_dbus_init(void)
460 { 443 {
444 gaim_debug_register_category("dbus");
445
461 gaim_dbus_init_ids(); 446 gaim_dbus_init_ids();
462 gaim_object_error_quark = 447 return gaim_dbus_dispatch_init() ;
463 g_quark_from_static_string("org.gaim.GaimError"); 448 }
464 449
465 450
466
467 gaim_dbus_object = GAIM_DBUS_OBJECT(g_object_new (GAIM_DBUS_TYPE_OBJECT, NULL));
468
469 gaim_dbus_object->proxy = NULL;
470 return TRUE;
471 }
472
473