|
1 /* -*- mode: C; c-file-style: "gnu" -*- */ |
|
2 /* dbus-gmain.c GLib main loop integration |
|
3 * |
|
4 * Copyright (C) 2002, 2003 CodeFactory AB |
|
5 * Copyright (C) 2005 Red Hat, Inc. |
|
6 * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
7 * Licensed under the Academic Free License version 2.1 |
|
8 * |
|
9 * This program is free software; you can redistribute it and/or modify |
|
10 * it under the terms of the GNU General Public License as published by |
|
11 * the Free Software Foundation; either version 2 of the License, or |
|
12 * (at your option) any later version. |
|
13 * |
|
14 * This program is distributed in the hope that it will be useful, |
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 * GNU General Public License for more details. |
|
18 * |
|
19 * You should have received a copy of the GNU General Public License |
|
20 * along with this program; if not, write to the Free Software |
|
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
22 * |
|
23 */ |
|
24 |
|
25 #ifndef __SYMBIAN32__ |
|
26 #include <config.h> |
|
27 #else |
|
28 #include "config.h" |
|
29 #endif //__SYMBIAN32__ |
|
30 #include <dbus/dbus-glib.h> |
|
31 #include <dbus/dbus-glib-lowlevel.h> |
|
32 #include "dbus-gtest.h" |
|
33 #include "dbus-gutils.h" |
|
34 #include "dbus-gvalue.h" |
|
35 #include "dbus-gobject.h" |
|
36 #include "dbus-gvalue-utils.h" |
|
37 #include "dbus-gsignature.h" |
|
38 #include <string.h> |
|
39 #ifndef __SYMBIAN32__ |
|
40 #include <libintl.h> |
|
41 #define _(x) dgettext (GETTEXT_PACKAGE, x) |
|
42 #define N_(x) x |
|
43 #else |
|
44 |
|
45 #define _(x) x |
|
46 #define N_(x) x |
|
47 #endif |
|
48 |
|
49 #ifdef __SYMBIAN32__ |
|
50 #include "libdbus_glib_wsd_solution.h" |
|
51 #endif |
|
52 /** |
|
53 * @defgroup DBusGLibInternals GLib bindings implementation details |
|
54 * @ingroup DBusInternals |
|
55 * @brief Implementation details of GLib bindings |
|
56 * |
|
57 * @{ |
|
58 */ |
|
59 |
|
60 /** |
|
61 * DBusGMessageQueue: |
|
62 * A GSource subclass for dispatching DBusConnection messages. |
|
63 * We need this on top of the IO handlers, because sometimes |
|
64 * there are messages to dispatch queued up but no IO pending. |
|
65 */ |
|
66 typedef struct |
|
67 { |
|
68 GSource source; /**< the parent GSource */ |
|
69 DBusConnection *connection; /**< the connection to dispatch */ |
|
70 } DBusGMessageQueue; |
|
71 |
|
72 static gboolean message_queue_prepare (GSource *source, |
|
73 gint *timeout); |
|
74 static gboolean message_queue_check (GSource *source); |
|
75 static gboolean message_queue_dispatch (GSource *source, |
|
76 GSourceFunc callback, |
|
77 gpointer user_data); |
|
78 |
|
79 static const GSourceFuncs message_queue_funcs = { |
|
80 message_queue_prepare, |
|
81 message_queue_check, |
|
82 message_queue_dispatch, |
|
83 NULL |
|
84 }; |
|
85 |
|
86 static gboolean |
|
87 message_queue_prepare (GSource *source, |
|
88 gint *timeout) |
|
89 { |
|
90 DBusConnection *connection = ((DBusGMessageQueue *)source)->connection; |
|
91 |
|
92 *timeout = -1; |
|
93 |
|
94 return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS); |
|
95 } |
|
96 |
|
97 static gboolean |
|
98 message_queue_check (GSource *source) |
|
99 { |
|
100 return FALSE; |
|
101 } |
|
102 |
|
103 static gboolean |
|
104 message_queue_dispatch (GSource *source, |
|
105 GSourceFunc callback, |
|
106 gpointer user_data) |
|
107 { |
|
108 DBusConnection *connection = ((DBusGMessageQueue *)source)->connection; |
|
109 |
|
110 dbus_connection_ref (connection); |
|
111 |
|
112 /* Only dispatch once - we don't want to starve other GSource */ |
|
113 dbus_connection_dispatch (connection); |
|
114 |
|
115 dbus_connection_unref (connection); |
|
116 |
|
117 return TRUE; |
|
118 } |
|
119 |
|
120 typedef struct |
|
121 { |
|
122 GMainContext *context; /**< the main context */ |
|
123 GSList *ios; /**< all IOHandler */ |
|
124 GSList *timeouts; /**< all TimeoutHandler */ |
|
125 DBusConnection *connection; /**< NULL if this is really for a server not a connection */ |
|
126 GSource *message_queue_source; /**< DBusGMessageQueue */ |
|
127 } ConnectionSetup; |
|
128 |
|
129 |
|
130 typedef struct |
|
131 { |
|
132 ConnectionSetup *cs; |
|
133 GSource *source; |
|
134 DBusWatch *watch; |
|
135 } IOHandler; |
|
136 |
|
137 typedef struct |
|
138 { |
|
139 ConnectionSetup *cs; |
|
140 GSource *source; |
|
141 DBusTimeout *timeout; |
|
142 } TimeoutHandler; |
|
143 |
|
144 |
|
145 #if EMULATOR |
|
146 GET_GLOBAL_VAR_FROM_TLS(_dbus_gmain_connection_slot,dbus_gmain,dbus_int32_t) |
|
147 #define _dbus_gmain_connection_slot (*GET_DBUS_WSD_VAR_NAME(_dbus_gmain_connection_slot,dbus_gmain,g)()) |
|
148 |
|
149 GET_STATIC_VAR_FROM_TLS(server_slot,dbus_gmain,dbus_int32_t) |
|
150 #define server_slot (*GET_DBUS_WSD_VAR_NAME(server_slot,dbus_gmain,s)()) |
|
151 |
|
152 #else |
|
153 |
|
154 dbus_int32_t _dbus_gmain_connection_slot = -1; |
|
155 |
|
156 static dbus_int32_t server_slot = -1; |
|
157 #endif |
|
158 |
|
159 |
|
160 |
|
161 static ConnectionSetup* |
|
162 connection_setup_new (GMainContext *context, |
|
163 DBusConnection *connection) |
|
164 { |
|
165 ConnectionSetup *cs; |
|
166 |
|
167 cs = g_new0 (ConnectionSetup, 1); |
|
168 |
|
169 g_assert (context != NULL); |
|
170 |
|
171 cs->context = context; |
|
172 g_main_context_ref (cs->context); |
|
173 |
|
174 if (connection) |
|
175 { |
|
176 cs->connection = connection; |
|
177 |
|
178 cs->message_queue_source = g_source_new ((GSourceFuncs *) &message_queue_funcs, |
|
179 sizeof (DBusGMessageQueue)); |
|
180 ((DBusGMessageQueue*)cs->message_queue_source)->connection = connection; |
|
181 g_source_attach (cs->message_queue_source, cs->context); |
|
182 } |
|
183 |
|
184 return cs; |
|
185 } |
|
186 |
|
187 static void |
|
188 io_handler_source_finalized (gpointer data) |
|
189 { |
|
190 IOHandler *handler; |
|
191 |
|
192 handler = data; |
|
193 |
|
194 if (handler->watch) |
|
195 dbus_watch_set_data (handler->watch, NULL, NULL); |
|
196 |
|
197 g_free (handler); |
|
198 } |
|
199 |
|
200 static void |
|
201 io_handler_destroy_source (void *data) |
|
202 { |
|
203 IOHandler *handler; |
|
204 |
|
205 handler = data; |
|
206 |
|
207 if (handler->source) |
|
208 { |
|
209 GSource *source = handler->source; |
|
210 handler->source = NULL; |
|
211 handler->cs->ios = g_slist_remove (handler->cs->ios, handler); |
|
212 g_source_destroy (source); |
|
213 g_source_unref (source); |
|
214 } |
|
215 } |
|
216 |
|
217 static void |
|
218 io_handler_watch_freed (void *data) |
|
219 { |
|
220 IOHandler *handler; |
|
221 |
|
222 handler = data; |
|
223 |
|
224 handler->watch = NULL; |
|
225 |
|
226 io_handler_destroy_source (handler); |
|
227 } |
|
228 |
|
229 static gboolean |
|
230 io_handler_dispatch (GIOChannel *source, |
|
231 GIOCondition condition, |
|
232 gpointer data) |
|
233 { |
|
234 IOHandler *handler; |
|
235 guint dbus_condition = 0; |
|
236 DBusConnection *connection; |
|
237 |
|
238 handler = data; |
|
239 |
|
240 connection = handler->cs->connection; |
|
241 |
|
242 if (connection) |
|
243 dbus_connection_ref (connection); |
|
244 |
|
245 if (condition & G_IO_IN) |
|
246 dbus_condition |= DBUS_WATCH_READABLE; |
|
247 if (condition & G_IO_OUT) |
|
248 dbus_condition |= DBUS_WATCH_WRITABLE; |
|
249 if (condition & G_IO_ERR) |
|
250 dbus_condition |= DBUS_WATCH_ERROR; |
|
251 if (condition & G_IO_HUP) |
|
252 dbus_condition |= DBUS_WATCH_HANGUP; |
|
253 |
|
254 /* Note that we don't touch the handler after this, because |
|
255 * dbus may have disabled the watch and thus killed the |
|
256 * handler. |
|
257 */ |
|
258 dbus_watch_handle (handler->watch, dbus_condition); |
|
259 handler = NULL; |
|
260 |
|
261 if (connection) |
|
262 dbus_connection_unref (connection); |
|
263 |
|
264 return TRUE; |
|
265 } |
|
266 |
|
267 static void |
|
268 connection_setup_add_watch (ConnectionSetup *cs, |
|
269 DBusWatch *watch) |
|
270 { |
|
271 guint flags; |
|
272 GIOCondition condition; |
|
273 GIOChannel *channel; |
|
274 IOHandler *handler; |
|
275 |
|
276 if (!dbus_watch_get_enabled (watch)) |
|
277 return; |
|
278 |
|
279 g_assert (dbus_watch_get_data (watch) == NULL); |
|
280 |
|
281 flags = dbus_watch_get_flags (watch); |
|
282 |
|
283 condition = G_IO_ERR | G_IO_HUP; |
|
284 if (flags & DBUS_WATCH_READABLE) |
|
285 condition |= G_IO_IN; |
|
286 if (flags & DBUS_WATCH_WRITABLE) |
|
287 condition |= G_IO_OUT; |
|
288 |
|
289 handler = g_new0 (IOHandler, 1); |
|
290 handler->cs = cs; |
|
291 handler->watch = watch; |
|
292 |
|
293 channel = g_io_channel_unix_new (dbus_watch_get_fd (watch)); |
|
294 |
|
295 handler->source = g_io_create_watch (channel, condition); |
|
296 g_source_set_callback (handler->source, (GSourceFunc) io_handler_dispatch, handler, |
|
297 io_handler_source_finalized); |
|
298 g_source_attach (handler->source, cs->context); |
|
299 |
|
300 cs->ios = g_slist_prepend (cs->ios, handler); |
|
301 |
|
302 dbus_watch_set_data (watch, handler, io_handler_watch_freed); |
|
303 g_io_channel_unref (channel); |
|
304 } |
|
305 |
|
306 static void |
|
307 connection_setup_remove_watch (ConnectionSetup *cs, |
|
308 DBusWatch *watch) |
|
309 { |
|
310 IOHandler *handler; |
|
311 |
|
312 handler = dbus_watch_get_data (watch); |
|
313 |
|
314 if (handler == NULL) |
|
315 return; |
|
316 |
|
317 io_handler_destroy_source (handler); |
|
318 } |
|
319 |
|
320 static void |
|
321 timeout_handler_source_finalized (gpointer data) |
|
322 { |
|
323 TimeoutHandler *handler; |
|
324 |
|
325 handler = data; |
|
326 |
|
327 if (handler->timeout) |
|
328 dbus_timeout_set_data (handler->timeout, NULL, NULL); |
|
329 |
|
330 g_free (handler); |
|
331 } |
|
332 |
|
333 static void |
|
334 timeout_handler_destroy_source (void *data) |
|
335 { |
|
336 TimeoutHandler *handler; |
|
337 |
|
338 handler = data; |
|
339 |
|
340 if (handler->source) |
|
341 { |
|
342 GSource *source = handler->source; |
|
343 handler->source = NULL; |
|
344 handler->cs->timeouts = g_slist_remove (handler->cs->timeouts, handler); |
|
345 g_source_destroy (source); |
|
346 g_source_unref (source); |
|
347 } |
|
348 } |
|
349 |
|
350 static void |
|
351 timeout_handler_timeout_freed (void *data) |
|
352 { |
|
353 TimeoutHandler *handler; |
|
354 |
|
355 handler = data; |
|
356 |
|
357 handler->timeout = NULL; |
|
358 |
|
359 timeout_handler_destroy_source (handler); |
|
360 } |
|
361 |
|
362 static gboolean |
|
363 timeout_handler_dispatch (gpointer data) |
|
364 { |
|
365 TimeoutHandler *handler; |
|
366 |
|
367 handler = data; |
|
368 |
|
369 dbus_timeout_handle (handler->timeout); |
|
370 |
|
371 return TRUE; |
|
372 } |
|
373 |
|
374 static void |
|
375 connection_setup_add_timeout (ConnectionSetup *cs, |
|
376 DBusTimeout *timeout) |
|
377 { |
|
378 TimeoutHandler *handler; |
|
379 |
|
380 if (!dbus_timeout_get_enabled (timeout)) |
|
381 return; |
|
382 |
|
383 g_assert (dbus_timeout_get_data (timeout) == NULL); |
|
384 |
|
385 handler = g_new0 (TimeoutHandler, 1); |
|
386 handler->cs = cs; |
|
387 handler->timeout = timeout; |
|
388 |
|
389 handler->source = g_timeout_source_new (dbus_timeout_get_interval (timeout)); |
|
390 g_source_set_callback (handler->source, timeout_handler_dispatch, handler, |
|
391 timeout_handler_source_finalized); |
|
392 g_source_attach (handler->source, handler->cs->context); |
|
393 |
|
394 cs->timeouts = g_slist_prepend (cs->timeouts, handler); |
|
395 |
|
396 dbus_timeout_set_data (timeout, handler, timeout_handler_timeout_freed); |
|
397 } |
|
398 |
|
399 static void |
|
400 connection_setup_remove_timeout (ConnectionSetup *cs, |
|
401 DBusTimeout *timeout) |
|
402 { |
|
403 TimeoutHandler *handler; |
|
404 |
|
405 handler = dbus_timeout_get_data (timeout); |
|
406 |
|
407 if (handler == NULL) |
|
408 return; |
|
409 |
|
410 timeout_handler_destroy_source (handler); |
|
411 } |
|
412 |
|
413 static void |
|
414 connection_setup_free (ConnectionSetup *cs) |
|
415 { |
|
416 while (cs->ios) |
|
417 io_handler_destroy_source (cs->ios->data); |
|
418 |
|
419 while (cs->timeouts) |
|
420 timeout_handler_destroy_source (cs->timeouts->data); |
|
421 |
|
422 if (cs->message_queue_source) |
|
423 { |
|
424 GSource *source; |
|
425 |
|
426 source = cs->message_queue_source; |
|
427 cs->message_queue_source = NULL; |
|
428 |
|
429 g_source_destroy (source); |
|
430 g_source_unref (source); |
|
431 } |
|
432 |
|
433 g_main_context_unref (cs->context); |
|
434 g_free (cs); |
|
435 } |
|
436 |
|
437 static dbus_bool_t |
|
438 add_watch (DBusWatch *watch, |
|
439 gpointer data) |
|
440 { |
|
441 ConnectionSetup *cs; |
|
442 |
|
443 cs = data; |
|
444 |
|
445 connection_setup_add_watch (cs, watch); |
|
446 |
|
447 return TRUE; |
|
448 } |
|
449 |
|
450 static void |
|
451 remove_watch (DBusWatch *watch, |
|
452 gpointer data) |
|
453 { |
|
454 ConnectionSetup *cs; |
|
455 |
|
456 cs = data; |
|
457 |
|
458 connection_setup_remove_watch (cs, watch); |
|
459 } |
|
460 |
|
461 static void |
|
462 watch_toggled (DBusWatch *watch, |
|
463 void *data) |
|
464 { |
|
465 /* Because we just exit on OOM, enable/disable is |
|
466 * no different from add/remove |
|
467 */ |
|
468 if (dbus_watch_get_enabled (watch)) |
|
469 add_watch (watch, data); |
|
470 else |
|
471 remove_watch (watch, data); |
|
472 } |
|
473 |
|
474 static dbus_bool_t |
|
475 add_timeout (DBusTimeout *timeout, |
|
476 void *data) |
|
477 { |
|
478 ConnectionSetup *cs; |
|
479 |
|
480 cs = data; |
|
481 |
|
482 if (!dbus_timeout_get_enabled (timeout)) |
|
483 return TRUE; |
|
484 |
|
485 connection_setup_add_timeout (cs, timeout); |
|
486 |
|
487 return TRUE; |
|
488 } |
|
489 |
|
490 static void |
|
491 remove_timeout (DBusTimeout *timeout, |
|
492 void *data) |
|
493 { |
|
494 ConnectionSetup *cs; |
|
495 |
|
496 cs = data; |
|
497 |
|
498 connection_setup_remove_timeout (cs, timeout); |
|
499 } |
|
500 |
|
501 static void |
|
502 timeout_toggled (DBusTimeout *timeout, |
|
503 void *data) |
|
504 { |
|
505 /* Because we just exit on OOM, enable/disable is |
|
506 * no different from add/remove |
|
507 */ |
|
508 if (dbus_timeout_get_enabled (timeout)) |
|
509 add_timeout (timeout, data); |
|
510 else |
|
511 remove_timeout (timeout, data); |
|
512 } |
|
513 |
|
514 static void |
|
515 wakeup_main (void *data) |
|
516 { |
|
517 ConnectionSetup *cs = data; |
|
518 |
|
519 g_main_context_wakeup (cs->context); |
|
520 } |
|
521 |
|
522 |
|
523 /* Move to a new context */ |
|
524 static ConnectionSetup* |
|
525 connection_setup_new_from_old (GMainContext *context, |
|
526 ConnectionSetup *old) |
|
527 { |
|
528 GSList *tmp; |
|
529 ConnectionSetup *cs; |
|
530 |
|
531 g_assert (old->context != context); |
|
532 |
|
533 cs = connection_setup_new (context, old->connection); |
|
534 |
|
535 tmp = old->ios; |
|
536 while (tmp != NULL) |
|
537 { |
|
538 IOHandler *handler = tmp->data; |
|
539 |
|
540 connection_setup_add_watch (cs, handler->watch); |
|
541 |
|
542 tmp = tmp->next; |
|
543 } |
|
544 |
|
545 tmp = old->timeouts; |
|
546 while (tmp != NULL) |
|
547 { |
|
548 TimeoutHandler *handler = tmp->data; |
|
549 |
|
550 connection_setup_add_timeout (cs, handler->timeout); |
|
551 |
|
552 tmp = tmp->next; |
|
553 } |
|
554 |
|
555 return cs; |
|
556 } |
|
557 |
|
558 /** @} */ /* End of GLib bindings internals */ |
|
559 |
|
560 /** @addtogroup DBusGLib |
|
561 * @{ |
|
562 */ |
|
563 |
|
564 /** |
|
565 * dbus_connection_setup_with_g_main: |
|
566 * @connection: the connection |
|
567 * @context: the #GMainContext or #NULL for default context |
|
568 * |
|
569 * Sets the watch and timeout functions of a #DBusConnection |
|
570 * to integrate the connection with the GLib main loop. |
|
571 * Pass in #NULL for the #GMainContext unless you're |
|
572 * doing something specialized. |
|
573 * |
|
574 * If called twice for the same context, does nothing the second |
|
575 * time. If called once with context A and once with context B, |
|
576 * context B replaces context A as the context monitoring the |
|
577 * connection. |
|
578 */ |
|
579 #ifdef __SYMBIAN32__ |
|
580 EXPORT_C |
|
581 #endif |
|
582 void |
|
583 dbus_connection_setup_with_g_main (DBusConnection *connection, |
|
584 GMainContext *context) |
|
585 { |
|
586 ConnectionSetup *old_setup; |
|
587 ConnectionSetup *cs; |
|
588 |
|
589 /* FIXME we never free the slot, so its refcount just keeps growing, |
|
590 * which is kind of broken. |
|
591 */ |
|
592 dbus_connection_allocate_data_slot (&_dbus_gmain_connection_slot); |
|
593 if (_dbus_gmain_connection_slot < 0) |
|
594 goto nomem; |
|
595 |
|
596 if (context == NULL) |
|
597 context = g_main_context_default (); |
|
598 |
|
599 cs = NULL; |
|
600 |
|
601 old_setup = dbus_connection_get_data (connection, _dbus_gmain_connection_slot); |
|
602 if (old_setup != NULL) |
|
603 { |
|
604 if (old_setup->context == context) |
|
605 return; /* nothing to do */ |
|
606 |
|
607 cs = connection_setup_new_from_old (context, old_setup); |
|
608 |
|
609 /* Nuke the old setup */ |
|
610 dbus_connection_set_data (connection, _dbus_gmain_connection_slot, NULL, NULL); |
|
611 old_setup = NULL; |
|
612 } |
|
613 |
|
614 if (cs == NULL) |
|
615 cs = connection_setup_new (context, connection); |
|
616 |
|
617 if (!dbus_connection_set_data (connection, _dbus_gmain_connection_slot, cs, |
|
618 (DBusFreeFunction)connection_setup_free)) |
|
619 goto nomem; |
|
620 |
|
621 if (!dbus_connection_set_watch_functions (connection, |
|
622 add_watch, |
|
623 remove_watch, |
|
624 watch_toggled, |
|
625 cs, NULL)) |
|
626 goto nomem; |
|
627 |
|
628 if (!dbus_connection_set_timeout_functions (connection, |
|
629 add_timeout, |
|
630 remove_timeout, |
|
631 timeout_toggled, |
|
632 cs, NULL)) |
|
633 goto nomem; |
|
634 |
|
635 dbus_connection_set_wakeup_main_function (connection, |
|
636 wakeup_main, |
|
637 cs, NULL); |
|
638 |
|
639 return; |
|
640 |
|
641 nomem: |
|
642 g_error ("Not enough memory to set up DBusConnection for use with GLib"); |
|
643 } |
|
644 |
|
645 /** |
|
646 * dbus_server_setup_with_g_main: |
|
647 * @server: the server |
|
648 * @context: the #GMainContext or #NULL for default |
|
649 * |
|
650 * Sets the watch and timeout functions of a #DBusServer |
|
651 * to integrate the server with the GLib main loop. |
|
652 * In most cases the context argument should be #NULL. |
|
653 * |
|
654 * If called twice for the same context, does nothing the second |
|
655 * time. If called once with context A and once with context B, |
|
656 * context B replaces context A as the context monitoring the |
|
657 * connection. |
|
658 */ |
|
659 #ifdef __SYMBIAN32__ |
|
660 EXPORT_C |
|
661 #endif |
|
662 void |
|
663 dbus_server_setup_with_g_main (DBusServer *server, |
|
664 GMainContext *context) |
|
665 { |
|
666 ConnectionSetup *old_setup; |
|
667 ConnectionSetup *cs; |
|
668 |
|
669 /* FIXME we never free the slot, so its refcount just keeps growing, |
|
670 * which is kind of broken. |
|
671 */ |
|
672 dbus_server_allocate_data_slot (&server_slot); |
|
673 if (server_slot < 0) |
|
674 goto nomem; |
|
675 |
|
676 if (context == NULL) |
|
677 context = g_main_context_default (); |
|
678 |
|
679 cs = NULL; |
|
680 |
|
681 old_setup = dbus_server_get_data (server, server_slot); |
|
682 if (old_setup != NULL) |
|
683 { |
|
684 if (old_setup->context == context) |
|
685 return; /* nothing to do */ |
|
686 |
|
687 cs = connection_setup_new_from_old (context, old_setup); |
|
688 |
|
689 /* Nuke the old setup */ |
|
690 dbus_server_set_data (server, server_slot, NULL, NULL); |
|
691 old_setup = NULL; |
|
692 } |
|
693 |
|
694 if (cs == NULL) |
|
695 cs = connection_setup_new (context, NULL); |
|
696 |
|
697 if (!dbus_server_set_data (server, server_slot, cs, |
|
698 (DBusFreeFunction)connection_setup_free)) |
|
699 goto nomem; |
|
700 |
|
701 if (!dbus_server_set_watch_functions (server, |
|
702 add_watch, |
|
703 remove_watch, |
|
704 watch_toggled, |
|
705 cs, NULL)) |
|
706 goto nomem; |
|
707 |
|
708 if (!dbus_server_set_timeout_functions (server, |
|
709 add_timeout, |
|
710 remove_timeout, |
|
711 timeout_toggled, |
|
712 cs, NULL)) |
|
713 goto nomem; |
|
714 |
|
715 return; |
|
716 |
|
717 nomem: |
|
718 g_error ("Not enough memory to set up DBusServer for use with GLib"); |
|
719 } |
|
720 |
|
721 /** |
|
722 * dbus_g_connection_open: |
|
723 * @address: address of the connection to open |
|
724 * @error: address where an error can be returned. |
|
725 * |
|
726 * Returns a connection to the given address. |
|
727 * |
|
728 * (Internally, calls dbus_connection_open() then calls |
|
729 * dbus_connection_setup_with_g_main() on the result.) |
|
730 * |
|
731 * Returns: a DBusConnection |
|
732 */ |
|
733 #ifdef __SYMBIAN32__ |
|
734 EXPORT_C |
|
735 #endif |
|
736 DBusGConnection* |
|
737 dbus_g_connection_open (const gchar *address, |
|
738 GError **error) |
|
739 { |
|
740 DBusConnection *connection; |
|
741 DBusError derror; |
|
742 |
|
743 g_return_val_if_fail (error == NULL || *error == NULL, NULL); |
|
744 |
|
745 _dbus_g_value_types_init (); |
|
746 |
|
747 dbus_error_init (&derror); |
|
748 |
|
749 connection = dbus_connection_open (address, &derror); |
|
750 if (connection == NULL) |
|
751 { |
|
752 dbus_set_g_error (error, &derror); |
|
753 dbus_error_free (&derror); |
|
754 return NULL; |
|
755 } |
|
756 |
|
757 /* does nothing if it's already been done */ |
|
758 dbus_connection_setup_with_g_main (connection, NULL); |
|
759 |
|
760 return DBUS_G_CONNECTION_FROM_CONNECTION (connection); |
|
761 } |
|
762 |
|
763 /** |
|
764 * dbus_g_bus_get: |
|
765 * @type: bus type |
|
766 * @error: address where an error can be returned. |
|
767 * |
|
768 * Returns a connection to the given bus. The connection is a global variable |
|
769 * shared with other callers of this function. |
|
770 * |
|
771 * (Internally, calls dbus_bus_get() then calls |
|
772 * dbus_connection_setup_with_g_main() on the result.) |
|
773 * |
|
774 * Returns: a DBusConnection |
|
775 */ |
|
776 #ifdef __SYMBIAN32__ |
|
777 EXPORT_C |
|
778 #endif |
|
779 DBusGConnection* |
|
780 dbus_g_bus_get (DBusBusType type, |
|
781 GError **error) |
|
782 { |
|
783 DBusConnection *connection; |
|
784 DBusError derror; |
|
785 |
|
786 g_return_val_if_fail (error == NULL || *error == NULL, NULL); |
|
787 |
|
788 _dbus_g_value_types_init (); |
|
789 |
|
790 dbus_error_init (&derror); |
|
791 |
|
792 connection = dbus_bus_get (type, &derror); |
|
793 if (connection == NULL) |
|
794 { |
|
795 dbus_set_g_error (error, &derror); |
|
796 dbus_error_free (&derror); |
|
797 return NULL; |
|
798 } |
|
799 |
|
800 /* does nothing if it's already been done */ |
|
801 dbus_connection_setup_with_g_main (connection, NULL); |
|
802 |
|
803 return DBUS_G_CONNECTION_FROM_CONNECTION (connection); |
|
804 } |
|
805 |
|
806 /** @} */ /* end of public API */ |
|
807 |
|
808 #ifdef DBUS_BUILD_TESTS |
|
809 |
|
810 /** |
|
811 * @ingroup DBusGLibInternals |
|
812 * Unit test for GLib main loop integration |
|
813 * Returns: #TRUE on success. |
|
814 */ |
|
815 #ifdef __SYMBIAN32__ |
|
816 EXPORT_C |
|
817 #endif |
|
818 gboolean |
|
819 _dbus_gmain_test (const char *test_data_dir) |
|
820 { |
|
821 GType type; |
|
822 GType rectype; |
|
823 |
|
824 g_type_init (); |
|
825 _dbus_g_value_types_init (); |
|
826 |
|
827 rectype = dbus_g_type_get_collection ("GArray", G_TYPE_UINT); |
|
828 g_assert (rectype != G_TYPE_INVALID); |
|
829 g_assert (!strcmp (g_type_name (rectype), "GArray_guint_")); |
|
830 |
|
831 type = _dbus_gtype_from_signature ("au", TRUE); |
|
832 g_assert (type == rectype); |
|
833 |
|
834 rectype = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING); |
|
835 g_assert (rectype != G_TYPE_INVALID); |
|
836 g_assert (!strcmp (g_type_name (rectype), "GHashTable_gchararray+gchararray_")); |
|
837 |
|
838 type = _dbus_gtype_from_signature ("a{ss}", TRUE); |
|
839 g_assert (type == rectype); |
|
840 |
|
841 type = _dbus_gtype_from_signature ("o", FALSE); |
|
842 g_assert (type == DBUS_TYPE_G_OBJECT_PATH); |
|
843 type = _dbus_gtype_from_signature ("o", TRUE); |
|
844 g_assert (type == DBUS_TYPE_G_OBJECT_PATH); |
|
845 |
|
846 return TRUE; |
|
847 } |
|
848 |
|
849 #endif /* DBUS_BUILD_TESTS */ |