Mercurial > pidgin.yaz
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 |