1ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann/*
2ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
3be0ba88ce4a4c37821f1ffa46ff6411d278297c1Marcel Holtmann *  D-Bus helper library
4ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
5d21f53083c83614a4dbae21b06e7aabfa1a12454Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
7ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
8ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  This program is free software; you can redistribute it and/or modify
9ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  it under the terms of the GNU General Public License as published by
10ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
11ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  (at your option) any later version.
12ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
13ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  This program is distributed in the hope that it will be useful,
14ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  GNU General Public License for more details.
17ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
18ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  You should have received a copy of the GNU General Public License
19ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  along with this program; if not, write to the Free Software
20ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann *
22ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann */
23ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
24ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#ifdef HAVE_CONFIG_H
25ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <config.h>
26ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#endif
27ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
2815ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <stdio.h>
29ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <string.h>
30ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
318cc5595d9091b484b9a4abe314c0f3ec055e0581Marcel Holtmann#include <glib.h>
32ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann#include <dbus/dbus.h>
33ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
3415ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include "gdbus.h"
35ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
3615ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#define info(fmt...)
3715ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#define error(fmt...)
3815ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#define debug(fmt...)
39ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
40ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmannstruct generic_data {
41dd368f19884b9751a0f99ffebcd2c5520069f5dbMarcel Holtmann	unsigned int refcount;
42f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	GSList *interfaces;
43f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann	char *introspect;
44f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann};
45f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
46f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmannstruct interface_data {
4730957bc2890f3db99907178304046610e77c7efaJohan Hedberg	char *name;
48d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusMethodTable *methods;
49d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusSignalTable *signals;
50d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusPropertyTable *properties;
5197e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	void *user_data;
5297e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	GDBusDestroyFunction destroy;
53ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann};
54ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
5530877999b61e655ff7f4e804240098c4cd31831eMarcel Holtmannstatic void print_arguments(GString *gstr, const char *sig,
5630877999b61e655ff7f4e804240098c4cd31831eMarcel Holtmann						const char *direction)
57d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg{
58d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	int i;
59d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
60d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	for (i = 0; sig[i]; i++) {
61223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		char type[32];
62b75f83543ab6385e56adc5efe0110b94a9a9555eMarcel Holtmann		int struct_level, dict_level;
63b75f83543ab6385e56adc5efe0110b94a9a9555eMarcel Holtmann		unsigned int len;
64223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		gboolean complete;
65223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
66223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		complete = FALSE;
67223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		struct_level = dict_level = 0;
68223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		memset(type, 0, sizeof(type));
69223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
70223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		/* Gather enough data to have a single complete type */
71223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
72223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			switch (sig[i]){
73223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '(':
74223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				struct_level++;
75223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
76223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case ')':
77223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				struct_level--;
78223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
79223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
80223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
81223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '{':
82223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				dict_level++;
83223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
84223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case '}':
85223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				dict_level--;
86223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
87223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
88223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
89223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			case 'a':
90223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
91223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			default:
92223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				if (struct_level <= 0 && dict_level <= 0)
93223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					complete = TRUE;
94223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
95223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			}
96223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
97223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			type[len] = sig[i];
98223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
99223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg			if (complete)
100223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg				break;
101223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg		}
102223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
103223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg
104d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		if (direction)
105d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg			g_string_append_printf(gstr,
106223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					"\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
107223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					type, direction);
108d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		else
109d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg			g_string_append_printf(gstr,
110223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					"\t\t\t<arg type=\"%s\"/>\n",
111223aa9581953c03f371a10b3f0555f7fa132f690Johan Hedberg					type);
112d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	}
113d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg}
114d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
115e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmannstatic void generate_interface_xml(GString *gstr, struct interface_data *iface)
116e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann{
117d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusMethodTable *method;
118d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusSignalTable *signal;
119e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann
120e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann	for (method = iface->methods; method && method->name; method++) {
121e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		if (!strlen(method->signature) && !strlen(method->reply))
122e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
123e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								method->name);
124e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		else {
125e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
126e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								method->name);
127e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			print_arguments(gstr, method->signature, "in");
128e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			print_arguments(gstr, method->reply, "out");
129e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t</method>\n");
130e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		}
131e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann	}
132e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann
133e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann	for (signal = iface->signals; signal && signal->name; signal++) {
134e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		if (!strlen(signal->signature))
135e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
136e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								signal->name);
137e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		else {
138e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
139e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								signal->name);
140e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			print_arguments(gstr, signal->signature, NULL);
141e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann			g_string_append_printf(gstr, "\t\t</signal>\n");
142e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		}
143e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann	}
144e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann}
145e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann
146251f743f1501e99176c4071487b93567e94fefaaJohan Hedbergstatic void generate_introspection_xml(DBusConnection *conn,
147e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann				struct generic_data *data, const char *path)
148d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg{
149d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	GSList *list;
150d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	GString *gstr;
1515cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	char **children;
1525cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	int i;
153d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
154d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_free(data->introspect);
155d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
156d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	gstr = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
157d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
158b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	g_string_append_printf(gstr, "<node name=\"%s\">\n", path);
159d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
160d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	for (list = data->interfaces; list; list = list->next) {
161d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		struct interface_data *iface = list->data;
162d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
163e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		g_string_append_printf(gstr, "\t<interface name=\"%s\">\n",
164e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								iface->name);
165d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
166e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		generate_interface_xml(gstr, iface);
167d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
168d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg		g_string_append_printf(gstr, "\t</interface>\n");
169d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	}
170d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
1715cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!dbus_connection_list_registered(conn, path, &children))
1725cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
1735cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
1745cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	for (i = 0; children[i]; i++)
175e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann		g_string_append_printf(gstr, "\t<node name=\"%s\"/>\n",
176e7bf43c753dda82371be083bdb063a96767576ebMarcel Holtmann								children[i]);
1775cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
1785cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	dbus_free_string_array(children);
1795cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
1805cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergdone:
181d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	g_string_append_printf(gstr, "</node>\n");
182d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg
183d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	data->introspect = g_string_free(gstr, FALSE);
184d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg}
185f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
186b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergelystatic DBusMessage *introspect(DBusConnection *connection,
187b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely				DBusMessage *message, void *user_data)
188251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg{
189b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	struct generic_data *data = user_data;
190251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	DBusMessage *reply;
191251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
192d1c4d1d53a5f153d6c778debe1470fc1f32857e8Johan Hedberg	if (!dbus_message_has_signature(message, DBUS_TYPE_INVALID_AS_STRING)) {
193251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg		error("Unexpected signature to introspect call");
194b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely		return NULL;
195251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	}
196251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
197251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	if (!data->introspect)
198251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg		generate_introspection_xml(connection, data,
199251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg						dbus_message_get_path(message));
200251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
201251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	reply = dbus_message_new_method_return(message);
202251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	if (!reply)
203b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely		return NULL;
204251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
205251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
206251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg					DBUS_TYPE_INVALID);
207251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
208b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	return reply;
209251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg}
210251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
211251f743f1501e99176c4071487b93567e94fefaaJohan Hedbergstatic void generic_unregister(DBusConnection *connection, void *user_data)
212251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg{
213251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	struct generic_data *data = user_data;
214251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
215251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	g_free(data->introspect);
216251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	g_free(data);
217251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg}
218251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
219251f743f1501e99176c4071487b93567e94fefaaJohan Hedbergstatic struct interface_data *find_interface(GSList *interfaces,
220251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg						const char *name)
221251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg{
222251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	GSList *list;
223251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
224b8481a1eb474bd60c9fc0cffbcbf0f8da76c1c9dMarcel Holtmann	if (!name)
225b8481a1eb474bd60c9fc0cffbcbf0f8da76c1c9dMarcel Holtmann		return NULL;
226b8481a1eb474bd60c9fc0cffbcbf0f8da76c1c9dMarcel Holtmann
227251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	for (list = interfaces; list; list = list->next) {
228251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg		struct interface_data *iface = list->data;
229251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg		if (!strcmp(name, iface->name))
230251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg			return iface;
231251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	}
232251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
233251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	return NULL;
234251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg}
235251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
236251f743f1501e99176c4071487b93567e94fefaaJohan Hedbergstatic DBusHandlerResult generic_message(DBusConnection *connection,
237251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg					DBusMessage *message, void *user_data)
238251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg{
239251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	struct generic_data *data = user_data;
240251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	struct interface_data *iface;
241d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusMethodTable *method;
242251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	const char *interface;
243251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
244251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	interface = dbus_message_get_interface(message);
245251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
246251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	iface = find_interface(data->interfaces, interface);
247251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	if (!iface)
248251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
249251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
250cc2d696524d90b3c624c8857338f8572c7edff99Marcel Holtmann	for (method = iface->methods; method &&
251aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			method->name && method->function; method++) {
252aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		DBusMessage *reply;
253aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
254aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		if (dbus_message_is_method_call(message, iface->name,
255aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann							method->name) == FALSE)
256aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			continue;
257aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
258aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		if (dbus_message_has_signature(message,
259aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann						method->signature) == FALSE)
260aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			continue;
261aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
262aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		reply = method->function(connection, message, iface->user_data);
263aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
264aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY) {
265aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			if (reply != NULL)
266aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann				dbus_message_unref(reply);
267aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			return DBUS_HANDLER_RESULT_HANDLED;
268aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		}
269aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
270aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		if (method->flags & G_DBUS_METHOD_FLAG_ASYNC) {
271aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			if (reply == NULL)
272aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann				return DBUS_HANDLER_RESULT_HANDLED;
273aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		}
274aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
275aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		if (reply == NULL)
276aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann			return DBUS_HANDLER_RESULT_NEED_MEMORY;
277aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
278aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		dbus_connection_send(connection, reply, NULL);
279aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		dbus_message_unref(reply);
280aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
281aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann		return DBUS_HANDLER_RESULT_HANDLED;
282aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann	}
283aff0ec6707716c2ea129695f85715d59e3d9474bMarcel Holtmann
284251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
285251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg}
286251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
287251f743f1501e99176c4071487b93567e94fefaaJohan Hedbergstatic DBusObjectPathVTable generic_table = {
288251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	.unregister_function	= generic_unregister,
289251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	.message_function	= generic_message,
290251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg};
291251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg
292fb2c49cfc95ee82f77df6b8242199599f5e9f9eeJohan Hedbergstatic void invalidate_parent_data(DBusConnection *conn, const char *child_path)
2935cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg{
2945fcad6abebf97c6a06d9eb5c206d5c10bcf14eb7Claudio Takahasi	struct generic_data *data = NULL;
2955cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	char *parent_path, *slash;
2965cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
2975cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	parent_path = g_strdup(child_path);
2985cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	slash = strrchr(parent_path, '/');
2995cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!slash)
3005cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
3015cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3021f6936fe7c9d16a2e184add8730ce714e8b8eaddDenis Kenzior	if (slash == parent_path && parent_path[1] != '\0')
3031f6936fe7c9d16a2e184add8730ce714e8b8eaddDenis Kenzior		parent_path[1] = '\0';
3041f6936fe7c9d16a2e184add8730ce714e8b8eaddDenis Kenzior	else
3051f6936fe7c9d16a2e184add8730ce714e8b8eaddDenis Kenzior		*slash = '\0';
3061f6936fe7c9d16a2e184add8730ce714e8b8eaddDenis Kenzior
3075cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!strlen(parent_path))
3085cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
3095cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3105cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!dbus_connection_get_object_path_data(conn, parent_path,
311800e8fa2575c80d236312451f43ca5f4780524a6Johan Hedberg							(void *) &data)) {
312800e8fa2575c80d236312451f43ca5f4780524a6Johan Hedberg		invalidate_parent_data(conn, parent_path);
3135cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
314800e8fa2575c80d236312451f43ca5f4780524a6Johan Hedberg	}
3155cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3165cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	if (!data)
3175cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg		goto done;
3185cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
319251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	g_free(data->introspect);
320251f743f1501e99176c4071487b93567e94fefaaJohan Hedberg	data->introspect = NULL;
3215cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
3225cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedbergdone:
3235cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg	g_free(parent_path);
3245cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg}
3255cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
326b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergelystatic GDBusMethodTable introspect_methods[] = {
327b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	{ "Introspect",	"",	"s", introspect	},
328b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	{ }
329b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely};
330b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
331b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergelystatic void add_interface(struct generic_data *data, const char *name,
332d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann				const GDBusMethodTable *methods,
333d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann				const GDBusSignalTable *signals,
334d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann				const GDBusPropertyTable *properties,
335b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely				void *user_data,
336b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely				GDBusDestroyFunction destroy)
337b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely{
338b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	struct interface_data *iface;
339b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
340b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface = g_new0(struct interface_data, 1);
341b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->name = g_strdup(name);
342b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->methods = methods;
343b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->signals = signals;
344b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->properties = properties;
345b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->user_data = user_data;
346b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface->destroy = destroy;
347b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
348b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	data->interfaces = g_slist_append(data->interfaces, iface);
349b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely}
350b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
351ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmannstatic struct generic_data *object_path_ref(DBusConnection *connection,
352ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann							const char *path)
353ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann{
354af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann	struct generic_data *data;
355ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
356ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	if (dbus_connection_get_object_path_data(connection, path,
357af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann						(void *) &data) == TRUE) {
358af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann		if (data != NULL) {
359af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann			data->refcount++;
360af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann			return data;
361af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann		}
362ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	}
363ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
364ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	data = g_new0(struct generic_data, 1);
365ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
366d370964fbe6a9e32837037dcf193a216a0a75077Johan Hedberg	data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>");
367f7c027662d2066b3862f41dbae3b68e5c1bafce7Marcel Holtmann
368ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	data->refcount = 1;
369ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
370d1c4d1d53a5f153d6c778debe1470fc1f32857e8Johan Hedberg	if (!dbus_connection_register_object_path(connection, path,
371d1c4d1d53a5f153d6c778debe1470fc1f32857e8Johan Hedberg						&generic_table, data)) {
37279e5dd0c9e917822d0a97a1f803fc7571b253643Marcel Holtmann		g_free(data->introspect);
3733d16152fd30f2570ad8e9bb2427045e6fd317ce3Johan Hedberg		g_free(data);
374ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann		return NULL;
375ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann	}
376ee6b2930a0519021232f92f615f6a8fd9cd61805Marcel Holtmann
377fb2c49cfc95ee82f77df6b8242199599f5e9f9eeJohan Hedberg	invalidate_parent_data(connection, path);
3785cf1ae29510f5ec975080c793c692fedc10d86d8Johan Hedberg
379b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	add_interface(data, DBUS_INTERFACE_INTROSPECTABLE,
380b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely			introspect_methods, NULL, NULL, data, NULL);
381b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
382ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	return data;
383ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann}
384ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
385b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergelystatic gboolean remove_interface(struct generic_data *data, const char *name)
386b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely{
387b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	struct interface_data *iface;
388b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
389b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	iface = find_interface(data->interfaces, name);
390b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	if (!iface)
391b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely		return FALSE;
392b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
393b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	data->interfaces = g_slist_remove(data->interfaces, iface);
394b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
395b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	if (iface->destroy)
396b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely		iface->destroy(iface->user_data);
397b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
398b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	g_free(iface->name);
399b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	g_free(iface);
400b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
401b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	return TRUE;
402b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely}
403b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
404ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmannstatic void object_path_unref(DBusConnection *connection, const char *path)
405ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann{
406ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	struct generic_data *data = NULL;
407ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
408af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann	if (dbus_connection_get_object_path_data(connection, path,
409af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann						(void *) &data) == FALSE)
410af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann		return;
411af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann
412af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann	if (data == NULL)
413ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann		return;
414ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
415ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	data->refcount--;
416ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
417ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	if (data->refcount > 0)
418ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann		return;
419ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
420b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	remove_interface(data, DBUS_INTERFACE_INTROSPECTABLE);
421b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely
422ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	invalidate_parent_data(connection, path);
423ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
424ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	dbus_connection_unregister_object_path(connection, path);
425ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann}
426ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
4273ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentzstatic gboolean check_signal(DBusConnection *conn, const char *path,
4283ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz				const char *interface, const char *name,
4293ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz				const char **args)
43055466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg{
4315fcad6abebf97c6a06d9eb5c206d5c10bcf14eb7Claudio Takahasi	struct generic_data *data = NULL;
43255466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	struct interface_data *iface;
433d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann	const GDBusSignalTable *signal;
43455466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4353ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	*args = NULL;
4365fcad6abebf97c6a06d9eb5c206d5c10bcf14eb7Claudio Takahasi	if (!dbus_connection_get_object_path_data(conn, path,
4375fcad6abebf97c6a06d9eb5c206d5c10bcf14eb7Claudio Takahasi					(void *) &data) || !data) {
438d1c4d1d53a5f153d6c778debe1470fc1f32857e8Johan Hedberg		error("dbus_connection_emit_signal: path %s isn't registered",
439d1c4d1d53a5f153d6c778debe1470fc1f32857e8Johan Hedberg				path);
44055466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		return FALSE;
44155466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	}
44255466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
44355466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	iface = find_interface(data->interfaces, interface);
44455466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	if (!iface) {
44555466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		error("dbus_connection_emit_signal: %s does not implement %s",
44655466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg				path, interface);
44755466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		return FALSE;
44855466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	}
44955466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4501ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann	for (signal = iface->signals; signal && signal->name; signal++) {
4511ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann		if (!strcmp(signal->name, name)) {
4521ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann			*args = signal->signature;
4531ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann			break;
4541ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann		}
4551ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann	}
4561ed48482e52554d7bfa1a8edf8239399ae3e1155Marcel Holtmann
4573ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	if (!*args) {
45855466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		error("No signal named %s on interface %s", name, interface);
45955466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		return FALSE;
46055466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	}
46155466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4623ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	return TRUE;
4633ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz}
4643ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz
465f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmannstatic dbus_bool_t emit_signal_valist(DBusConnection *conn,
4663ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz						const char *path,
4673ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz						const char *interface,
4683ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz						const char *name,
4693ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz						int first,
4703ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz						va_list var_args)
4713ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz{
4723ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	DBusMessage *signal;
4733ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	dbus_bool_t ret;
4743ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	const char *signature, *args;
4753ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz
4763ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz	if (!check_signal(conn, path, interface, name, &args))
4773ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz		return FALSE;
4783ca0c59a0f86f9d4aaf6b6db167a3fd390dc0e4fLuiz Augusto von Dentz
47955466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	signal = dbus_message_new_signal(path, interface, name);
48055466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	if (!signal) {
48155466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		error("Unable to allocate new %s.%s signal", interface,  name);
48255466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg		return FALSE;
48355466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	}
48455466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4859dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	ret = dbus_message_append_args_valist(signal, first, var_args);
4869dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	if (!ret)
4879dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi		goto fail;
48855466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4899dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	signature = dbus_message_get_signature(signal);
4909dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	if (strcmp(args, signature) != 0) {
4919dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi		error("%s.%s: expected signature'%s' but got '%s'",
4929dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi				interface, name, args, signature);
4939dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi		ret = FALSE;
4949dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi		goto fail;
49555466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	}
49655466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
4979dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	ret = dbus_connection_send(conn, signal, NULL);
498dd368f19884b9751a0f99ffebcd2c5520069f5dbMarcel Holtmann
4999dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasifail:
50055466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg	dbus_message_unref(signal);
50155466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
5029dca4cf2d579b58c62d0ce98102250a6e0759daeClaudio Takahasi	return ret;
50355466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg}
50455466e2f43cf52b563954a9c2d1a722f6c646f7cJohan Hedberg
5055567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmanngboolean g_dbus_register_interface(DBusConnection *connection,
5065567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann					const char *path, const char *name,
507d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann					const GDBusMethodTable *methods,
508d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann					const GDBusSignalTable *signals,
509d44989c514beb2f66874babe6b0e75eb444c11e8Marcel Holtmann					const GDBusPropertyTable *properties,
5105567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann					void *user_data,
5115567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann					GDBusDestroyFunction destroy)
5125567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann{
513ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	struct generic_data *data;
51497e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
515ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	data = object_path_ref(connection, path);
516ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	if (data == NULL)
51797e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann		return FALSE;
51897e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
5199bbcbff03911ed1094ce4f2d4aa57df1282621d2Johan Hedberg	if (find_interface(data->interfaces, name)) {
5209bbcbff03911ed1094ce4f2d4aa57df1282621d2Johan Hedberg		object_path_unref(connection, path);
52197e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann		return FALSE;
5229bbcbff03911ed1094ce4f2d4aa57df1282621d2Johan Hedberg	}
52397e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
524b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	add_interface(data, name, methods, signals,
525b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely			properties, user_data, destroy);
52697e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
52797e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	g_free(data->introspect);
52897e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	data->introspect = NULL;
52997e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
53097e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	return TRUE;
5315567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann}
5325567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann
5335567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmanngboolean g_dbus_unregister_interface(DBusConnection *connection,
5345567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann					const char *path, const char *name)
5355567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann{
53697e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	struct generic_data *data = NULL;
53797e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
53821f3750cf534b1326f9d1357b8713d881437907aRaymond Liu	if (!path)
53921f3750cf534b1326f9d1357b8713d881437907aRaymond Liu		return FALSE;
54021f3750cf534b1326f9d1357b8713d881437907aRaymond Liu
541af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann	if (dbus_connection_get_object_path_data(connection, path,
542af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann						(void *) &data) == FALSE)
543af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann		return FALSE;
544af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann
545af6885a49f231d2e5fe421187679b27252658b6cMarcel Holtmann	if (data == NULL)
54697e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann		return FALSE;
54797e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
548b7ec8242e53006e83c63cb8cd8b27a007e91aa48RISKÓ Gergely	if (remove_interface(data, name) == FALSE)
54997e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann		return FALSE;
55097e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
55197e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	g_free(data->introspect);
55297e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	data->introspect = NULL;
55397e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann
554ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann	object_path_unref(connection, path);
555ac79141ef561c9d87494350c2b28b0d37975650aMarcel Holtmann
55697e97deb25d098c2e094ebfa8be2ed3994cc56baMarcel Holtmann	return TRUE;
5575567809ce0381ebfc22d77e5df31624d23c591dcMarcel Holtmann}
558d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
559d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel HoltmannDBusMessage *g_dbus_create_error_valist(DBusMessage *message, const char *name,
560d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann					const char *format, va_list args)
561d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann{
5620b3d10c5ef6262410e6799ee3e2037c4441b563dJohan Hedberg	char str[1024];
5630b3d10c5ef6262410e6799ee3e2037c4441b563dJohan Hedberg
5640b3d10c5ef6262410e6799ee3e2037c4441b563dJohan Hedberg	vsnprintf(str, sizeof(str), format, args);
5650b3d10c5ef6262410e6799ee3e2037c4441b563dJohan Hedberg
5660b3d10c5ef6262410e6799ee3e2037c4441b563dJohan Hedberg	return dbus_message_new_error(message, name, str);
567d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann}
568d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
569d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel HoltmannDBusMessage *g_dbus_create_error(DBusMessage *message, const char *name,
570d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann						const char *format, ...)
571d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann{
572d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	va_list args;
573d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	DBusMessage *reply;
574d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
575d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	va_start(args, format);
576d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
577d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	reply = g_dbus_create_error_valist(message, name, format, args);
578d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
579d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	va_end(args);
580d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann
581d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann	return reply;
582d0b06ea8fd1a8642c99d6b2c7661d562acf3c43eMarcel Holtmann}
583671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
584671e8bc7340909da8b0fe750176423113e9ea8c1Marcel HoltmannDBusMessage *g_dbus_create_reply_valist(DBusMessage *message,
585671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann						int type, va_list args)
586671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann{
587671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	DBusMessage *reply;
588671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
589671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	reply = dbus_message_new_method_return(message);
590671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	if (reply == NULL)
591671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann		return NULL;
592671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
593671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	if (dbus_message_append_args_valist(reply, type, args) == FALSE) {
594671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann		dbus_message_unref(reply);
595671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann		return NULL;
596671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	}
597671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
598671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	return reply;
599671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann}
600671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
601671e8bc7340909da8b0fe750176423113e9ea8c1Marcel HoltmannDBusMessage *g_dbus_create_reply(DBusMessage *message, int type, ...)
602671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann{
603671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	va_list args;
604671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	DBusMessage *reply;
605671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
606671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	va_start(args, type);
607671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
608671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	reply = g_dbus_create_reply_valist(message, type, args);
609671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
610671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	va_end(args);
611671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann
612671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann	return reply;
613671e8bc7340909da8b0fe750176423113e9ea8c1Marcel Holtmann}
61480d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
61580d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmanngboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
61680d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann{
61780d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	dbus_bool_t result;
61880d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
619b892677f0ba83e28daf6c05561295c1145d1c59fMarcel Holtmann	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
620b892677f0ba83e28daf6c05561295c1145d1c59fMarcel Holtmann		dbus_message_set_no_reply(message, TRUE);
621b892677f0ba83e28daf6c05561295c1145d1c59fMarcel Holtmann
62280d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	result = dbus_connection_send(connection, message, NULL);
62380d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
62480d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	dbus_message_unref(message);
62580d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
62680d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	return result;
62780d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann}
62880d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
62980d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmanngboolean g_dbus_send_reply_valist(DBusConnection *connection,
63080d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann				DBusMessage *message, int type, va_list args)
63180d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann{
63280d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	DBusMessage *reply;
63380d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
63480d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	reply = dbus_message_new_method_return(message);
63580d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	if (reply == NULL)
63680d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann		return FALSE;
63780d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
63880d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	if (dbus_message_append_args_valist(reply, type, args) == FALSE) {
63980d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann		dbus_message_unref(reply);
64080d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann		return FALSE;
64180d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	}
64280d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
64380d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	return g_dbus_send_message(connection, reply);
64480d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann}
64580d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
64680d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmanngboolean g_dbus_send_reply(DBusConnection *connection,
64780d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann				DBusMessage *message, int type, ...)
64880d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann{
64980d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	va_list args;
65080d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	gboolean result;
65180d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
65280d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	va_start(args, type);
65380d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
65480d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	result = g_dbus_send_reply_valist(connection, message, type, args);
65580d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
65680d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	va_end(args);
65780d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann
65880d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann	return result;
65980d6914d167a731d97aff4e25497f84e96e09fe3Marcel Holtmann}
660f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
661f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmanngboolean g_dbus_emit_signal(DBusConnection *connection,
662f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann				const char *path, const char *interface,
663f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann				const char *name, int type, ...)
664f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann{
66514673292786fe0c37ed2953cadedd2e200759887Marcel Holtmann	va_list args;
666f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann	gboolean result;
667f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
66814673292786fe0c37ed2953cadedd2e200759887Marcel Holtmann	va_start(args, type);
669f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
670f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann	result = emit_signal_valist(connection, path, interface,
671f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann							name, type, args);
672f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
67314673292786fe0c37ed2953cadedd2e200759887Marcel Holtmann	va_end(args);
674f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
67514673292786fe0c37ed2953cadedd2e200759887Marcel Holtmann	return result;
676f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann}
677f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann
678f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmanngboolean g_dbus_emit_signal_valist(DBusConnection *connection,
679f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann				const char *path, const char *interface,
680f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann				const char *name, int type, va_list args)
681f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann{
682f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann	return emit_signal_valist(connection, path, interface,
683f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann							name, type, args);
684f06919f22999bd132ae6d84191245387eae9d733Marcel Holtmann}
685