Mercurial > pidgin
comparison src/dbus-server.c @ 11187:744c0708d11f
[gaim-migrate @ 13303]
gaim-remote.py implements the functionality of standard gaim-remote,
but using DBus. It can also call all gaim functions exported via
DBus.
dbus-analize-function.py can now produce dbus bindings for GHashTable
arguments.
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Wed, 03 Aug 2005 23:54:37 +0000 |
parents | 57af14280b5f |
children | 421a8523ad04 |
comparison
equal
deleted
inserted
replaced
11186:bbe84acea03a | 11187:744c0708d11f |
---|---|
94 g_hash_table_remove(map_id_type, GINT_TO_POINTER(id)); | 94 g_hash_table_remove(map_id_type, GINT_TO_POINTER(id)); |
95 } | 95 } |
96 | 96 |
97 gint gaim_dbus_pointer_to_id(gpointer node) { | 97 gint gaim_dbus_pointer_to_id(gpointer node) { |
98 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); | 98 gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node)); |
99 g_return_val_if_fail(id, 0); | 99 g_return_val_if_fail(id || node == NULL, 0); |
100 return id; | 100 return id; |
101 } | 101 } |
102 | 102 |
103 gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusType *type) { | 103 gpointer gaim_dbus_id_to_pointer(gint id, GaimDBusType *type) { |
104 GaimDBusType *objtype = | 104 GaimDBusType *objtype = |
134 dbus_set_error(error, "org.gaim.InvalidHandle", | 134 dbus_set_error(error, "org.gaim.InvalidHandle", |
135 "%s object with ID = %i not found", typename, id); | 135 "%s object with ID = %i not found", typename, id); |
136 | 136 |
137 return ptr; | 137 return ptr; |
138 } | 138 } |
139 | 139 |
140 | |
141 /**************************************************************************/ | |
142 /** @name Modified versions of some DBus functions */ | |
143 /**************************************************************************/ | |
144 | |
145 dbus_bool_t | |
146 gaim_dbus_message_get_args (DBusMessage *message, | |
147 DBusError *error, | |
148 int first_arg_type, | |
149 ...) | |
150 { | |
151 dbus_bool_t retval; | |
152 va_list var_args; | |
153 | |
154 va_start (var_args, first_arg_type); | |
155 retval = gaim_dbus_message_get_args_valist (message, error, first_arg_type, var_args); | |
156 va_end (var_args); | |
157 | |
158 return retval; | |
159 } | |
160 | |
161 dbus_bool_t | |
162 gaim_dbus_message_get_args_valist (DBusMessage *message, | |
163 DBusError *error, | |
164 int first_arg_type, | |
165 va_list var_args) | |
166 { | |
167 DBusMessageIter iter; | |
168 | |
169 dbus_message_iter_init (message, &iter); | |
170 return gaim_dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args); | |
171 } | |
172 | |
173 dbus_bool_t | |
174 gaim_dbus_message_iter_get_args(DBusMessageIter *iter, | |
175 DBusError *error, | |
176 int first_arg_type, | |
177 ...) | |
178 { | |
179 dbus_bool_t retval; | |
180 va_list var_args; | |
181 | |
182 va_start (var_args, first_arg_type); | |
183 retval = gaim_dbus_message_iter_get_args_valist(iter, error, first_arg_type, var_args); | |
184 va_end (var_args); | |
185 | |
186 return retval; | |
187 } | |
188 | |
189 #define TYPE_IS_CONTAINER(typecode) \ | |
190 ((typecode) == DBUS_TYPE_STRUCT || \ | |
191 (typecode) == DBUS_TYPE_DICT_ENTRY || \ | |
192 (typecode) == DBUS_TYPE_VARIANT || \ | |
193 (typecode) == DBUS_TYPE_ARRAY) | |
194 | |
195 | |
196 dbus_bool_t | |
197 gaim_dbus_message_iter_get_args_valist (DBusMessageIter *iter, | |
198 DBusError *error, | |
199 int first_arg_type, | |
200 va_list var_args) | |
201 { | |
202 int spec_type, msg_type, i; | |
203 | |
204 spec_type = first_arg_type; | |
205 | |
206 for(i=0; spec_type != DBUS_TYPE_INVALID; i++) { | |
207 msg_type = dbus_message_iter_get_arg_type (iter); | |
208 | |
209 if (msg_type != spec_type) { | |
210 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, | |
211 "Argument %d is specified to be of type \"%i\", but " | |
212 "is actually of type \"%i\"\n", i, | |
213 spec_type, msg_type); | |
214 return FALSE; | |
215 } | |
216 | |
217 if (!TYPE_IS_CONTAINER(spec_type)) { | |
218 gpointer ptr; | |
219 ptr = va_arg (var_args, gpointer); | |
220 dbus_message_iter_get_basic(iter, ptr); | |
221 } | |
222 else { | |
223 DBusMessageIter *sub; | |
224 sub = va_arg (var_args, DBusMessageIter*); | |
225 dbus_message_iter_recurse(iter, sub); | |
226 g_print("subiter %i:%i\n", (int) sub, * (int*) sub); | |
227 break; /* for testing only! */ | |
228 } | |
229 | |
230 spec_type = va_arg (var_args, int); | |
231 if (!dbus_message_iter_next(iter) && spec_type != DBUS_TYPE_INVALID) { | |
232 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, | |
233 "Message has only %d arguments, but more were expected", i); | |
234 return FALSE; | |
235 } | |
236 } | |
237 return TRUE; | |
238 } | |
239 | |
240 | |
241 | |
140 /**************************************************************************/ | 242 /**************************************************************************/ |
141 /** @name Useful functions */ | 243 /** @name Useful functions */ |
142 /**************************************************************************/ | 244 /**************************************************************************/ |
143 | 245 |
144 const char* empty_to_null(const char *str) { | 246 const char* empty_to_null(const char *str) { |
152 if (s) | 254 if (s) |
153 return s; | 255 return s; |
154 else | 256 else |
155 return ""; | 257 return ""; |
156 } | 258 } |
157 | |
158 | |
159 | |
160 | 259 |
161 dbus_int32_t* gaim_dbusify_GList(GList *list, gboolean free_memory, | 260 dbus_int32_t* gaim_dbusify_GList(GList *list, gboolean free_memory, |
162 dbus_int32_t *len) | 261 dbus_int32_t *len) |
163 { | 262 { |
164 dbus_int32_t *array; | 263 dbus_int32_t *array; |
190 | 289 |
191 if (free_memory) | 290 if (free_memory) |
192 g_slist_free(list); | 291 g_slist_free(list); |
193 | 292 |
194 return array; | 293 return array; |
294 } | |
295 | |
296 gpointer* gaim_GList_to_array(GList *list, gboolean free_memory, | |
297 dbus_int32_t *len) | |
298 { | |
299 gpointer *array; | |
300 int i; | |
301 GList *elem; | |
302 | |
303 *len = g_list_length(list); | |
304 array = g_new0(gpointer, g_list_length(list)); | |
305 for(i = 0, elem = list; elem != NULL; elem = elem->next, i++) | |
306 array[i] = elem->data; | |
307 | |
308 if (free_memory) | |
309 g_list_free(list); | |
310 | |
311 return array; | |
312 } | |
313 | |
314 gpointer* gaim_GSList_to_array(GSList *list, gboolean free_memory, | |
315 dbus_int32_t *len) | |
316 { | |
317 gpointer *array; | |
318 int i; | |
319 GSList *elem; | |
320 | |
321 *len = g_slist_length(list); | |
322 array = g_new0(gpointer, g_slist_length(list)); | |
323 for(i = 0, elem = list; elem != NULL; elem = elem->next, i++) | |
324 array[i] = elem->data; | |
325 | |
326 if (free_memory) | |
327 g_slist_free(list); | |
328 | |
329 return array; | |
330 } | |
331 | |
332 GHashTable *gaim_dbus_iter_hash_table(DBusMessageIter *iter, DBusError *error) { | |
333 GHashTable *hash; | |
334 | |
335 /* we do not need to destroy strings because they are part of the message */ | |
336 hash = g_hash_table_new(g_str_hash, g_str_equal); | |
337 | |
338 do { | |
339 char *key, *value; | |
340 DBusMessageIter subiter; | |
341 | |
342 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) | |
343 goto error; /* With all due respect to Dijkstra, | |
344 this goto is for exception | |
345 handling, and it is ok because it | |
346 avoids duplication of the code | |
347 responsible for destroying the hash | |
348 table. Exceptional instructions | |
349 for exceptional situations. */ | |
350 | |
351 dbus_message_iter_recurse(iter, &subiter); | |
352 if (!gaim_dbus_message_iter_get_args(&subiter, error, | |
353 DBUS_TYPE_STRING, &key, | |
354 DBUS_TYPE_STRING, &value, | |
355 DBUS_TYPE_INVALID)) | |
356 goto error; /* same here */ | |
357 | |
358 g_hash_table_insert(hash, key, value); | |
359 } while (dbus_message_iter_next(iter)); | |
360 | |
361 return hash; | |
362 | |
363 error: | |
364 g_hash_table_destroy(hash); | |
365 return NULL; | |
195 } | 366 } |
196 | 367 |
197 /**************************************************************/ | 368 /**************************************************************/ |
198 /* DBus bindings ... */ | 369 /* DBus bindings ... */ |
199 /**************************************************************/ | 370 /**************************************************************/ |
258 | 429 |
259 return FALSE; | 430 return FALSE; |
260 } | 431 } |
261 | 432 |
262 | 433 |
263 /* Introspection */ | 434 /**************************************************************************/ |
435 /** @name Signals */ | |
436 /**************************************************************************/ | |
264 | 437 |
265 static const char *gettext(const char **ptr) { | 438 static const char *gettext(const char **ptr) { |
266 const char *text = *ptr; | 439 const char *text = *ptr; |
267 *ptr += strlen(text) + 1; | 440 *ptr += strlen(text) + 1; |
268 return text; | 441 return text; |
305 | 478 |
306 direction = gettext(&text); | 479 direction = gettext(&text); |
307 type = gettext(&text); | 480 type = gettext(&text); |
308 name = gettext(&text); | 481 name = gettext(&text); |
309 | 482 |
310 g_string_append_printf(str, | 483 g_string_append_printf(str, |
311 "<arg name='%s' type='%s' direction='%s'/>\n", | 484 "<arg name='%s' type='%s' direction='%s'/>\n", |
312 name, type, direction); | 485 name, type, direction); |
313 } | 486 } |
314 g_string_append(str, "</method>\n"); | 487 g_string_append(str, "</method>\n"); |
315 } | 488 } |
316 } | 489 } |
317 | 490 |
533 gaim_dbus_init_ids(); | 706 gaim_dbus_init_ids(); |
534 return gaim_dbus_dispatch_init() ; | 707 return gaim_dbus_dispatch_init() ; |
535 } | 708 } |
536 | 709 |
537 | 710 |
538 /* Introspection support */ | |
539 | |
540 | |
541 |