2 This file is part of PulseAudio.
4 Copyright 2009 Tanu Kaskinen
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 #include <dbus/dbus.h>
28 #include <pulse/client-conf.h>
29 #include <pulse/xmalloc.h>
31 #include <pulsecore/core.h>
32 #include <pulsecore/core-util.h>
33 #include <pulsecore/dbus-common.h>
34 #include <pulsecore/dbus-shared.h>
35 #include <pulsecore/macro.h>
37 #include "server-lookup.h"
39 struct pa_dbusobj_server_lookup
{
41 pa_dbus_connection
*conn
;
42 pa_bool_t path_registered
;
45 static const char introspection
[] =
46 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
48 " <!-- If you are looking for documentation make sure to check out\n"
49 " http://pulseaudio.org/wiki/DBusInterface -->\n"
50 " <interface name=\"org.pulseaudio.ServerLookup\">"
51 " <method name=\"GetDBusAddress\">"
52 " <arg name=\"result\" type=\"s\" direction=\"out\"/>"
55 " <interface name=\"org.freedesktop.DBus.Introspectable\">"
56 " <method name=\"Introspect\">"
57 " <arg name=\"data\" type=\"s\" direction=\"out\"/>"
62 static void unregister_cb(DBusConnection
*conn
, void *user_data
) {
63 pa_dbusobj_server_lookup
*sl
= user_data
;
66 pa_assert(sl
->path_registered
);
68 sl
->path_registered
= FALSE
;
71 static DBusHandlerResult
handle_introspect(DBusConnection
*conn
, DBusMessage
*msg
, pa_dbusobj_server_lookup
*sl
) {
72 const char *i
= introspection
;
73 DBusMessage
*reply
= NULL
;
78 if (!(reply
= dbus_message_new_method_return(msg
)))
81 if (!dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &i
, DBUS_TYPE_INVALID
))
84 if (!dbus_connection_send(conn
, reply
, NULL
))
87 dbus_message_unref(reply
);
89 return DBUS_HANDLER_RESULT_HANDLED
;
93 dbus_message_unref(reply
);
95 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
99 dbus_message_unref(reply
);
101 return DBUS_HANDLER_RESULT_NEED_MEMORY
;
104 static DBusHandlerResult
handle_get_dbus_address(DBusConnection
*conn
, DBusMessage
*msg
, pa_dbusobj_server_lookup
*sl
) {
105 DBusMessage
*reply
= NULL
;
106 pa_client_conf
*conf
= NULL
;
107 char *address
= NULL
;
113 conf
= pa_client_conf_new();
115 if (pa_client_conf_load(conf
, NULL
) < 0) {
116 if (!(reply
= dbus_message_new_error(msg
, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf.")))
118 if (!dbus_connection_send(conn
, reply
, NULL
))
120 return DBUS_HANDLER_RESULT_HANDLED
;
123 pa_client_conf_free(conf
);
125 if (conf
->default_dbus_server
) {
126 if (!(address
= dbus_address_escape_value(conf
->default_dbus_server
)))
129 if (!(address
= pa_get_dbus_address_from_server_type(sl
->core
->server_type
))) {
130 if (!(reply
= dbus_message_new_error(msg
, DBUS_ERROR_FAILED
, "get_dbus_server_from_type() failed.")))
132 if (!dbus_connection_send(conn
, reply
, NULL
))
134 return DBUS_HANDLER_RESULT_HANDLED
;
138 if (!(reply
= dbus_message_new_method_return(msg
)))
141 if (!dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &address
, DBUS_TYPE_INVALID
))
144 if (!dbus_connection_send(conn
, reply
, NULL
))
147 pa_log_debug("handle_get_dbus_address(): Sent reply with address '%s'.", address
);
151 dbus_message_unref(reply
);
153 return DBUS_HANDLER_RESULT_HANDLED
;
157 pa_client_conf_free(conf
);
162 dbus_message_unref(reply
);
164 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
168 pa_client_conf_free(conf
);
173 dbus_message_unref(reply
);
175 return DBUS_HANDLER_RESULT_NEED_MEMORY
;
178 static DBusHandlerResult
message_cb(DBusConnection
*conn
, DBusMessage
*msg
, void *user_data
) {
179 pa_dbusobj_server_lookup
*sl
= user_data
;
185 /* pa_log("Got message! type = %s path = %s iface = %s member = %s dest = %s", dbus_message_type_to_string(dbus_message_get_type(msg)), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), dbus_message_get_destination(msg)); */
187 if (dbus_message_is_method_call(msg
, "org.freedesktop.DBus.Introspectable", "Introspect"))
188 return handle_introspect(conn
, msg
, sl
);
190 if (dbus_message_is_method_call(msg
, "org.pulseaudio.ServerLookup", "GetDBusAddress"))
191 return handle_get_dbus_address(conn
, msg
, sl
);
193 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
196 static DBusObjectPathVTable vtable
= {
197 .unregister_function
= unregister_cb
,
198 .message_function
= message_cb
,
199 .dbus_internal_pad1
= NULL
,
200 .dbus_internal_pad2
= NULL
,
201 .dbus_internal_pad3
= NULL
,
202 .dbus_internal_pad4
= NULL
205 pa_dbusobj_server_lookup
*pa_dbusobj_server_lookup_new(pa_core
*c
) {
206 pa_dbusobj_server_lookup
*sl
;
209 dbus_error_init(&error
);
211 sl
= pa_xnew(pa_dbusobj_server_lookup
, 1);
213 sl
->path_registered
= FALSE
;
215 if (!(sl
->conn
= pa_dbus_bus_get(c
, DBUS_BUS_SESSION
, &error
)) || dbus_error_is_set(&error
)) {
216 pa_log("Unable to contact D-Bus: %s: %s", error
.name
, error
.message
);
220 if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl
->conn
), "/org/pulseaudio/server_lookup", &vtable
, sl
)) {
221 pa_log("dbus_connection_register_object_path() failed for /org/pulseaudio/server_lookup.");
225 sl
->path_registered
= TRUE
;
230 dbus_error_free(&error
);
232 pa_dbusobj_server_lookup_free(sl
);
237 void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup
*sl
) {
240 if (sl
->path_registered
) {
242 if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl
->conn
), "/org/pulseaudio/server_lookup"))
243 pa_log_debug("dbus_connection_unregister_object_path() failed for /org/pulseaudio/server_lookup.");
247 pa_dbus_connection_unref(sl
->conn
);