42
40
#define error(fmt...)
43
41
#define debug(fmt...)
43
struct timeout_handler {
47
45
DBusTimeout *timeout;
50
48
struct watch_info {
53
51
DBusConnection *conn;
62
54
struct disconnect_data {
63
GDBusWatchFunction disconnect_cb;
55
GDBusWatchFunction function;
67
static DBusHandlerResult disconnect_filter(DBusConnection *conn,
59
static gboolean disconnected_signal(DBusConnection *conn,
68
60
DBusMessage *msg, void *data)
70
62
struct disconnect_data *dc_data = data;
72
if (dbus_message_is_signal(msg,
73
DBUS_INTERFACE_LOCAL, "Disconnected") == TRUE) {
74
error("Got disconnected from the system message bus");
75
dc_data->disconnect_cb(conn, dc_data->user_data);
76
dbus_connection_unref(conn);
79
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
64
error("Got disconnected from the system message bus");
66
dc_data->function(conn, dc_data->user_data);
68
dbus_connection_unref(conn);
82
static gboolean message_dispatch_cb(void *data)
73
static gboolean message_dispatch(void *data)
84
DBusConnection *connection = data;
75
DBusConnection *conn = data;
86
dbus_connection_ref(connection);
77
dbus_connection_ref(conn);
88
79
/* Dispatch messages */
89
while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
80
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
91
dbus_connection_unref(connection);
82
dbus_connection_unref(conn);
87
static inline void queue_dispatch(DBusConnection *conn,
88
DBusDispatchStatus status)
90
if (status == DBUS_DISPATCH_DATA_REMAINS)
91
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
96
94
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
98
DBusWatch *watch = data;
99
struct watch_info *info = dbus_watch_get_data(watch);
96
struct watch_info *info = data;
97
unsigned int flags = 0;
99
dbus_connection_ref(info->conn);
102
101
if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE;
103
102
if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
104
103
if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
105
104
if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
107
dbus_watch_handle(watch, flags);
106
dbus_watch_handle(info->watch, flags);
109
if (dbus_connection_get_dispatch_status(info->conn) == DBUS_DISPATCH_DATA_REMAINS)
110
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch_cb, info->conn);
108
dbus_connection_unref(info->conn);
113
static void watch_info_free(void *data)
115
struct watch_info *info = data;
118
g_source_remove(info->id);
122
dbus_connection_unref(info->conn);
115
127
static dbus_bool_t add_watch(DBusWatch *watch, void *data)
129
DBusConnection *conn = data;
117
130
GIOCondition cond = G_IO_HUP | G_IO_ERR;
118
DBusConnection *conn = data;
119
132
struct watch_info *info;
122
136
if (!dbus_watch_get_enabled(watch))
125
info = g_new(struct watch_info, 1);
139
info = g_new0(struct watch_info, 1);
127
141
fd = dbus_watch_get_unix_fd(watch);
128
info->io = g_io_channel_unix_new(fd);
142
chan = g_io_channel_unix_new(fd);
129
145
info->conn = dbus_connection_ref(conn);
131
dbus_watch_set_data(watch, info, NULL);
147
dbus_watch_set_data(watch, info, watch_info_free);
133
149
flags = dbus_watch_get_flags(watch);
135
151
if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
136
152
if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;
138
info->watch_id = g_io_add_watch(info->io, cond, watch_func, watch);
154
info->id = g_io_add_watch(chan, cond, watch_func, info);
156
g_io_channel_unref(chan);
143
161
static void remove_watch(DBusWatch *watch, void *data)
145
struct watch_info *info = dbus_watch_get_data(watch);
163
if (dbus_watch_get_enabled(watch))
166
/* will trigger watch_info_free() */
147
167
dbus_watch_set_data(watch, NULL, NULL);
150
g_source_remove(info->watch_id);
151
g_io_channel_unref(info->io);
152
dbus_connection_unref(info->conn);
157
170
static void watch_toggled(DBusWatch *watch, void *data)
194
207
static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
196
timeout_handler_t *handler;
209
int interval = dbus_timeout_get_interval(timeout);
210
struct timeout_handler *handler;
198
212
if (!dbus_timeout_get_enabled(timeout))
201
handler = g_new0(timeout_handler_t, 1);
215
handler = g_new0(struct timeout_handler, 1);
203
217
handler->timeout = timeout;
204
handler->id = g_timeout_add(dbus_timeout_get_interval(timeout),
205
timeout_handler_dispatch, handler);
207
219
dbus_timeout_set_data(timeout, handler, timeout_handler_free);
221
handler->id = g_timeout_add(interval, timeout_handler_dispatch,
212
227
static void remove_timeout(DBusTimeout *timeout, void *data)
214
timeout_handler_t *handler;
216
handler = dbus_timeout_get_data(timeout);
221
if (handler->id > 0) {
222
g_source_remove(handler->id);
229
if (dbus_timeout_get_enabled(timeout))
232
/* will trigger timeout_handler_free() */
233
dbus_timeout_set_data(timeout, NULL, NULL);
227
236
static void timeout_toggled(DBusTimeout *timeout, void *data)
232
241
remove_timeout(timeout, data);
235
static void dispatch_status_cb(DBusConnection *conn,
236
DBusDispatchStatus new_status, void *data)
244
static void dispatch_status(DBusConnection *conn,
245
DBusDispatchStatus status, void *data)
238
247
if (!dbus_connection_get_is_connected(conn))
241
if (new_status == DBUS_DISPATCH_DATA_REMAINS)
242
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch_cb, data);
250
queue_dispatch(conn, status);
245
static void setup_dbus_with_main_loop(DBusConnection *conn)
253
static inline void setup_dbus_with_main_loop(DBusConnection *conn)
247
255
dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
248
256
watch_toggled, conn, NULL);
250
258
dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout,
251
timeout_toggled, conn, NULL);
259
timeout_toggled, NULL, NULL);
253
dbus_connection_set_dispatch_status_function(conn, dispatch_status_cb,
261
dbus_connection_set_dispatch_status_function(conn, dispatch_status,
257
DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
265
static gboolean setup_bus(DBusConnection *conn, const char *name,
260
DBusConnection *conn;
262
conn = dbus_bus_get(type, error);
265
if (dbus_error_is_set(error) == TRUE)
269
DBusDispatchStatus status;
272
271
if (name != NULL) {
273
if (dbus_bus_request_name(conn, name,
274
DBUS_NAME_FLAG_DO_NOT_QUEUE, error) !=
275
DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) {
276
dbus_connection_unref(conn);
272
result = g_dbus_request_name(conn, name, error);
280
274
if (error != NULL) {
281
if (dbus_error_is_set(error) == TRUE) {
282
dbus_connection_unref(conn);
275
if (dbus_error_is_set(error) == TRUE)
288
283
setup_dbus_with_main_loop(conn);
290
if (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
291
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch_cb, conn);
285
status = dbus_connection_get_dispatch_status(conn);
286
queue_dispatch(conn, status);
291
DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
294
DBusConnection *conn;
296
conn = dbus_bus_get(type, error);
299
if (dbus_error_is_set(error) == TRUE)
306
if (setup_bus(conn, name, error) == FALSE) {
307
dbus_connection_unref(conn);
314
DBusConnection *g_dbus_setup_private(DBusBusType type, const char *name,
317
DBusConnection *conn;
319
conn = dbus_bus_get_private(type, error);
322
if (dbus_error_is_set(error) == TRUE)
329
if (setup_bus(conn, name, error) == FALSE) {
330
dbus_connection_unref(conn);
306
364
struct disconnect_data *dc_data;
308
dc_data = g_new(struct disconnect_data, 1);
366
dc_data = g_new0(struct disconnect_data, 1);
310
dc_data->disconnect_cb = function;
368
dc_data->function = function;
311
369
dc_data->user_data = user_data;
313
371
dbus_connection_set_exit_on_disconnect(connection, FALSE);
315
if (dbus_connection_add_filter(connection, disconnect_filter,
316
dc_data, g_free) == FALSE) {
317
error("Can't add D-Bus disconnect filter");
373
if (g_dbus_add_signal_watch(connection, NULL, NULL,
374
DBUS_INTERFACE_LOCAL, "Disconnected",
375
disconnected_signal, dc_data, g_free) == 0) {
376
error("Failed to add watch for D-Bus Disconnected signal");