Restore JACK parameters during studio load. Closes #2
[ladish.git] / dbus / object_path.c
blob2d5b92eeb860d245996891b75889d66347c39716
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
8 **************************************************************************
9 * This file contains D-Bus object path helpers
10 **************************************************************************
12 * LADI Session Handler is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * LADI Session Handler is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
24 * or write to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdarg.h>
32 #include "object_path.h"
33 #include "../common/safety.h"
34 #include "../common/debug.h"
35 #include "introspection.h" /* g_dbus_interface_dtor_introspectable */
36 #include "error.h" /* lash_dbus_error() */
38 static DBusHandlerResult
39 object_path_handler(DBusConnection *connection,
40 DBusMessage *message,
41 void *data);
43 static void
44 object_path_handler_unregister(DBusConnection *conn,
45 void *data);
47 object_path_t *
48 object_path_new(const char *name,
49 void *context,
50 int num_ifaces,
51 ...)
53 if (!name || !name[0] || num_ifaces < 0)
55 lash_error("Invalid arguments");
56 return NULL;
59 lash_debug("Creating object path");
61 object_path_t *path;
62 va_list argp;
63 const interface_t **iface_pptr;
65 path = lash_malloc(1, sizeof(object_path_t));
66 path->name = lash_strdup(name);
67 path->interfaces = lash_malloc(num_ifaces + 2, sizeof(interface_t *));
69 va_start(argp, num_ifaces);
71 iface_pptr = path->interfaces;
72 *iface_pptr++ = &g_dbus_interface_dtor_introspectable;
73 while (num_ifaces > 0)
75 *iface_pptr++ = va_arg(argp, const interface_t *);
76 num_ifaces--;
78 *iface_pptr = NULL;
80 va_end(argp);
82 if ((path->introspection = introspection_new(path))) {
83 path->context = context;
84 return path;
87 lash_error("Failed to create object path");
88 object_path_destroy(NULL, path);
90 return NULL;
93 bool
94 object_path_register(DBusConnection *conn,
95 object_path_t *path)
97 if (!conn || !path || !path->name || !path->interfaces) {
98 lash_debug("Invalid arguments");
99 return false;
102 lash_debug("Registering object path");
104 DBusObjectPathVTable vtable =
106 object_path_handler_unregister,
107 object_path_handler,
108 NULL, NULL, NULL, NULL
111 dbus_connection_register_object_path(conn, path->name,
112 &vtable, (void *) path);
114 return true;
117 void object_path_destroy(DBusConnection * connection_ptr, object_path_t * path_ptr)
119 lash_debug("Destroying object path");
121 if (path_ptr)
123 if (connection_ptr != NULL && !dbus_connection_unregister_object_path(connection_ptr, path_ptr->name))
125 lash_error("dbus_connection_unregister_object_path() failed.");
128 if (path_ptr->name)
130 free(path_ptr->name);
131 path_ptr->name = NULL;
134 if (path_ptr->interfaces)
136 free(path_ptr->interfaces);
137 path_ptr->interfaces = NULL;
140 introspection_destroy(path_ptr);
141 free(path_ptr);
143 #ifdef LASH_DEBUG
144 else
146 lash_debug("Nothing to destroy");
148 #endif
152 static DBusHandlerResult
153 object_path_handler(DBusConnection *connection,
154 DBusMessage *message,
155 void *data)
157 const char *interface_name;
158 const interface_t **iface_pptr;
159 method_call_t call;
161 /* Check if the message is a method call. If not, ignore it. */
162 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
163 goto handled;
166 /* Get the invoked method's name and make sure it's non-NULL. */
167 if (!(call.method_name = dbus_message_get_member(message))) {
168 lash_dbus_error(&call, LASH_DBUS_ERROR_UNKNOWN_METHOD,
169 "Received method call with empty method name");
170 goto send_return;
173 /* Initialize our data. */
174 call.connection = connection;
175 call.message = message;
176 call.interface = NULL; /* To be set by the default interface handler */
177 call.context = data;
178 call.reply = NULL;
180 /* Check if there's an interface specified for this method call. */
181 if ((interface_name = dbus_message_get_interface(message)))
183 for (iface_pptr = (const interface_t **) ((object_path_t *) data)->interfaces;
184 iface_pptr && *iface_pptr;
185 ++iface_pptr)
187 if (strcmp(interface_name, (*iface_pptr)->name) == 0)
189 if ((*iface_pptr)->handler(*iface_pptr, &call))
191 goto send_return;
194 break;
198 else
200 /* No interface was specified so we have to try them all. This is
201 * dictated by the D-Bus specification which states that method calls
202 * omitting the interface must never be rejected.
205 for (iface_pptr = (const interface_t **) ((object_path_t *) data)->interfaces;
206 iface_pptr && *iface_pptr;
207 ++iface_pptr) {
208 if ((*iface_pptr)->handler(*iface_pptr, &call)) {
209 goto send_return;
214 lash_dbus_error(&call, LASH_DBUS_ERROR_UNKNOWN_METHOD,
215 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
216 call.method_name, dbus_message_get_signature(message), interface_name);
218 send_return:
219 method_return_send(&call);
221 handled:
222 return DBUS_HANDLER_RESULT_HANDLED;
225 static void
226 object_path_handler_unregister(DBusConnection *conn,
227 void *data)
229 #ifdef LASH_DEBUG
230 object_path_t *path = data;
231 lash_debug("Message handler of object path %s was unregistered",
232 (path && path->name) ? path->name : "<unknown>");
233 #endif /* LASH_DEBUG */
236 /* EOF */