15442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann/*
25442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
3be0ba88ce4a4c37821f1ffa46ff6411d278297c1Marcel Holtmann *  D-Bus helper library
45442ba4d63b8f9548e140a47f63046c11819a972Marcel Holtmann *
5e7c4557de7b49f0186bcc28dda5a79c4d629e125Marcel Holtmann *  Copyright (C) 2004-2011  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;
98fd6b74727b0baf2d89f448721296149bf2852869Luiz Augusto von Dentz	DBusDispatchStatus status;
994da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1004da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_ref(info->conn);
10133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
10233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
10333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
10433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
10533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
10633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1074da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_watch_handle(info->watch, flags);
10833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
109fd6b74727b0baf2d89f448721296149bf2852869Luiz Augusto von Dentz	status = dbus_connection_get_dispatch_status(info->conn);
110fd6b74727b0baf2d89f448721296149bf2852869Luiz Augusto von Dentz	queue_dispatch(info->conn, status);
111fd6b74727b0baf2d89f448721296149bf2852869Luiz Augusto von Dentz
1124da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_unref(info->conn);
11333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
11433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
11533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
11633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1174da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic void watch_info_free(void *data)
1184da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann{
1194da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct watch_info *info = data;
1204da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1214da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (info->id > 0) {
1224da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		g_source_remove(info->id);
1234da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		info->id = 0;
1244da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	}
1254da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1264da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_unref(info->conn);
1274da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1284da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	g_free(info);
1294da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann}
1304da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
13133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic dbus_bool_t add_watch(DBusWatch *watch, void *data)
13233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
13333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusConnection *conn = data;
1344da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	GIOCondition cond = G_IO_HUP | G_IO_ERR;
1354da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	GIOChannel *chan;
13633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	struct watch_info *info;
1374da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	unsigned int flags;
1384da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int fd;
13933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
14033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_watch_get_enabled(watch))
14133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return TRUE;
14233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1434da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info = g_new0(struct watch_info, 1);
14433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
14533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	fd = dbus_watch_get_unix_fd(watch);
1464da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	chan = g_io_channel_unix_new(fd);
1474da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1484da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info->watch = watch;
14933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	info->conn = dbus_connection_ref(conn);
15033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1514da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_watch_set_data(watch, info, watch_info_free);
15233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
15333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	flags = dbus_watch_get_flags(watch);
15433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
15533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
15633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;
15733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1584da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	info->id = g_io_add_watch(chan, cond, watch_func, info);
1594da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1604da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	g_io_channel_unref(chan);
16133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
16233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
16333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
16433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
16533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void remove_watch(DBusWatch *watch, void *data)
16633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
1674da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (dbus_watch_get_enabled(watch))
1684da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		return;
16933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
1704da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	/* will trigger watch_info_free() */
17133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_watch_set_data(watch, NULL, NULL);
17233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
17333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
17433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void watch_toggled(DBusWatch *watch, void *data)
17533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
17633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	/* Because we just exit on OOM, enable/disable is
17733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	 * no different from add/remove */
17833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (dbus_watch_get_enabled(watch))
17933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		add_watch(watch, data);
18033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	else
18133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		remove_watch(watch, data);
18233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
18333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
18433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic gboolean timeout_handler_dispatch(gpointer data)
18533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
1864da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler = data;
1874da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
1884da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler->id = 0;
18933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	/* if not enabled should not be polled by the main loop */
1914da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (!dbus_timeout_get_enabled(handler->timeout))
19233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return FALSE;
19333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_timeout_handle(handler->timeout);
19533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return FALSE;
19733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
19833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
19933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void timeout_handler_free(void *data)
20033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
2014da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler = data;
20233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2030b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius	if (handler->id > 0) {
2040b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius		g_source_remove(handler->id);
2050b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius		handler->id = 0;
2060b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius	}
2070b15d14b98393f6be6de50f0ef1c8c687054ef5dDaniel Orstadius
20833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	g_free(handler);
20933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
21033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
21133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
21233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
2134da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int interval = dbus_timeout_get_interval(timeout);
2144da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	struct timeout_handler *handler;
21533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
21633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_timeout_get_enabled(timeout))
21733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return TRUE;
21833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2194da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler = g_new0(struct timeout_handler, 1);
22033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
22133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	handler->timeout = timeout;
22233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
22333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_timeout_set_data(timeout, handler, timeout_handler_free);
22433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2254da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	handler->id = g_timeout_add(interval, timeout_handler_dispatch,
2264da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann								handler);
2274da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
22833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	return TRUE;
22933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
23033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
23133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void remove_timeout(DBusTimeout *timeout, void *data)
23233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
2334da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	/* will trigger timeout_handler_free() */
2344da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_timeout_set_data(timeout, NULL, NULL);
23533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
23633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
23733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmannstatic void timeout_toggled(DBusTimeout *timeout, void *data)
23833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
23933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (dbus_timeout_get_enabled(timeout))
24033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		add_timeout(timeout, data);
24133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	else
24233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		remove_timeout(timeout, data);
24333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
24433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2454da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic void dispatch_status(DBusConnection *conn,
2464da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann					DBusDispatchStatus status, void *data)
24733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
24833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	if (!dbus_connection_get_is_connected(conn))
24933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		return;
25033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2514da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	queue_dispatch(conn, status);
25233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
25333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2544da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmannstatic inline void setup_dbus_with_main_loop(DBusConnection *conn)
25533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
25633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_connection_set_watch_functions(conn, add_watch, remove_watch,
25733191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann						watch_toggled, conn, NULL);
25833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
25933191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout,
2604da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann						timeout_toggled, NULL, NULL);
26133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
2624da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dbus_connection_set_dispatch_status_function(conn, dispatch_status,
2634da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann								NULL, NULL);
26433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
26533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
26622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhaostatic gboolean setup_bus(DBusConnection *conn, const char *name,
26722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao						DBusError *error)
26822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao{
26922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	gboolean result;
27022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	DBusDispatchStatus status;
27122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
27222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (name != NULL) {
27322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		result = g_dbus_request_name(conn, name, error);
27422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
27522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (error != NULL) {
27622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao			if (dbus_error_is_set(error) == TRUE)
27722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao				return FALSE;
27822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		}
27922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (result == FALSE)
28122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao			return FALSE;
28222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
28322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	setup_dbus_with_main_loop(conn);
28522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	status = dbus_connection_get_dispatch_status(conn);
28722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	queue_dispatch(conn, status);
28822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
28922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	return TRUE;
29022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao}
29122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
292aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel HoltmannDBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
293aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann							DBusError *error)
29433191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann{
29533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	DBusConnection *conn;
29633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
297aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	conn = dbus_bus_get(type, error);
29833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
299aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	if (error != NULL) {
300aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		if (dbus_error_is_set(error) == TRUE)
301aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann			return NULL;
30233191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
30333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
304aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	if (conn == NULL)
305aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		return NULL;
30633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
307dd99e73bd8bdc33c9eba55ed57a99f7028984719Marcel Holtmann	if (setup_bus(conn, name, error) == FALSE) {
30822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		dbus_connection_unref(conn);
30922d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
31022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
31122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
31222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	return conn;
31322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao}
31422d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
31522d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest ZhaoDBusConnection *g_dbus_setup_private(DBusBusType type, const char *name,
31622d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao							DBusError *error)
31722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao{
31822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	DBusConnection *conn;
3194da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
32022d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	conn = dbus_bus_get_private(type, error);
32122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao
32222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (error != NULL) {
32322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		if (dbus_error_is_set(error) == TRUE)
3244da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann			return NULL;
32533191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
32633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
32722d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	if (conn == NULL)
32822d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
329aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann
330dd99e73bd8bdc33c9eba55ed57a99f7028984719Marcel Holtmann	if (setup_bus(conn, name, error) == FALSE) {
33122d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		dbus_connection_unref(conn);
33222d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao		return NULL;
33322d39c8860d15d2ed9a2a170bf46f576ca819e42Forrest Zhao	}
33445806a9b07eb6bc83cf9ccfd87288e021c702730Claudio Takahasi
335aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	return conn;
336aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann}
337aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann
3389fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmanngboolean g_dbus_request_name(DBusConnection *connection, const char *name,
3399fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann							DBusError *error)
3409fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann{
3414da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	int result;
3424da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3434da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	result = dbus_bus_request_name(connection, name,
3444da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann					DBUS_NAME_FLAG_DO_NOT_QUEUE, error);
3454da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3464da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	if (error != NULL) {
3474da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		if (dbus_error_is_set(error) == TRUE)
3484da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann			return FALSE;
3494da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	}
3504da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
351e6b83be22e3c3c12e499ca626a2c97943bdf24b4Vinicius Costa Gomes	if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
352e6b83be22e3c3c12e499ca626a2c97943bdf24b4Vinicius Costa Gomes		if (error != NULL)
353e6b83be22e3c3c12e499ca626a2c97943bdf24b4Vinicius Costa Gomes			dbus_set_error(error, name, "Name already in use");
354e6b83be22e3c3c12e499ca626a2c97943bdf24b4Vinicius Costa Gomes
3554da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		return FALSE;
356e6b83be22e3c3c12e499ca626a2c97943bdf24b4Vinicius Costa Gomes	}
3574da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann
3589fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann	return TRUE;
3599fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann}
3609fb751d2128e128fe1f321f2cc2e018000a542f6Marcel Holtmann
361aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmanngboolean g_dbus_set_disconnect_function(DBusConnection *connection,
3627d1a9d56719aea39ecd38c8dafffee9de898e68bMarcel Holtmann				GDBusWatchFunction function,
363aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann				void *user_data, DBusFreeFunction destroy)
364aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann{
365aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	struct disconnect_data *dc_data;
36633191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3674da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dc_data = g_new0(struct disconnect_data, 1);
36833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3694da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann	dc_data->function = function;
37033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	dc_data->user_data = user_data;
37133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
372aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	dbus_connection_set_exit_on_disconnect(connection, FALSE);
37333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
3742ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz	if (g_dbus_add_signal_watch(connection, NULL, NULL,
3752ae4af4d42cf1bf8eb6bc8956beaf3741c8be807Luiz Augusto von Dentz				DBUS_INTERFACE_LOCAL, "Disconnected",
3764da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann				disconnected_signal, dc_data, g_free) == 0) {
3774da121910a70aa00db2c95a10c0fbcb6bc0ee3ddMarcel Holtmann		error("Failed to add watch for D-Bus Disconnected signal");
37833191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann		g_free(dc_data);
379aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann		return FALSE;
38033191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann	}
38133191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann
382aa215d6fa551a3edbd129d4a163210e98357bdd1Marcel Holtmann	return TRUE;
38333191e6275ab82aa4161cdf75b45597e4d1568ecMarcel Holtmann}
384