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=\"GetAddress\">"
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_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 if (conf
->default_dbus_server
) {
124 address
= pa_xstrdup(conf
->default_dbus_server
);
126 if (!(address
= pa_get_dbus_address_from_server_type(sl
->core
->server_type
))) {
127 if (!(reply
= dbus_message_new_error(msg
, DBUS_ERROR_FAILED
, "PulseAudio internal error: get_dbus_server_from_type() failed.")))
129 if (!dbus_connection_send(conn
, reply
, NULL
))
131 return DBUS_HANDLER_RESULT_HANDLED
;
135 if (!(reply
= dbus_message_new_method_return(msg
)))
138 if (!dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &address
, DBUS_TYPE_INVALID
))
141 if (!dbus_connection_send(conn
, reply
, NULL
))
144 pa_client_conf_free(conf
);
146 dbus_message_unref(reply
);
148 return DBUS_HANDLER_RESULT_HANDLED
;
152 pa_client_conf_free(conf
);
157 dbus_message_unref(reply
);
159 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
163 pa_client_conf_free(conf
);
168 dbus_message_unref(reply
);
170 return DBUS_HANDLER_RESULT_NEED_MEMORY
;
173 static DBusHandlerResult
message_cb(DBusConnection
*conn
, DBusMessage
*msg
, void *user_data
) {
174 pa_dbusobj_server_lookup
*sl
= user_data
;
180 /* 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)); */
182 if (dbus_message_is_method_call(msg
, "org.freedesktop.DBus.Introspectable", "Introspect"))
183 return handle_introspect(conn
, msg
, sl
);
185 if (dbus_message_is_method_call(msg
, "org.pulseaudio.ServerLookup", "GetAddress"))
186 return handle_get_address(conn
, msg
, sl
);
188 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
191 static DBusObjectPathVTable vtable
= {
192 .unregister_function
= unregister_cb
,
193 .message_function
= message_cb
,
194 .dbus_internal_pad1
= NULL
,
195 .dbus_internal_pad2
= NULL
,
196 .dbus_internal_pad3
= NULL
,
197 .dbus_internal_pad4
= NULL
200 pa_dbusobj_server_lookup
*pa_dbusobj_server_lookup_new(pa_core
*c
) {
201 pa_dbusobj_server_lookup
*sl
;
204 dbus_error_init(&error
);
206 sl
= pa_xnew(pa_dbusobj_server_lookup
, 1);
208 sl
->path_registered
= FALSE
;
210 if (!(sl
->conn
= pa_dbus_bus_get(c
, DBUS_BUS_SESSION
, &error
)) || dbus_error_is_set(&error
)) {
211 pa_log("Unable to contact D-Bus: %s: %s", error
.name
, error
.message
);
215 if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl
->conn
), "/org/pulseaudio/server_lookup", &vtable
, sl
)) {
216 pa_log("dbus_connection_register_object_path() failed for /org/pulseaudio/server_lookup.");
220 sl
->path_registered
= TRUE
;
225 dbus_error_free(&error
);
227 pa_dbusobj_server_lookup_free(sl
);
232 void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup
*sl
) {
235 if (sl
->path_registered
) {
237 if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl
->conn
), "/org/pulseaudio/server_lookup"))
238 pa_log_debug("dbus_connection_unregister_object_path() failed for /org/pulseaudio/server_lookup.");
242 pa_dbus_connection_unref(sl
->conn
);