update the jack2 submodule to contain the fix for #103
[ladish.git] / proxies / a2j_proxy.c
blob559478264d89c75cc707a54102980168e3d1707a
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains code that interface with a2jmidid through D-Bus
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "a2j_proxy.h"
29 #define A2J_SERVICE "org.gna.home.a2jmidid"
30 #define A2J_OBJECT "/"
31 #define A2J_IFACE_CONTROL "org.gna.home.a2jmidid.control"
33 static bool g_a2j_started = false;
34 static char * g_a2j_jack_client_name = NULL;
36 static void on_a2j_bridge_started(void * context, DBusMessage * message_ptr)
38 log_info("a2j bridge start detected.");
40 if (g_a2j_jack_client_name != NULL)
42 free(g_a2j_jack_client_name);
43 g_a2j_jack_client_name = NULL;
46 g_a2j_started = true;
49 static void on_a2j_bridge_stopped(void * context, DBusMessage * message_ptr)
51 if (g_a2j_jack_client_name != NULL)
53 free(g_a2j_jack_client_name);
54 g_a2j_jack_client_name = NULL;
57 g_a2j_started = false;
59 log_info("a2j bridge stop detected.");
62 static void on_a2j_life_status_changed(bool appeared)
64 if (appeared)
66 log_info("a2j activatation detected.");
68 else
70 log_info("a2j deactivatation detected.");
74 /* this must be static because it is referenced by the
75 * dbus helper layer when hooks are active */
76 static struct dbus_signal_hook g_signal_hooks[] =
78 {"bridge_started", on_a2j_bridge_started},
79 {"bridge_stopped", on_a2j_bridge_stopped},
80 {NULL, NULL}
83 bool a2j_proxy_init(void)
85 g_a2j_started = a2j_proxy_is_started();
86 if (g_a2j_started)
88 a2j_proxy_get_jack_client_name_noncached(&g_a2j_jack_client_name);
91 if (!dbus_register_service_lifetime_hook(g_dbus_connection, A2J_SERVICE, on_a2j_life_status_changed))
93 log_error("dbus_register_service_lifetime_hook() failed for a2j service");
94 return false;
97 if (!dbus_register_object_signal_hooks(
98 g_dbus_connection,
99 A2J_SERVICE,
100 A2J_OBJECT,
101 A2J_IFACE_CONTROL,
102 NULL,
103 g_signal_hooks))
105 dbus_unregister_service_lifetime_hook(g_dbus_connection, A2J_SERVICE);
106 log_error("dbus_register_object_signal_hooks() failed for a2j control interface");
107 return false;
110 return true;
113 void a2j_proxy_uninit(void)
115 dbus_unregister_object_signal_hooks(g_dbus_connection, A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL);
116 dbus_unregister_service_lifetime_hook(g_dbus_connection, A2J_SERVICE);
119 const char * a2j_proxy_get_jack_client_name_cached(void)
121 if (g_a2j_jack_client_name == NULL)
123 a2j_proxy_get_jack_client_name_noncached(&g_a2j_jack_client_name);
126 return g_a2j_jack_client_name;
129 bool a2j_proxy_get_jack_client_name_noncached(char ** client_name_ptr_ptr)
131 DBusMessage * reply_ptr;
132 const char * name;
134 if (!dbus_call(A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL, "get_jack_client_name", "", NULL, &reply_ptr))
136 //log_error("a2j::get_jack_client_name() failed.");
137 return false;
140 if (!dbus_message_get_args(reply_ptr, &g_dbus_error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
142 dbus_message_unref(reply_ptr);
143 dbus_error_free(&g_dbus_error);
144 log_error("decoding reply of get_jack_client_name failed.");
145 return false;
148 *client_name_ptr_ptr = strdup(name);
150 dbus_message_unref(reply_ptr);
152 if (*client_name_ptr_ptr == NULL)
154 log_error("strdup() failed for a2j jack client name string");
155 return false;
158 return true;
161 bool
162 a2j_proxy_map_jack_port(
163 const char * jack_port_name,
164 char ** alsa_client_name_ptr_ptr,
165 char ** alsa_port_name_ptr_ptr,
166 uint32_t * alsa_client_id_ptr)
168 DBusMessage * reply_ptr;
169 dbus_uint32_t alsa_client_id;
170 dbus_uint32_t alsa_port_id;
171 const char * alsa_client_name;
172 const char * alsa_port_name;
174 if (!dbus_call(A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL, "map_jack_port_to_alsa", "s", &jack_port_name, NULL, &reply_ptr))
176 log_error("a2j::map_jack_port_to_alsa() failed.");
177 return false;
180 if (!dbus_message_get_args(
181 reply_ptr,
182 &g_dbus_error,
183 DBUS_TYPE_UINT32,
184 &alsa_client_id,
185 DBUS_TYPE_UINT32,
186 &alsa_port_id,
187 DBUS_TYPE_STRING,
188 &alsa_client_name,
189 DBUS_TYPE_STRING,
190 &alsa_port_name,
191 DBUS_TYPE_INVALID))
193 dbus_message_unref(reply_ptr);
194 dbus_error_free(&g_dbus_error);
195 log_error("decoding reply of map_jack_port_to_alsa failed.");
196 return false;
199 *alsa_client_name_ptr_ptr = strdup(alsa_client_name);
200 if (*alsa_client_name_ptr_ptr == NULL)
202 dbus_message_unref(reply_ptr);
203 log_error("strdup() failed for a2j alsa client name string");
204 return false;
207 *alsa_port_name_ptr_ptr = strdup(alsa_port_name);
208 if (*alsa_port_name_ptr_ptr == NULL)
210 dbus_message_unref(reply_ptr);
211 log_error("strdup() failed for a2j alsa port name string");
212 free(*alsa_client_name_ptr_ptr);
213 return false;
216 *alsa_client_id_ptr = alsa_client_id;
218 dbus_message_unref(reply_ptr);
220 return true;
223 bool a2j_proxy_is_started(void)
225 dbus_bool_t started;
227 if (!dbus_call(A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL, "is_started", "", "b", &started))
229 log_error("a2j::is_started() failed.");
230 return false;
233 return started;
236 bool a2j_proxy_start_bridge(void)
238 if (!dbus_call(A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL, "start", "", ""))
240 log_error("a2j::start() failed.");
241 return false;
244 return true;
247 bool a2j_proxy_stop_bridge(void)
249 if (!dbus_call(A2J_SERVICE, A2J_OBJECT, A2J_IFACE_CONTROL, "stop", "", ""))
251 log_error("a2j::stop() failed.");
252 return false;
255 return true;