00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include <config.h>
00025
#include <dbus/dbus-glib.h>
00026
#include <dbus/dbus-glib-lowlevel.h>
00027
#include "dbus-gtest.h"
00028
#include "dbus-gutils.h"
00029
00030
#include <libintl.h>
00031
#define _(x) dgettext (GETTEXT_PACKAGE, x)
00032
#define N_(x) x
00033
00056 typedef struct DBusGSource DBusGSource;
00057
00061 struct DBusGSource
00062 {
00063 GSource
source;
00065 GList *
watch_fds;
00067 GMainContext *
context;
00069 void *
connection_or_server;
00070 };
00071
00076 typedef struct
00077
{
00078 int refcount;
00080 GPollFD poll_fd;
00081 DBusWatch *watch;
00083 unsigned int removed : 1;
00084 }
WatchFD;
00085
00086
static WatchFD *
00087 watch_fd_new (
void)
00088 {
00089
WatchFD *watch_fd;
00090
00091 watch_fd = g_new0 (
WatchFD, 1);
00092 watch_fd->
refcount = 1;
00093
00094
return watch_fd;
00095 }
00096
00097
static WatchFD *
00098 watch_fd_ref (
WatchFD *watch_fd)
00099 {
00100 watch_fd->
refcount += 1;
00101
00102
return watch_fd;
00103 }
00104
00105
static void
00106 watch_fd_unref (
WatchFD *watch_fd)
00107 {
00108 watch_fd->
refcount -= 1;
00109
00110
if (watch_fd->
refcount == 0)
00111 {
00112 g_assert (watch_fd->
removed);
00113
00114 g_free (watch_fd);
00115 }
00116 }
00117
00118
static dbus_int32_t connection_slot = -1;
00119
static dbus_int32_t server_slot = -1;
00120
00121
static gboolean gsource_connection_prepare (GSource *source,
00122 gint *timeout);
00123
static gboolean gsource_connection_check (GSource *source);
00124
static gboolean gsource_connection_dispatch (GSource *source,
00125 GSourceFunc callback,
00126 gpointer user_data);
00127
static gboolean gsource_server_prepare (GSource *source,
00128 gint *timeout);
00129
static gboolean gsource_server_check (GSource *source);
00130
static gboolean gsource_server_dispatch (GSource *source,
00131 GSourceFunc callback,
00132 gpointer user_data);
00133
00134
static GSourceFuncs dbus_connection_funcs = {
00135 gsource_connection_prepare,
00136 gsource_connection_check,
00137 gsource_connection_dispatch,
00138
NULL
00139 };
00140
00141
static GSourceFuncs dbus_server_funcs = {
00142 gsource_server_prepare,
00143 gsource_server_check,
00144 gsource_server_dispatch,
00145
NULL
00146 };
00147
00148
static gboolean
00149 gsource_connection_prepare (GSource *source,
00150 gint *timeout)
00151 {
00152
DBusConnection *connection = ((
DBusGSource *)source)->connection_or_server;
00153
00154 *timeout = -1;
00155
00156
return (
dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS);
00157 }
00158
00159
static gboolean
00160 gsource_server_prepare (GSource *source,
00161 gint *timeout)
00162 {
00163 *timeout = -1;
00164
00165
return FALSE;
00166 }
00167
00168
static gboolean
00169 dbus_gsource_check (GSource *source)
00170 {
00171
DBusGSource *dbus_source = (
DBusGSource *)source;
00172 GList *list;
00173
00174 list = dbus_source->
watch_fds;
00175
00176
while (list)
00177 {
00178
WatchFD *watch_fd = list->data;
00179
00180
if (watch_fd->
poll_fd.revents != 0)
00181
return TRUE;
00182
00183 list = list->next;
00184 }
00185
00186
return FALSE;
00187 }
00188
00189
static gboolean
00190 gsource_connection_check (GSource *source)
00191 {
00192
return dbus_gsource_check (source);
00193 }
00194
00195
static gboolean
00196 gsource_server_check (GSource *source)
00197 {
00198
return dbus_gsource_check (source);
00199 }
00200
00201
static gboolean
00202 dbus_gsource_dispatch (GSource *source,
00203 GSourceFunc callback,
00204 gpointer user_data,
00205 dbus_bool_t is_server)
00206 {
00207
DBusGSource *dbus_source = (
DBusGSource *)source;
00208 GList *copy, *list;
00209
00210
00211 copy = g_list_copy (dbus_source->
watch_fds);
00212 g_list_foreach (copy, (GFunc)watch_fd_ref, NULL);
00213
00214 list = copy;
00215
while (list)
00216 {
00217
WatchFD *watch_fd = list->data;
00218
00219
if (!watch_fd->
removed && watch_fd->
poll_fd.revents != 0)
00220 {
00221 guint condition = 0;
00222
00223
if (watch_fd->
poll_fd.revents & G_IO_IN)
00224 condition |= DBUS_WATCH_READABLE;
00225
if (watch_fd->
poll_fd.revents & G_IO_OUT)
00226 condition |= DBUS_WATCH_WRITABLE;
00227
if (watch_fd->
poll_fd.revents & G_IO_ERR)
00228 condition |= DBUS_WATCH_ERROR;
00229
if (watch_fd->
poll_fd.revents & G_IO_HUP)
00230 condition |= DBUS_WATCH_HANGUP;
00231
00232
dbus_watch_handle (watch_fd->
watch, condition);
00233 }
00234
00235 list = list->next;
00236 }
00237
00238 g_list_foreach (copy, (GFunc)watch_fd_unref, NULL);
00239 g_list_free (copy);
00240
00241
return TRUE;
00242 }
00243
00244
static gboolean
00245 gsource_connection_dispatch (GSource *source,
00246 GSourceFunc callback,
00247 gpointer user_data)
00248 {
00249
DBusGSource *dbus_source = (
DBusGSource *)source;
00250
DBusConnection *connection = dbus_source->
connection_or_server;
00251
00252
dbus_connection_ref (connection);
00253
00254 dbus_gsource_dispatch (source, callback, user_data,
00255 FALSE);
00256
00257
00258
while (
dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS)
00259 ;
00260
00261
dbus_connection_unref (connection);
00262
00263
return TRUE;
00264 }
00265
00266
static gboolean
00267 gsource_server_dispatch (GSource *source,
00268 GSourceFunc callback,
00269 gpointer user_data)
00270 {
00271
DBusGSource *dbus_source = (
DBusGSource *)source;
00272
DBusServer *server = dbus_source->
connection_or_server;
00273
00274
dbus_server_ref (server);
00275
00276 dbus_gsource_dispatch (source, callback, user_data,
00277 TRUE);
00278
00279
dbus_server_unref (server);
00280
00281
return TRUE;
00282 }
00283
00284
static dbus_bool_t
00285 add_watch (
DBusWatch *watch,
00286 gpointer data)
00287 {
00288
WatchFD *watch_fd;
00289
DBusGSource *dbus_source;
00290 guint flags;
00291
00292
if (!
dbus_watch_get_enabled (watch))
00293
return TRUE;
00294
00295 dbus_source = data;
00296
00297 watch_fd = watch_fd_new ();
00298 watch_fd->
poll_fd.fd =
dbus_watch_get_fd (watch);
00299 watch_fd->
poll_fd.events = 0;
00300 flags =
dbus_watch_get_flags (watch);
00301
dbus_watch_set_data (watch, watch_fd, (DBusFreeFunction)watch_fd_unref);
00302
00303
if (flags & DBUS_WATCH_READABLE)
00304 watch_fd->
poll_fd.events |= G_IO_IN;
00305
if (flags & DBUS_WATCH_WRITABLE)
00306 watch_fd->
poll_fd.events |= G_IO_OUT;
00307 watch_fd->
poll_fd.events |= G_IO_ERR | G_IO_HUP;
00308
00309 watch_fd->
watch = watch;
00310
00311 g_source_add_poll ((GSource *)dbus_source, &watch_fd->
poll_fd);
00312
00313 dbus_source->
watch_fds = g_list_prepend (dbus_source->
watch_fds, watch_fd);
00314
00315
return TRUE;
00316 }
00317
00318
static void
00319 remove_watch (
DBusWatch *watch,
00320 gpointer data)
00321 {
00322
DBusGSource *dbus_source = data;
00323
WatchFD *watch_fd;
00324
00325 watch_fd =
dbus_watch_get_data (watch);
00326
if (watch_fd ==
NULL)
00327
return;
00328
00329 watch_fd->
removed =
TRUE;
00330 watch_fd->
watch =
NULL;
00331
00332 dbus_source->
watch_fds = g_list_remove (dbus_source->
watch_fds, watch_fd);
00333
00334 g_source_remove_poll ((GSource *)dbus_source, &watch_fd->
poll_fd);
00335
00336
dbus_watch_set_data (watch, NULL, NULL);
00337
00338
00339 }
00340
00341
static void
00342 watch_toggled (
DBusWatch *watch,
00343
void *data)
00344 {
00345
00346
00347
00348
if (
dbus_watch_get_enabled (watch))
00349 add_watch (watch, data);
00350
else
00351 remove_watch (watch, data);
00352 }
00353
00354
static gboolean
00355 timeout_handler (gpointer data)
00356 {
00357
DBusTimeout *timeout = data;
00358
00359
dbus_timeout_handle (timeout);
00360
00361
return TRUE;
00362 }
00363
00364
static dbus_bool_t
00365 add_timeout (
DBusTimeout *timeout,
00366
void *data)
00367 {
00368
DBusGSource *dbus_source = data;
00369 GSource *source;
00370
00371
if (!
dbus_timeout_get_enabled (timeout))
00372
return TRUE;
00373
00374 source = g_timeout_source_new (dbus_timeout_get_interval (timeout));
00375 g_source_set_callback (source, timeout_handler, timeout, NULL);
00376 g_source_attach (source, dbus_source->
context);
00377
00378
dbus_timeout_set_data (timeout, GUINT_TO_POINTER (g_source_get_id (source)),
00379 NULL);
00380
00381
return TRUE;
00382 }
00383
00384
static void
00385 remove_timeout (
DBusTimeout *timeout,
00386
void *data)
00387 {
00388 guint timeout_tag;
00389
00390 timeout_tag = GPOINTER_TO_UINT (dbus_timeout_get_data (timeout));
00391
00392
if (timeout_tag != 0)
00393 g_source_remove (timeout_tag);
00394 }
00395
00396
static void
00397 timeout_toggled (
DBusTimeout *timeout,
00398
void *data)
00399 {
00400
00401
00402
00403
if (
dbus_timeout_get_enabled (timeout))
00404 add_timeout (timeout, data);
00405
else
00406 remove_timeout (timeout, data);
00407 }
00408
00409
00410
static void
00411 free_source (GSource *source)
00412 {
00413 g_source_destroy (source);
00414 }
00415
00416
static void
00417 wakeup_main (
void *data)
00418 {
00419
DBusGSource *dbus_source = data;
00420
00421 g_main_context_wakeup (dbus_source->
context);
00422 }
00423
00424
00426
00431
static GSource*
00432 create_source (
void *connection_or_server,
00433 GSourceFuncs *funcs,
00434 GMainContext *context)
00435 {
00436 GSource *source;
00437
DBusGSource *dbus_source;
00438
00439 source = g_source_new (funcs,
sizeof (DBusGSource));
00440
00441 dbus_source = (
DBusGSource *)source;
00442 dbus_source->
connection_or_server = connection_or_server;
00443 dbus_source->
context = context;
00444
00445
return source;
00446 }
00447
00462
void
00463 dbus_connection_setup_with_g_main (
DBusConnection *connection,
00464 GMainContext *context)
00465 {
00466 GSource *source;
00467
00468
00469
00470
00471
dbus_connection_allocate_data_slot (&connection_slot);
00472
if (connection_slot < 0)
00473
goto nomem;
00474
00475
00476
if (context ==
NULL)
00477 context = g_main_context_default ();
00478
00479 source =
dbus_connection_get_data (connection, connection_slot);
00480
if (source !=
NULL)
00481 {
00482
if (source->context == context)
00483
return;
00484
00485
00486
dbus_connection_set_data (connection, connection_slot,
NULL,
NULL);
00487 source =
NULL;
00488 }
00489
00490 source = create_source (connection, &dbus_connection_funcs, context);
00491
00492
if (!
dbus_connection_set_watch_functions (connection,
00493 add_watch,
00494 remove_watch,
00495 watch_toggled,
00496 source,
NULL))
00497
goto nomem;
00498
00499
if (!
dbus_connection_set_timeout_functions (connection,
00500 add_timeout,
00501 remove_timeout,
00502 timeout_toggled,
00503 source,
NULL))
00504
goto nomem;
00505
00506
dbus_connection_set_wakeup_main_function (connection,
00507 wakeup_main,
00508 source,
NULL);
00509
00510 g_source_attach (source, context);
00511
00512
if (!
dbus_connection_set_data (connection, connection_slot, source,
00513 (
DBusFreeFunction)free_source))
00514
goto nomem;
00515
00516
return;
00517
00518 nomem:
00519 g_error (
"Not enough memory to set up DBusConnection for use with GLib");
00520 }
00521
00535
void
00536 dbus_server_setup_with_g_main (
DBusServer *server,
00537 GMainContext *context)
00538 {
00539 GSource *source;
00540
00541
dbus_server_allocate_data_slot (&server_slot);
00542
if (server_slot < 0)
00543
goto nomem;
00544
00545
00546
if (context ==
NULL)
00547 context = g_main_context_default ();
00548
00549 source =
dbus_server_get_data (server, server_slot);
00550
if (source !=
NULL)
00551 {
00552
if (source->context == context)
00553
return;
00554
00555
00556
dbus_server_set_data (server, server_slot,
NULL,
NULL);
00557 source =
NULL;
00558 }
00559
00560 source = create_source (server, &dbus_server_funcs, context);
00561
00562
dbus_server_set_watch_functions (server,
00563 add_watch,
00564 remove_watch,
00565 watch_toggled,
00566 source,
NULL);
00567
00568
dbus_server_set_timeout_functions (server,
00569 add_timeout,
00570 remove_timeout,
00571 timeout_toggled,
00572
NULL,
NULL);
00573
00574 g_source_attach (source, context);
00575
00576
if (!
dbus_server_set_data (server, server_slot, source,
00577 (
DBusFreeFunction)free_source))
00578
goto nomem;
00579
00580
return;
00581
00582 nomem:
00583 g_error (
"Not enough memory to set up DBusServer for use with GLib");
00584 }
00585
00597 DBusGConnection*
00598 dbus_g_bus_get (DBusBusType type,
00599 GError **error)
00600 {
00601
DBusConnection *connection;
00602
DBusError derror;
00603
00604 g_return_val_if_fail (error ==
NULL || *error ==
NULL,
NULL);
00605
00606
dbus_error_init (&derror);
00607
00608 connection =
dbus_bus_get (type, &derror);
00609
if (connection ==
NULL)
00610 {
00611
dbus_set_g_error (error, &derror);
00612
dbus_error_free (&derror);
00613 }
00614
else
00615 {
00616
00617
dbus_connection_setup_with_g_main (connection,
NULL);
00618 }
00619
00620
return DBUS_G_CONNECTION_FROM_CONNECTION (connection);
00621 }
00622
00629 GQuark
00630 dbus_g_error_quark (
void)
00631 {
00632
static GQuark quark = 0;
00633
if (quark == 0)
00634 quark = g_quark_from_static_string (
"g-exec-error-quark");
00635
return quark;
00636 }
00637
00638
00647
void
00648 dbus_set_g_error (GError **gerror,
00649
DBusError *derror)
00650 {
00651 g_return_if_fail (derror !=
NULL);
00652 g_return_if_fail (
dbus_error_is_set (derror));
00653
00654 g_set_error (gerror, DBUS_GERROR,
00655 DBUS_GERROR_FAILED,
00656 _(
"D-BUS error %s: %s"),
00657 derror->name, derror->message);
00658 }
00659
00665 GType
00666 dbus_connection_get_g_type (
void)
00667 {
00668
static GType our_type = 0;
00669
00670
if (our_type == 0)
00671 our_type = g_boxed_type_register_static (
"DBusConnection",
00672 (GBoxedCopyFunc)
dbus_connection_ref,
00673 (GBoxedFreeFunc)
dbus_connection_unref);
00674
00675
return our_type;
00676 }
00677
00683 GType
00684 dbus_message_get_g_type (
void)
00685 {
00686
static GType our_type = 0;
00687
00688
if (our_type == 0)
00689 our_type = g_boxed_type_register_static (
"DBusMessage",
00690 (GBoxedCopyFunc)
dbus_message_ref,
00691 (GBoxedFreeFunc)
dbus_message_unref);
00692
00693
return our_type;
00694 }
00695
00696
static DBusGConnection*
00697 dbus_g_connection_ref (DBusGConnection *gconnection)
00698 {
00699
DBusConnection *c;
00700
00701 c = DBUS_CONNECTION_FROM_G_CONNECTION (gconnection);
00702
dbus_connection_ref (c);
00703
return gconnection;
00704 }
00705
00706
static void
00707 dbus_g_connection_unref (DBusGConnection *gconnection)
00708 {
00709
DBusConnection *c;
00710
00711 c = DBUS_CONNECTION_FROM_G_CONNECTION (gconnection);
00712
dbus_connection_unref (c);
00713 }
00714
00715
00716
static DBusGMessage*
00717 dbus_g_message_ref (DBusGMessage *gmessage)
00718 {
00719
DBusMessage *c;
00720
00721 c = DBUS_MESSAGE_FROM_G_MESSAGE (gmessage);
00722
dbus_message_ref (c);
00723
return gmessage;
00724 }
00725
00726
static void
00727 dbus_g_message_unref (DBusGMessage *gmessage)
00728 {
00729
DBusMessage *c;
00730
00731 c = DBUS_MESSAGE_FROM_G_MESSAGE (gmessage);
00732
dbus_message_unref (c);
00733 }
00734
00740 GType
00741 dbus_g_connection_get_g_type (
void)
00742 {
00743
static GType our_type = 0;
00744
00745
if (our_type == 0)
00746 our_type = g_boxed_type_register_static (
"DBusGConnection",
00747 (GBoxedCopyFunc) dbus_g_connection_ref,
00748 (GBoxedFreeFunc) dbus_g_connection_unref);
00749
00750
return our_type;
00751 }
00752
00758 GType
00759 dbus_g_message_get_g_type (
void)
00760 {
00761
static GType our_type = 0;
00762
00763
if (our_type == 0)
00764 our_type = g_boxed_type_register_static (
"DBusGMessage",
00765 (GBoxedCopyFunc) dbus_g_message_ref,
00766 (GBoxedFreeFunc) dbus_g_message_unref);
00767
00768
return our_type;
00769 }
00770
00777
DBusConnection*
00778 dbus_g_connection_get_connection (DBusGConnection *gconnection)
00779 {
00780
return DBUS_CONNECTION_FROM_G_CONNECTION (gconnection);
00781 }
00782
00789
DBusMessage*
00790 dbus_g_message_get_message (DBusGMessage *gmessage)
00791 {
00792
return DBUS_MESSAGE_FROM_G_MESSAGE (gmessage);
00793 }
00794
00796
00797
#ifdef DBUS_BUILD_TESTS
00798
00804 gboolean
00805 _dbus_gmain_test (
const char *test_data_dir)
00806 {
00807
00808
return TRUE;
00809 }
00810
00811
#endif