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