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 #define OBJECT_PATH "/org/pulseaudio1/server_lookup"
40 #define INTERFACE "org.pulseaudio.ServerLookup1"
42 struct pa_dbusobj_server_lookup
{
44 pa_dbus_connection
*conn
;
45 pa_bool_t path_registered
;
48 static const char introspection
[] =
49 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
51 " <!-- If you are looking for documentation make sure to check out\n"
52 " http://pulseaudio.org/wiki/DBusInterface -->\n"
53 " <interface name=\"" INTERFACE
"\">"
54 " <method name=\"GetAddress\">"
55 " <arg name=\"result\" type=\"s\" direction=\"out\"/>"
58 " <interface name=\"org.freedesktop.DBus.Introspectable\">"
59 " <method name=\"Introspect\">"
60 " <arg name=\"data\" type=\"s\" direction=\"out\"/>"
65 static void unregister_cb(DBusConnection
*conn
, void *user_data
) {
66 pa_dbusobj_server_lookup
*sl
= user_data
;
69 pa_assert(sl
->path_registered
);
71 sl
->path_registered
= FALSE
;
74 static DBusHandlerResult
handle_introspect(DBusConnection
*conn
, DBusMessage
*msg
, pa_dbusobj_server_lookup
*sl
) {
75 const char *i
= introspection
;
76 DBusMessage
*reply
= NULL
;
81 if (!(reply
= dbus_message_new_method_return(msg
)))
84 if (!dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &i
, DBUS_TYPE_INVALID
))
87 if (!dbus_connection_send(conn
, reply
, NULL
))
90 dbus_message_unref(reply
);
92 return DBUS_HANDLER_RESULT_HANDLED
;
96 dbus_message_unref(reply
);
98 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
102 dbus_message_unref(reply
);
104 return DBUS_HANDLER_RESULT_NEED_MEMORY
;
107 static DBusHandlerResult
handle_get_address(DBusConnection
*conn
, DBusMessage
*msg
, pa_dbusobj_server_lookup
*sl
) {
108 DBusMessage
*reply
= NULL
;
109 pa_client_conf
*conf
= NULL
;
110 char *address
= NULL
;
116 conf
= pa_client_conf_new();
118 if (pa_client_conf_load(conf
, NULL
) < 0) {
119 if (!(reply
= dbus_message_new_error(msg
, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf.")))
121 if (!dbus_connection_send(conn
, reply
, NULL
))
123 return DBUS_HANDLER_RESULT_HANDLED
;
126 if (conf
->default_dbus_server
) {
127 address
= pa_xstrdup(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
, "PulseAudio internal error: 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_client_conf_free(conf
);
149 dbus_message_unref(reply
);
151 return DBUS_HANDLER_RESULT_HANDLED
;
155 pa_client_conf_free(conf
);
160 dbus_message_unref(reply
);
162 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
166 pa_client_conf_free(conf
);
171 dbus_message_unref(reply
);
173 return DBUS_HANDLER_RESULT_NEED_MEMORY
;
176 static DBusHandlerResult
message_cb(DBusConnection
*conn
, DBusMessage
*msg
, void *user_data
) {
177 pa_dbusobj_server_lookup
*sl
= user_data
;
183 /* 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)); */
185 if (dbus_message_is_method_call(msg
, "org.freedesktop.DBus.Introspectable", "Introspect"))
186 return handle_introspect(conn
, msg
, sl
);
188 if (dbus_message_is_method_call(msg
, INTERFACE
, "GetAddress"))
189 return handle_get_address(conn
, msg
, sl
);
191 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
194 static DBusObjectPathVTable vtable
= {
195 .unregister_function
= unregister_cb
,
196 .message_function
= message_cb
,
197 .dbus_internal_pad1
= NULL
,
198 .dbus_internal_pad2
= NULL
,
199 .dbus_internal_pad3
= NULL
,
200 .dbus_internal_pad4
= NULL
203 pa_dbusobj_server_lookup
*pa_dbusobj_server_lookup_new(pa_core
*c
) {
204 pa_dbusobj_server_lookup
*sl
;
207 dbus_error_init(&error
);
209 sl
= pa_xnew(pa_dbusobj_server_lookup
, 1);
211 sl
->path_registered
= FALSE
;
213 if (!(sl
->conn
= pa_dbus_bus_get(c
, DBUS_BUS_SESSION
, &error
)) || dbus_error_is_set(&error
)) {
214 pa_log("Unable to contact D-Bus: %s: %s", error
.name
, error
.message
);
218 if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl
->conn
), OBJECT_PATH
, &vtable
, sl
)) {
219 pa_log("dbus_connection_register_object_path() failed for " OBJECT_PATH
".");
223 sl
->path_registered
= TRUE
;
228 dbus_error_free(&error
);
230 pa_dbusobj_server_lookup_free(sl
);
235 void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup
*sl
) {
238 if (sl
->path_registered
) {
240 if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl
->conn
), OBJECT_PATH
))
241 pa_log_debug("dbus_connection_unregister_object_path() failed for " OBJECT_PATH
".");
245 pa_dbus_connection_unref(sl
->conn
);