Mercurial > pidgin
comparison src/dbus-server.c @ 11080:f54740547c95
[gaim-migrate @ 13092]
All gaim signals are automatically relayed to dbus.
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Sun, 10 Jul 2005 02:29:52 +0000 |
parents | 9bd0aac996f4 |
children | 1c5398ccbeb0 |
comparison
equal
deleted
inserted
replaced
11079:b2ace57224e2 | 11080:f54740547c95 |
---|---|
27 #include <stdlib.h> | 27 #include <stdlib.h> |
28 #include <string.h> | 28 #include <string.h> |
29 #include <glib/gi18n.h> | 29 #include <glib/gi18n.h> |
30 #include <glib-object.h> | 30 #include <glib-object.h> |
31 #include <glib/gquark.h> | 31 #include <glib/gquark.h> |
32 #include <glib.h> | |
32 | 33 |
33 #include "account.h" | 34 #include "account.h" |
34 #include "blist.h" | 35 #include "blist.h" |
35 #include "conversation.h" | 36 #include "conversation.h" |
36 #include "dbus-gaim.h" | 37 #include "dbus-gaim.h" |
37 #include "dbus-server.h" | 38 #include "dbus-server.h" |
38 #include "debug.h" | 39 #include "debug.h" |
39 #include "core.h" | 40 #include "core.h" |
40 #include "value.h" | 41 #include "value.h" |
41 | 42 |
42 /**************************************************************************/ | 43 static gint gaim_dbus_pointer_to_id(gpointer node); |
43 /** @name Lots of GObject crap I don't understand */ | 44 static gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type); |
44 /**************************************************************************/ | 45 |
45 | 46 |
46 typedef struct GaimObject GaimObject; | 47 /**************************************************************************/ |
47 typedef struct GaimObjectClass GaimObjectClass; | 48 /** @name Lots of GObject stuff I don't really understand */ |
49 /**************************************************************************/ | |
48 | 50 |
49 GType gaim_object_get_type(void); | 51 GType gaim_object_get_type(void); |
50 | 52 |
51 struct GaimObject { | 53 struct _GaimObject { |
52 GObject parent; | 54 GObject parent; |
55 | |
56 int ping_signal_id; | |
53 }; | 57 }; |
54 | 58 |
55 struct GaimObjectClass { | 59 typedef struct { |
56 GObjectClass parent; | 60 GObjectClass parent; |
57 }; | 61 } GaimObjectClass; |
58 | 62 |
59 #define GAIM_TYPE_OBJECT (gaim_object_get_type ()) | 63 |
60 #define GAIM_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GAIM_TYPE_OBJECT, GaimObject)) | 64 |
61 #define GAIM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIM_TYPE_OBJECT, GaimObjectClass)) | 65 #define GAIM_DBUS_TYPE_OBJECT (gaim_object_get_type ()) |
62 #define GAIM_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GAIM_TYPE_OBJECT)) | 66 #define GAIM_DBUS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GAIM_DBUS_TYPE_OBJECT, GaimObject)) |
63 #define GAIM_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIM_TYPE_OBJECT)) | 67 #define GAIM_DBUS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIM_DBUS_TYPE_OBJECT, GaimObjectClass)) |
64 #define GAIM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIM_TYPE_OBJECT, GaimObjectClass)) | 68 #define GAIM_DBUS_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GAIM_DBUS_TYPE_OBJECT)) |
69 #define GAIM_DBUS_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIM_DBUS_TYPE_OBJECT)) | |
70 #define GAIM_DBUS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIM_DBUS_TYPE_OBJECT, GaimObjectClass)) | |
65 | 71 |
66 G_DEFINE_TYPE(GaimObject, gaim_object, G_TYPE_OBJECT) | 72 G_DEFINE_TYPE(GaimObject, gaim_object, G_TYPE_OBJECT) |
67 | 73 |
68 | 74 GaimObject *gaim_dbus_object; |
69 static void | 75 static GQuark gaim_object_error_quark; |
70 gaim_object_init(GaimObject *obj) | 76 |
71 { | 77 static const char* null_to_empty(const char *s) { |
72 } | 78 if (s) |
73 | 79 return s; |
74 static void | 80 else |
75 gaim_object_class_init(GaimObjectClass *mobject_class) | 81 return ""; |
82 } | |
83 | |
84 | |
85 | |
86 static void gaim_object_class_init(GaimObjectClass *klass) | |
76 { | 87 { |
77 } | 88 } |
78 | 89 |
79 static GObject *gaim_object; | 90 |
80 static GQuark gaim_object_error_quark; | 91 |
81 | 92 /**************************************************************************/ |
93 /** @name Signals */ | |
94 /**************************************************************************/ | |
95 | |
96 /* used in #gaim_values_to_gvalues, undefined afterwards */ | |
97 #define my_arg(type) (ptr != NULL ? * ((type *)ptr) : va_arg(data, type)) | |
98 | |
99 /** | |
100 Converts from a list of data into an GValue array. | |
101 | |
102 @param gvalus Array of empty gvalues to be filled. | |
103 @param number The number of data items. | |
104 @param gaim_value Array of #number pointers to GaimValues. | |
105 The types of of these GaimValues determine the type | |
106 of data items. The values do not matter. | |
107 @param mainptr A pointer to a single data item. If this pointer is not #NULL, | |
108 then #number must be 1. | |
109 @param data A va_list containing data items. If | |
110 | |
111 Exactly one of #mainptr and #data must be not #NULL. If #mainptr | |
112 is not #NULL, then there is a single piece of data at the address | |
113 pointed at by #mainptr. If #data is not #NULL, then there are | |
114 #number data items in the #va_list #data. | |
115 */ | |
116 static void gaim_values_to_gvalues(GValue *gvalue, int number, | |
117 GaimValue **gaim_values, gpointer mainptr, va_list data) | |
118 { | |
119 int i; | |
120 gpointer ptr; | |
121 | |
122 g_assert(mainptr == NULL || data == NULL); | |
123 g_assert(mainptr != NULL || data != NULL); | |
124 g_assert(number == 1 || data != NULL); | |
125 | |
126 for(i=0; i<number; i++, gvalue++) { | |
127 ptr = mainptr; | |
128 if (gaim_value_is_outgoing(gaim_values[i])) { | |
129 ptr = my_arg(gpointer); | |
130 g_assert(ptr); | |
131 } | |
132 | |
133 switch(gaim_values[i]->type) { | |
134 case GAIM_TYPE_CHAR: | |
135 g_value_init(gvalue, G_TYPE_CHAR); | |
136 g_value_set_char(gvalue, (char) my_arg(int)); | |
137 break; | |
138 case GAIM_TYPE_INT: | |
139 g_value_init(gvalue, G_TYPE_INT); | |
140 g_value_set_int(gvalue, my_arg(gint)); | |
141 break; | |
142 case GAIM_TYPE_UINT: | |
143 g_value_init(gvalue, G_TYPE_UINT); | |
144 g_value_set_uint(gvalue, my_arg(guint)); | |
145 break; | |
146 case GAIM_TYPE_BOOLEAN: | |
147 g_value_init(gvalue, G_TYPE_BOOLEAN); | |
148 g_value_set_boolean(gvalue, my_arg(gboolean)); | |
149 break; | |
150 case GAIM_TYPE_STRING: | |
151 g_value_init(gvalue, G_TYPE_STRING); | |
152 g_value_set_string(gvalue, null_to_empty(my_arg(char*))); | |
153 break; | |
154 case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ | |
155 g_value_init(gvalue, G_TYPE_INT); | |
156 g_value_set_int(gvalue, | |
157 gaim_dbus_pointer_to_id(my_arg(gpointer))); | |
158 break; | |
159 case GAIM_TYPE_POINTER: | |
160 case GAIM_TYPE_OBJECT: | |
161 case GAIM_TYPE_BOXED: | |
162 my_arg(gpointer); /* cannot pass general pointers */ | |
163 g_value_init(gvalue, G_TYPE_INT); | |
164 g_value_set_int(gvalue, 0); | |
165 break; | |
166 | |
167 default: /* no conversion implemented */ | |
168 g_assert_not_reached(); | |
169 } | |
170 } | |
171 | |
172 if (data) | |
173 va_end(data); | |
174 } | |
175 | |
176 #undef my_arg /* my_arg was only used in gaim_values_to_gvalues */ | |
177 | |
178 | |
179 | |
180 /** | |
181 Converts from GaimTypes to GTypes. | |
182 | |
183 @param type A GaimType to be converted. | |
184 @result The result of the conversion (GType). | |
185 */ | |
186 static GType gaim_type_to_g_type(GaimType type) | |
187 { | |
188 switch(type) { | |
189 case GAIM_TYPE_CHAR: | |
190 return G_TYPE_CHAR; | |
191 case GAIM_TYPE_INT: | |
192 return G_TYPE_INT; | |
193 case GAIM_TYPE_UINT: | |
194 return G_TYPE_UINT; | |
195 case GAIM_TYPE_BOOLEAN: | |
196 return G_TYPE_BOOLEAN; | |
197 case GAIM_TYPE_STRING: | |
198 return G_TYPE_STRING; | |
199 case GAIM_TYPE_SUBTYPE: /* registered pointers only! */ | |
200 return G_TYPE_INT; | |
201 case GAIM_TYPE_POINTER: | |
202 case GAIM_TYPE_BOXED: | |
203 case GAIM_TYPE_OBJECT: | |
204 return G_TYPE_INT; /* always 0 */ | |
205 default: /* no conversion implemented */ | |
206 g_assert_not_reached(); | |
207 } | |
208 } | |
209 | |
210 | |
211 static const char *gaim_dbus_convert_signal_name(const char *gaim_name) | |
212 { | |
213 int gaim_index, g_index; | |
214 char *g_name = g_new(char, strlen(gaim_name)+1); | |
215 gboolean capitalize_next = TRUE; | |
216 | |
217 for(gaim_index = g_index = 0; gaim_name[gaim_index]; gaim_index++) | |
218 if (gaim_name[gaim_index] != '-' && gaim_name[gaim_index] != '_') { | |
219 if (capitalize_next) | |
220 g_name[g_index++] = g_ascii_toupper(gaim_name[gaim_index]); | |
221 else | |
222 g_name[g_index++] = gaim_name[gaim_index]; | |
223 capitalize_next = FALSE; | |
224 } else | |
225 capitalize_next = TRUE; | |
226 g_name[g_index] = 0; | |
227 | |
228 return g_name; | |
229 } | |
230 | |
231 /* Public signal-related functions */ | |
232 | |
233 | |
234 void gaim_dbus_invalid_marshaller(GClosure *closure, | |
235 GValue *return_value, | |
236 guint n_param_values, | |
237 const GValue *param_values, | |
238 gpointer invocation_hint, | |
239 gpointer marshal_data) | |
240 { | |
241 g_assert_not_reached(); | |
242 } | |
243 | |
244 int gaim_dbus_signal_register(GaimObject *object, const char *name, | |
245 GSignalCMarshaller marshaller, | |
246 int num_values, ...) | |
247 { | |
248 va_list args; | |
249 | |
250 va_start(args, num_values); | |
251 | |
252 return g_signal_new_valist(name, G_OBJECT_TYPE(object), | |
253 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, | |
254 NULL, NULL, NULL, marshaller, | |
255 G_TYPE_NONE, num_values, args); | |
256 } | |
257 | |
258 void gaim_dbus_signal_emit(GaimObject *object, int dbus_id, ...) { | |
259 va_list args; | |
260 | |
261 va_start(args, dbus_id); | |
262 | |
263 gaim_dbus_signal_emit_valist(object, dbus_id, args); | |
264 } | |
265 | |
266 void gaim_dbus_signal_emit_valist(GaimObject *object, int dbus_id, va_list args) { | |
267 g_signal_emit_valist(object, dbus_id, 0, args); | |
268 } | |
269 | |
270 int gaim_dbus_signal_register_gaim(GaimObject *object, const char *name, | |
271 GSignalCMarshaller marshaller, | |
272 int num_values, GaimValue **values) | |
273 { | |
274 int i; | |
275 int dbus_id; | |
276 GType *types; | |
277 | |
278 types = g_new0(GType, num_values); | |
279 | |
280 for(i=0; i<num_values; i++) | |
281 types[i] = gaim_type_to_g_type(values[i]->type); | |
282 | |
283 dbus_id = | |
284 g_signal_newv(gaim_dbus_convert_signal_name(name), | |
285 G_OBJECT_TYPE(object), | |
286 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, | |
287 NULL, NULL, NULL, marshaller, | |
288 G_TYPE_NONE, num_values, types); | |
289 | |
290 g_free(types); | |
291 | |
292 return dbus_id; | |
293 } | |
294 | |
295 | |
296 void gaim_dbus_signal_emit_gaim(GaimObject *object, int dbus_id, int num_values, | |
297 GaimValue **values, va_list vargs) | |
298 { | |
299 GValue *args; | |
300 int i; | |
301 | |
302 g_return_if_fail(dbus_id); | |
303 | |
304 args = g_new0(GValue, num_values + 1); | |
305 | |
306 g_value_init(args + 0, G_OBJECT_TYPE(object)); | |
307 g_value_set_object(args + 0, object); | |
308 | |
309 gaim_values_to_gvalues(args + 1, num_values, values, NULL, vargs); | |
310 | |
311 g_signal_emitv(args, dbus_id, 0, NULL); | |
312 | |
313 for(i = 1; i <= num_values; i++) | |
314 g_value_unset(args + i); | |
315 | |
316 g_free(args); | |
317 } | |
82 | 318 |
83 | 319 |
84 /**************************************************************************/ | 320 /**************************************************************************/ |
85 /** @name Utility functions */ | 321 /** @name Utility functions */ |
86 /**************************************************************************/ | 322 /**************************************************************************/ |
99 DBUS_ERROR_NOT_FOUND, \ | 335 DBUS_ERROR_NOT_FOUND, \ |
100 str, a,b); \ | 336 str, a,b); \ |
101 return FALSE; \ | 337 return FALSE; \ |
102 } | 338 } |
103 | 339 |
104 static const char* null_to_empty(const char *s) { | |
105 if (s) | |
106 return s; | |
107 else | |
108 return ""; | |
109 } | |
110 | |
111 typedef gboolean (*GaimNodeFilter)(GaimBlistNode *node, gpointer *user_data); | 340 typedef gboolean (*GaimNodeFilter)(GaimBlistNode *node, gpointer *user_data); |
112 | 341 |
113 static gboolean | 342 static gboolean |
114 filter_is_buddy(GaimBlistNode *node, gpointer *user_data) | 343 filter_is_buddy(GaimBlistNode *node, gpointer *user_data) |
115 { | 344 { |
150 /**************************************************************************/ | 379 /**************************************************************************/ |
151 /** @name Implementations of remote DBUS calls */ | 380 /** @name Implementations of remote DBUS calls */ |
152 /**************************************************************************/ | 381 /**************************************************************************/ |
153 | 382 |
154 static gboolean | 383 static gboolean |
155 gaim_object_ping(GaimObject *obj, GError **error) | 384 gaim_object_ping(GaimObject *object, GError **error) |
156 { | 385 { |
386 gaim_dbus_signal_emit(object, object->ping_signal_id, "Ping Pong!"); | |
157 return TRUE; | 387 return TRUE; |
158 } | 388 } |
159 | 389 |
160 static gboolean | 390 static gboolean |
161 gaim_object_quit(GaimObject *obj, GError **error) | 391 gaim_object_quit(GaimObject *obj, GError **error) |
202 | 432 |
203 | 433 |
204 | 434 |
205 | 435 |
206 static gboolean | 436 static gboolean |
207 gaim_object_find_account(GaimObject *unused, | 437 gaim_object_find_account(GaimObject *object, |
208 const char *account_name, const char *protocol_name, | 438 const char *account_name, const char *protocol_name, |
209 gint *account_id, GError **error) | 439 gint *account_id, GError **error) |
210 { | 440 { |
211 GaimAccount *account = gaim_accounts_find(account_name, protocol_name); | 441 GaimAccount *account = gaim_accounts_find(account_name, protocol_name); |
212 | 442 |
216 *account_id = gaim_dbus_pointer_to_id(account); | 446 *account_id = gaim_dbus_pointer_to_id(account); |
217 return TRUE; | 447 return TRUE; |
218 } | 448 } |
219 | 449 |
220 static gboolean | 450 static gboolean |
221 gaim_object_find_buddy(GaimObject *unused, gint account_id, const char *buddy_name, | 451 gaim_object_find_buddy(GaimObject *object, gint account_id, const char *buddy_name, |
222 gint *buddy_id, GError **error) | 452 gint *buddy_id, GError **error) |
223 { | 453 { |
224 GaimAccount *account; | 454 GaimAccount *account; |
225 GaimBuddy *buddy; | 455 GaimBuddy *buddy; |
226 | 456 |
233 *buddy_id = gaim_dbus_pointer_to_id(buddy); | 463 *buddy_id = gaim_dbus_pointer_to_id(buddy); |
234 return TRUE; | 464 return TRUE; |
235 } | 465 } |
236 | 466 |
237 static gboolean | 467 static gboolean |
238 gaim_object_start_im_conversation (GaimObject *obj, gint buddy_id, GError **error) | 468 gaim_object_start_im_conversation (GaimObject *object, gint buddy_id, GError **error) |
239 { | 469 { |
240 GaimBuddy *buddy = (GaimBuddy*) gaim_dbus_id_to_pointer(buddy_id, | 470 GaimBuddy *buddy = (GaimBuddy*) gaim_dbus_id_to_pointer(buddy_id, |
241 DBUS_POINTER_BUDDY); | 471 DBUS_POINTER_BUDDY); |
242 | 472 |
243 error_unless_1(buddy, "Invalid buddy id: %i", buddy_id); | 473 error_unless_1(buddy, "Invalid buddy id: %i", buddy_id); |
269 { | 499 { |
270 int i; | 500 int i; |
271 | 501 |
272 for(i=0; i<list_len; i++) { | 502 for(i=0; i<list_len; i++) { |
273 if (!strcmp(list[i].name, name)) { | 503 if (!strcmp(list[i].name, name)) { |
274 gpointer ptr = G_STRUCT_MEMBER_P(data, list[i].offset); | 504 gpointer ptr; |
275 switch(list[i].type) { | 505 GaimValue gaim_value, *gaim_value_ptr; |
276 case GAIM_TYPE_STRING: | 506 |
277 g_value_init(value, G_TYPE_STRING); | 507 ptr = G_STRUCT_MEMBER_P(data, list[i].offset); |
278 g_value_set_string (value, g_strdup(null_to_empty(*(char **)ptr))); | 508 gaim_value.type = list[i].type; |
279 break; | 509 gaim_value.flags = 0; |
280 | 510 gaim_value_ptr = &gaim_value; |
281 case GAIM_TYPE_INT: | 511 |
282 g_value_init(value, G_TYPE_INT); | 512 gaim_values_to_gvalues(value, 1, &gaim_value_ptr, |
283 g_value_set_int (value, *(int*) ptr); | 513 ptr, NULL); |
284 break; | |
285 | |
286 case GAIM_TYPE_BOOLEAN: | |
287 g_value_init(value, G_TYPE_BOOLEAN); | |
288 g_value_set_int (value, *(gboolean*) ptr); | |
289 break; | |
290 | |
291 case GAIM_TYPE_POINTER: /* registered pointers only! */ | |
292 g_value_init(value, G_TYPE_INT); | |
293 g_value_set_int (value, | |
294 gaim_dbus_pointer_to_id (*(gpointer *)ptr)); | |
295 break; | |
296 default: | |
297 g_assert_not_reached(); | |
298 } | |
299 return TRUE; | 514 return TRUE; |
300 } | 515 } |
301 } | 516 } |
302 | 517 |
303 g_value_init(value, G_TYPE_INT); | 518 g_value_init(value, G_TYPE_INT); |
310 | 525 |
311 GaimDBusProperty buddy_properties [] = { | 526 GaimDBusProperty buddy_properties [] = { |
312 DECLARE_PROPERTY(GaimBuddy, name, GAIM_TYPE_STRING), | 527 DECLARE_PROPERTY(GaimBuddy, name, GAIM_TYPE_STRING), |
313 DECLARE_PROPERTY(GaimBuddy, alias, GAIM_TYPE_STRING), | 528 DECLARE_PROPERTY(GaimBuddy, alias, GAIM_TYPE_STRING), |
314 DECLARE_PROPERTY(GaimBuddy, server_alias, GAIM_TYPE_STRING), | 529 DECLARE_PROPERTY(GaimBuddy, server_alias, GAIM_TYPE_STRING), |
315 DECLARE_PROPERTY(GaimBuddy, account, GAIM_TYPE_POINTER) | 530 DECLARE_PROPERTY(GaimBuddy, account, GAIM_TYPE_SUBTYPE) |
316 }; | 531 }; |
317 | 532 |
318 GaimDBusProperty account_properties [] = { | 533 GaimDBusProperty account_properties [] = { |
319 DECLARE_PROPERTY(GaimAccount, username, GAIM_TYPE_STRING), | 534 DECLARE_PROPERTY(GaimAccount, username, GAIM_TYPE_STRING), |
320 DECLARE_PROPERTY(GaimAccount, alias, GAIM_TYPE_STRING), | 535 DECLARE_PROPERTY(GaimAccount, alias, GAIM_TYPE_STRING), |
325 GaimDBusProperty contact_properties [] = { | 540 GaimDBusProperty contact_properties [] = { |
326 DECLARE_PROPERTY(GaimContact, alias, GAIM_TYPE_STRING), | 541 DECLARE_PROPERTY(GaimContact, alias, GAIM_TYPE_STRING), |
327 DECLARE_PROPERTY(GaimContact, totalsize, GAIM_TYPE_INT), | 542 DECLARE_PROPERTY(GaimContact, totalsize, GAIM_TYPE_INT), |
328 DECLARE_PROPERTY(GaimContact, currentsize, GAIM_TYPE_INT), | 543 DECLARE_PROPERTY(GaimContact, currentsize, GAIM_TYPE_INT), |
329 DECLARE_PROPERTY(GaimContact, online, GAIM_TYPE_INT), | 544 DECLARE_PROPERTY(GaimContact, online, GAIM_TYPE_INT), |
330 DECLARE_PROPERTY(GaimContact, priority, GAIM_TYPE_POINTER), | 545 DECLARE_PROPERTY(GaimContact, priority, GAIM_TYPE_SUBTYPE), |
331 DECLARE_PROPERTY(GaimContact, priority_valid, GAIM_TYPE_BOOLEAN), | 546 DECLARE_PROPERTY(GaimContact, priority_valid, GAIM_TYPE_BOOLEAN), |
332 }; | 547 }; |
333 | 548 |
334 GaimDBusProperty group_properties [] = { | 549 GaimDBusProperty group_properties [] = { |
335 DECLARE_PROPERTY(GaimGroup, name, GAIM_TYPE_STRING), | 550 DECLARE_PROPERTY(GaimGroup, name, GAIM_TYPE_STRING), |
338 DECLARE_PROPERTY(GaimGroup, online, GAIM_TYPE_INT), | 553 DECLARE_PROPERTY(GaimGroup, online, GAIM_TYPE_INT), |
339 }; | 554 }; |
340 | 555 |
341 GaimDBusProperty chat_properties [] = { | 556 GaimDBusProperty chat_properties [] = { |
342 DECLARE_PROPERTY(GaimChat, alias, GAIM_TYPE_STRING), | 557 DECLARE_PROPERTY(GaimChat, alias, GAIM_TYPE_STRING), |
343 DECLARE_PROPERTY(GaimChat, account, GAIM_TYPE_POINTER), | 558 DECLARE_PROPERTY(GaimChat, account, GAIM_TYPE_SUBTYPE), |
344 }; | 559 }; |
345 | 560 |
346 | 561 |
347 #define DECLARE_PROPERTY_HANDLER(type, gaim_type) \ | 562 #define DECLARE_PROPERTY_HANDLER(type, gaim_type) \ |
348 static gboolean \ | 563 static gboolean \ |
349 gaim_object_get_##type##_property (GaimObject *unused, \ | 564 gaim_object_get_##type##_property (GaimObject *object, \ |
350 gint id, const char *property_name, \ | 565 gint id, const char *property_name, \ |
351 GValue *value, GError **error) \ | 566 GValue *value, GError **error) \ |
352 { \ | 567 { \ |
353 gpointer object = gaim_dbus_id_to_pointer(id, gaim_type); \ | 568 gpointer ptr = gaim_dbus_id_to_pointer(id, gaim_type); \ |
354 \ | 569 \ |
355 error_unless_1(object, "Invalid " #type " id: %i", id); \ | 570 error_unless_1(ptr, "Invalid " #type " id: %i", id); \ |
356 \ | 571 \ |
357 return gaim_dbus_get_property(type##_properties, \ | 572 return gaim_dbus_get_property(type##_properties, \ |
358 G_N_ELEMENTS(type##_properties), \ | 573 G_N_ELEMENTS(type##_properties), \ |
359 object, property_name, value, error); \ | 574 ptr, property_name, value, error); \ |
360 } | 575 } |
361 | 576 |
362 DECLARE_PROPERTY_HANDLER(buddy, DBUS_POINTER_BUDDY) | 577 DECLARE_PROPERTY_HANDLER(buddy, DBUS_POINTER_BUDDY) |
363 DECLARE_PROPERTY_HANDLER(account, DBUS_POINTER_ACCOUNT) | 578 DECLARE_PROPERTY_HANDLER(account, DBUS_POINTER_ACCOUNT) |
364 DECLARE_PROPERTY_HANDLER(contact, DBUS_POINTER_CONTACT) | 579 DECLARE_PROPERTY_HANDLER(contact, DBUS_POINTER_CONTACT) |
376 static GHashTable *map_id_node; | 591 static GHashTable *map_id_node; |
377 static GHashTable *map_id_type; | 592 static GHashTable *map_id_type; |
378 static GHashTable *map_node_id; | 593 static GHashTable *map_node_id; |
379 | 594 |
380 void gaim_dbus_init_ids(void) { | 595 void gaim_dbus_init_ids(void) { |
596 | |
597 | |
381 map_id_node = g_hash_table_new (g_direct_hash, g_direct_equal); | 598 map_id_node = g_hash_table_new (g_direct_hash, g_direct_equal); |
382 map_id_type = g_hash_table_new (g_direct_hash, g_direct_equal); | 599 map_id_type = g_hash_table_new (g_direct_hash, g_direct_equal); |
383 map_node_id = g_hash_table_new (g_direct_hash, g_direct_equal); | 600 map_node_id = g_hash_table_new (g_direct_hash, g_direct_equal); |
384 } | 601 } |
385 | 602 |
386 void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type) | 603 void gaim_dbus_register_pointer(gpointer node, GaimDBusPointerType type) |
387 { | 604 { |
388 static gint last_id = 0; | 605 static gint last_id = 0; |
606 | |
607 g_assert(map_node_id); | |
389 g_assert(g_hash_table_lookup(map_node_id, node) == NULL); | 608 g_assert(g_hash_table_lookup(map_node_id, node) == NULL); |
390 | 609 |
391 | 610 |
392 last_id++; | 611 last_id++; |
393 g_hash_table_insert(map_node_id, node, GINT_TO_POINTER(last_id)); | 612 g_hash_table_insert(map_node_id, node, GINT_TO_POINTER(last_id)); |
403 g_hash_table_remove(map_node_id, node); | 622 g_hash_table_remove(map_node_id, node); |
404 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); | 623 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); |
405 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); | 624 g_hash_table_remove(map_id_node, GINT_TO_POINTER(id)); |
406 } | 625 } |
407 | 626 |
408 gint gaim_dbus_pointer_to_id(gpointer node) { | 627 static gint gaim_dbus_pointer_to_id(gpointer node) { |
628 g_assert(map_node_id); | |
629 | |
409 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); | 630 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); |
410 g_assert(id); | 631 g_return_val_if_fail(id, 0); |
411 return id; | 632 return id; |
412 } | 633 } |
413 | 634 |
414 gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type) { | 635 static gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusPointerType type) { |
415 if (type != GPOINTER_TO_INT(g_hash_table_lookup(map_id_type, | 636 if (type != GPOINTER_TO_INT(g_hash_table_lookup(map_id_type, |
416 GINT_TO_POINTER(id)))) | 637 GINT_TO_POINTER(id)))) |
417 return NULL; | 638 return NULL; |
418 return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); | 639 return g_hash_table_lookup(map_id_node, GINT_TO_POINTER(id)); |
419 } | 640 } |
423 /**************************************************************************/ | 644 /**************************************************************************/ |
424 /** @name Gaim DBUS init function */ | 645 /** @name Gaim DBUS init function */ |
425 /**************************************************************************/ | 646 /**************************************************************************/ |
426 | 647 |
427 | 648 |
428 gboolean | 649 gboolean gaim_dbus_connect(GaimObject *object) |
429 dbus_server_init(void) | |
430 { | 650 { |
431 DBusGConnection *connection; | 651 DBusGConnection *connection; |
432 GError *error = NULL; | 652 GError *error = NULL; |
433 DBusGProxy *driver_proxy; | 653 DBusGProxy *driver_proxy; |
434 guint32 request_name_ret; | 654 guint32 request_name_ret; |
435 | 655 |
436 gaim_object_error_quark = | |
437 g_quark_from_static_string("org.gaim.GaimError"); | |
438 | 656 |
439 gaim_debug_misc("dbus", "launching dbus server\n"); | 657 gaim_debug_misc("dbus", "launching dbus server\n"); |
440 | 658 |
441 /* Connect to the bus */ | 659 /* Connect to the bus */ |
442 | 660 |
451 return FALSE; | 669 return FALSE; |
452 } | 670 } |
453 | 671 |
454 /* Instantiate the gaim dbus object and register it */ | 672 /* Instantiate the gaim dbus object and register it */ |
455 | 673 |
456 gaim_object = g_object_new (GAIM_TYPE_OBJECT, NULL); | 674 |
457 | 675 |
458 | 676 |
459 dbus_g_object_type_install_info (GAIM_TYPE_OBJECT, | 677 dbus_g_object_type_install_info (GAIM_DBUS_TYPE_OBJECT, |
460 &dbus_glib_gaim_object_object_info); | 678 &dbus_glib_gaim_object_object_info); |
461 | 679 |
462 dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, | 680 dbus_g_connection_register_g_object (connection, DBUS_PATH_GAIM, |
463 gaim_object); | 681 (GObject*) object); |
464 | 682 |
465 | 683 |
466 /* Obtain a proxy for the DBus object */ | 684 /* Obtain a proxy for the DBus object */ |
467 | 685 |
468 driver_proxy = dbus_g_proxy_new_for_name (connection, | 686 driver_proxy = dbus_g_proxy_new_for_name (connection, |
494 DBUS_SERVICE_GAIM); | 712 DBUS_SERVICE_GAIM); |
495 gaim_debug_misc ("dbus", "GLib test service entering main loop\n"); | 713 gaim_debug_misc ("dbus", "GLib test service entering main loop\n"); |
496 | 714 |
497 return TRUE; | 715 return TRUE; |
498 } | 716 } |
717 | |
718 | |
719 static void gaim_object_init(GaimObject *object) | |
720 { | |
721 | |
722 object->ping_signal_id = | |
723 gaim_dbus_signal_register(object, "PingSignal", | |
724 g_cclosure_marshal_VOID__STRING, | |
725 1, G_TYPE_STRING); | |
726 } | |
727 | |
728 | |
729 gboolean gaim_dbus_init(void) | |
730 { | |
731 gaim_dbus_init_ids(); | |
732 gaim_object_error_quark = | |
733 g_quark_from_static_string("org.gaim.GaimError"); | |
734 | |
735 gaim_dbus_object = GAIM_DBUS_OBJECT(g_object_new (GAIM_DBUS_TYPE_OBJECT, NULL)); | |
736 | |
737 return TRUE; | |
738 } |