mainloop.c revision dd99e73bd8bdc33c9eba55ed57a99f7028984719
15442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann/*
25442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
3be0ba88ce4a4c37821f1ffa46ff6411d278297c1Marcel Holtmann *  D-Bus helper library
45442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
5d21f53083c83614a4dbae21b06e7aabfa1a12454Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
65442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
75442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
85442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  This program is free software; you can redistribute it and/or modify
95442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  it under the terms of the GNU General Public License as published by
105442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
115442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  (at your option) any later version.
125442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
135442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  This program is distributed in the hope that it will be useful,
145442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
155442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  GNU General Public License for more details.
175442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
185442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  You should have received a copy of the GNU General Public License
195442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  along with this program; if not, write to the Free Software
205442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
215442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
225442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann */
235442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann
245442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#ifdef HAVE_CONFIG_H
255442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#include <config.h>
265442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#endif
275442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann
2833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#include <glib.h>
295442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#include <dbus/dbus.h>
305442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann
315442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#ifdef NEED_DBUS_WATCH_GET_UNIX_FD
325442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#define dbus_watch_get_unix_fd dbus_watch_get_fd
335442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#endif
345442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann
355442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann#include "gdbus.h"
3633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#define DISPATCH_TIMEOUT  0
3833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#define info(fmt...)
4033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#define error(fmt...)
4133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann#define debug(fmt...)
4233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
434da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstruct timeout_handler {
444da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	guint id;
4533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusTimeout *timeout;
464da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann};
4733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
4833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstruct watch_info {
494da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	guint id;
504da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	DBusWatch *watch;
5133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusConnection *conn;
5233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann};
5333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
5433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstruct disconnect_data {
554da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	GDBusWatchFunction function;
5633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	void *user_data;
5733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann};
5833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
592ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentzstatic gboolean disconnected_signal(DBusConnection *conn,
6033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann						DBusMessage *msg, void *data)
6133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
6233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	struct disconnect_data *dc_data = data;
6333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
642ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz	error("Got disconnected from the system message bus");
654da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
664da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dc_data->function(conn, dc_data->user_data);
674da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
682ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz	dbus_connection_unref(conn);
6933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
702ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz	return TRUE;
7133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
7233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
734da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic gboolean message_dispatch(void *data)
7433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
754da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	DBusConnection *conn = data;
7633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
774da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_ref(conn);
7833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
7933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	/* Dispatch messages */
804da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
8133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
824da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_unref(conn);
8333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
8433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return FALSE;
8533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
8633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
874da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic inline void queue_dispatch(DBusConnection *conn,
884da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann						DBusDispatchStatus status)
894da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann{
904da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (status == DBUS_DISPATCH_DATA_REMAINS)
914da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
924da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann}
934da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
9433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
9533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
964da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct watch_info *info = data;
974da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	unsigned int flags = 0;
984da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
994da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_ref(info->conn);
10033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
10133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
10233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
10333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
10433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
10533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1064da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_watch_handle(info->watch, flags);
10733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1084da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_unref(info->conn);
10933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
11033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
11133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
11233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1134da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic void watch_info_free(void *data)
1144da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann{
1154da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct watch_info *info = data;
1164da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1174da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (info->id > 0) {
1184da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		g_source_remove(info->id);
1194da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		info->id = 0;
1204da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	}
1214da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1224da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_unref(info->conn);
1234da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1244da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	g_free(info);
1254da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann}
1264da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
12733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic dbus_bool_t add_watch(DBusWatch *watch, void *data)
12833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
12933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusConnection *conn = data;
1304da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	GIOCondition cond = G_IO_HUP | G_IO_ERR;
1314da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	GIOChannel *chan;
13233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	struct watch_info *info;
1334da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	unsigned int flags;
1344da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int fd;
13533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
13633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_watch_get_enabled(watch))
13733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return TRUE;
13833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1394da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info = g_new0(struct watch_info, 1);
14033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
14133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	fd = dbus_watch_get_unix_fd(watch);
1424da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	chan = g_io_channel_unix_new(fd);
1434da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1444da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info->watch = watch;
14533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	info->conn = dbus_connection_ref(conn);
14633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1474da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_watch_set_data(watch, info, watch_info_free);
14833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
14933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	flags = dbus_watch_get_flags(watch);
15033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
15133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
15233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;
15333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1544da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info->id = g_io_add_watch(chan, cond, watch_func, info);
1554da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1564da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	g_io_channel_unref(chan);
15733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
15833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
15933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
16033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
16133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void remove_watch(DBusWatch *watch, void *data)
16233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
1634da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (dbus_watch_get_enabled(watch))
1644da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		return;
16533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1664da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	/* will trigger watch_info_free() */
16733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_watch_set_data(watch, NULL, NULL);
16833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
16933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
17033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void watch_toggled(DBusWatch *watch, void *data)
17133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
17233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	/* Because we just exit on OOM, enable/disable is
17333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	 * no different from add/remove */
17433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (dbus_watch_get_enabled(watch))
17533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		add_watch(watch, data);
17633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	else
17733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		remove_watch(watch, data);
17833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
17933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
18033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic gboolean timeout_handler_dispatch(gpointer data)
18133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
1824da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler = data;
1834da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1844da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler->id = 0;
18533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
18633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	/* if not enabled should not be polled by the main loop */
1874da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (!dbus_timeout_get_enabled(handler->timeout))
18833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return FALSE;
18933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_timeout_handle(handler->timeout);
19133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return FALSE;
19333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
19433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void timeout_handler_free(void *data)
19633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
1974da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler = data;
19833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1990b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius	if (handler->id > 0) {
2000b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius		g_source_remove(handler->id);
2010b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius		handler->id = 0;
2020b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius	}
2030b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius
20433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	g_free(handler);
20533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
20633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
20733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
20833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
2094da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int interval = dbus_timeout_get_interval(timeout);
2104da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler;
21133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
21233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_timeout_get_enabled(timeout))
21333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return TRUE;
21433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2154da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler = g_new0(struct timeout_handler, 1);
21633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
21733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	handler->timeout = timeout;
21833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
21933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_timeout_set_data(timeout, handler, timeout_handler_free);
22033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2214da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler->id = g_timeout_add(interval, timeout_handler_dispatch,
2224da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann								handler);
2234da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
22433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
22533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
22633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
22733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void remove_timeout(DBusTimeout *timeout, void *data)
22833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
2294da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (dbus_timeout_get_enabled(timeout))
2304da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		return;
2310b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius
2324da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	/* will trigger timeout_handler_free() */
2334da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_timeout_set_data(timeout, NULL, NULL);
23433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
23533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
23633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void timeout_toggled(DBusTimeout *timeout, void *data)
23733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
23833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (dbus_timeout_get_enabled(timeout))
23933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		add_timeout(timeout, data);
24033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	else
24133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		remove_timeout(timeout, data);
24233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
24333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2444da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic void dispatch_status(DBusConnection *conn,
2454da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann					DBusDispatchStatus status, void *data)
24633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
24733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_connection_get_is_connected(conn))
24833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return;
24933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2504da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	queue_dispatch(conn, status);
25133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
25233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2534da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic inline void setup_dbus_with_main_loop(DBusConnection *conn)
25433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
25533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
25633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann						watch_toggled, conn, NULL);
25733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
25833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout,
2594da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann						timeout_toggled, NULL, NULL);
26033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2614da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_set_dispatch_status_function(conn, dispatch_status,
2624da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann								NULL, NULL);
26333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
26433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
26522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhaostatic gboolean setup_bus(DBusConnection *conn, const char *name,
26622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao						DBusError *error)
26722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao{
26822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	gboolean result;
26922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	DBusDispatchStatus status;
27022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
27122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (name != NULL) {
27222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		result = g_dbus_request_name(conn, name, error);
27322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
27422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (error != NULL) {
27522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao			if (dbus_error_is_set(error) == TRUE)
27622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao				return FALSE;
27722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		}
27822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
27922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (result == FALSE)
28022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao			return FALSE;
28122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
28222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	setup_dbus_with_main_loop(conn);
28422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	status = dbus_connection_get_dispatch_status(conn);
28622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	queue_dispatch(conn, status);
28722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	return TRUE;
28922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao}
29022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
291aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel HoltmannDBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
292aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann							DBusError *error)
29333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
29433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusConnection *conn;
29533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
296aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	conn = dbus_bus_get(type, error);
29733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
298aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	if (error != NULL) {
299aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		if (dbus_error_is_set(error) == TRUE)
300aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann			return NULL;
30133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
30233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
303aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	if (conn == NULL)
304aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		return NULL;
30533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
306dd99e73bd8bdc33c9eba55ed57a99f7028984719Marcel Holtmann	if (setup_bus(conn, name, error) == FALSE) {
30722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		dbus_connection_unref(conn);
30822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
30922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
31022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
31122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	return conn;
31222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao}
31322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
31422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest ZhaoDBusConnection *g_dbus_setup_private(DBusBusType type, const char *name,
31522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao							DBusError *error)
31622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao{
31722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	DBusConnection *conn;
3184da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
31922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	conn = dbus_bus_get_private(type, error);
32022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
32122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (error != NULL) {
32222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (dbus_error_is_set(error) == TRUE)
3234da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann			return NULL;
32433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
32533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
32622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (conn == NULL)
32722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
328aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann
329dd99e73bd8bdc33c9eba55ed57a99f7028984719Marcel Holtmann	if (setup_bus(conn, name, error) == FALSE) {
33022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		dbus_connection_unref(conn);
33122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
33222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
33345806a9b07eb6bc83cf9ccfd87288e021c702730Claudio Takahasi
334aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	return conn;
335aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann}
336aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann
3379fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmanngboolean g_dbus_request_name(DBusConnection *connection, const char *name,
3389fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann							DBusError *error)
3399fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann{
3404da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int result;
3414da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3424da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	result = dbus_bus_request_name(connection, name,
3434da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann					DBUS_NAME_FLAG_DO_NOT_QUEUE, error);
3444da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3454da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (error != NULL) {
3464da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		if (dbus_error_is_set(error) == TRUE)
3474da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann			return FALSE;
3484da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	}
3494da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3504da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
3514da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		return FALSE;
3524da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3539fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann	return TRUE;
3549fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann}
3559fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann
356aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmanngboolean g_dbus_set_disconnect_function(DBusConnection *connection,
3577d1a9d56719aea39ecd38c8dafffee9de898e68bMarcel Holtmann				GDBusWatchFunction function,
358aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann				void *user_data, DBusFreeFunction destroy)
359aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann{
360aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	struct disconnect_data *dc_data;
36133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3624da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dc_data = g_new0(struct disconnect_data, 1);
36333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3644da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dc_data->function = function;
36533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dc_data->user_data = user_data;
36633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
367aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	dbus_connection_set_exit_on_disconnect(connection, FALSE);
36833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3692ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz	if (g_dbus_add_signal_watch(connection, NULL, NULL,
3702ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz				DBUS_INTERFACE_LOCAL, "Disconnected",
3714da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann				disconnected_signal, dc_data, g_free) == 0) {
3724da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		error("Failed to add watch for D-Bus Disconnected signal");
37333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		g_free(dc_data);
374aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		return FALSE;
37533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
37633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
377aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	return TRUE;
37833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
379