Remove reset_drivers parameter of jack_reset_all_params()
[ladish.git] / gui / a2j_proxy.cpp
blob25f16a8db51751228e0d6b72fb4b908d4e21d921
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008 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 "common.h"
29 #include <dbus/dbus.h>
31 #include "a2j_proxy.hpp"
32 #include "Patchage.hpp"
33 #include "globals.hpp"
34 #include "dbus_helpers.h"
36 #define A2J_SERVICE "org.gna.home.a2jmidid"
37 #define A2J_OBJECT "/"
38 #define A2J_IFACE_CONTROL "org.gna.home.a2jmidid.control"
40 static
41 void
42 error_msg(
43 const std::string& msg)
45 g_app->error_msg((std::string)"[A2J] " + msg);
48 static
49 void
50 info_msg(
51 const std::string& msg)
53 g_app->info_msg((std::string)"[A2J] " + msg);
56 struct a2j_proxy_impl
58 void
59 init();
61 static
62 DBusHandlerResult
63 dbus_message_hook(
64 DBusConnection * connection,
65 DBusMessage * message,
66 void * proxy);
68 bool
69 call(
70 bool response_expected,
71 const char* iface,
72 const char* method,
73 DBusMessage ** reply_ptr_ptr,
74 int in_type,
75 ...);
77 bool
78 get_jack_client_name(
79 std::string& jack_client_name_ref);
81 bool
82 is_started();
84 bool _server_responding;
85 std::string _jack_client_name;
88 a2j_proxy::a2j_proxy()
90 _impl_ptr = new a2j_proxy_impl;
91 _impl_ptr->init();
94 a2j_proxy::~a2j_proxy()
96 delete _impl_ptr;
99 const char *
100 a2j_proxy::get_jack_client_name()
102 return _impl_ptr->_jack_client_name.c_str();
105 void
106 a2j_proxy_impl::init()
108 unsigned int status;
110 _server_responding = false;
112 patchage_dbus_add_match("type='signal',interface='" DBUS_INTERFACE_DBUS "',member=NameOwnerChanged,arg0='" A2J_SERVICE "'");
113 patchage_dbus_add_match("type='signal',interface='" A2J_IFACE_CONTROL "',member=bridge_started");
114 patchage_dbus_add_match("type='signal',interface='" A2J_IFACE_CONTROL "',member=bridge_stopped");
116 patchage_dbus_add_filter(dbus_message_hook, this);
118 // get jack client name
119 // calling any method to updates server responding status
120 // this also actiavtes a2j object if it not activated already
121 get_jack_client_name(_jack_client_name);
123 if (is_started())
125 status = A2J_STATUS_BRIDGE_STARTED;
127 else
129 if (!_server_responding)
131 status = A2J_STATUS_NO_RESPONSE;
133 else
135 status = A2J_STATUS_BRIDGE_STOPPED;
139 g_app->set_a2j_status(status);
142 DBusHandlerResult
143 a2j_proxy_impl::dbus_message_hook(
144 DBusConnection * connection,
145 DBusMessage * message,
146 void * proxy)
148 const char * object_name;
149 const char * old_owner;
150 const char * new_owner;
152 assert(proxy);
153 //a2j_proxy_impl * me = reinterpret_cast<a2j_proxy_impl *>(proxy);
155 //info_msg("dbus_message_hook() called.");
157 // Handle signals we have subscribed for in attach()
159 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
161 if (!dbus_message_get_args(
162 message, &g_dbus_error,
163 DBUS_TYPE_STRING, &object_name,
164 DBUS_TYPE_STRING, &old_owner,
165 DBUS_TYPE_STRING, &new_owner,
166 DBUS_TYPE_INVALID))
168 error_msg(str(boost::format("dbus_message_get_args() failed to extract NameOwnerChanged signal arguments (%s)") % g_dbus_error.message));
169 dbus_error_free(&g_dbus_error);
170 return DBUS_HANDLER_RESULT_HANDLED;
173 if ((std::string)object_name != A2J_SERVICE)
175 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
178 if (old_owner[0] == '\0')
180 info_msg((std::string)"A2J activated.");
181 g_app->set_a2j_status(A2J_STATUS_BRIDGE_STOPPED);
183 else if (new_owner[0] == '\0')
185 info_msg((std::string)"A2J deactivated.");
186 g_app->set_a2j_status(A2J_STATUS_NO_RESPONSE);
189 return DBUS_HANDLER_RESULT_HANDLED;
192 if (dbus_message_is_signal(message, A2J_IFACE_CONTROL, "bridge_started"))
194 info_msg("bridge started.");
195 g_app->set_a2j_status(A2J_STATUS_BRIDGE_STARTED);
197 return DBUS_HANDLER_RESULT_HANDLED;
200 if (dbus_message_is_signal(message, A2J_IFACE_CONTROL, "bridge_stopped"))
202 info_msg("bridge stopped.");
203 g_app->set_a2j_status(A2J_STATUS_BRIDGE_STOPPED);
205 return DBUS_HANDLER_RESULT_HANDLED;
208 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
211 bool
212 a2j_proxy_impl::call(
213 bool response_expected,
214 const char* iface,
215 const char* method,
216 DBusMessage ** reply_ptr_ptr,
217 int in_type,
218 ...)
220 va_list ap;
222 va_start(ap, in_type);
224 _server_responding = patchage_dbus_call_valist(
225 response_expected,
226 A2J_SERVICE,
227 A2J_OBJECT,
228 iface,
229 method,
230 reply_ptr_ptr,
231 in_type,
232 ap);
234 va_end(ap);
236 return _server_responding;
239 bool
240 a2j_proxy_impl::get_jack_client_name(
241 std::string& jack_client_name_ref)
243 DBusMessage * reply_ptr;
244 const char * jack_client_name;
246 if (!call(true, A2J_IFACE_CONTROL, "get_jack_client_name", &reply_ptr, DBUS_TYPE_INVALID))
248 return false;
251 if (!dbus_message_get_args(reply_ptr, &g_dbus_error, DBUS_TYPE_STRING, &jack_client_name, DBUS_TYPE_INVALID))
253 dbus_message_unref(reply_ptr);
254 dbus_error_free(&g_dbus_error);
255 error_msg("decoding reply of get_jack_client_name failed.");
256 return false;
259 jack_client_name_ref = jack_client_name;
261 dbus_message_unref(reply_ptr);
263 return true;
266 bool
267 a2j_proxy::map_jack_port(
268 const char * jack_port_name,
269 std::string& alsa_client_name_ref,
270 std::string& alsa_port_name_ref,
271 uint32_t& alsa_client_id_ref)
273 DBusMessage * reply_ptr;
274 dbus_uint32_t alsa_client_id;
275 dbus_uint32_t alsa_port_id;
276 const char * alsa_client_name;
277 const char * alsa_port_name;
279 if (!_impl_ptr->call(
280 true,
281 A2J_IFACE_CONTROL,
282 "map_jack_port_to_alsa",
283 &reply_ptr,
284 DBUS_TYPE_STRING,
285 &jack_port_name,
286 DBUS_TYPE_INVALID))
288 return false;
291 if (!dbus_message_get_args(
292 reply_ptr,
293 &g_dbus_error,
294 DBUS_TYPE_UINT32,
295 &alsa_client_id,
296 DBUS_TYPE_UINT32,
297 &alsa_port_id,
298 DBUS_TYPE_STRING,
299 &alsa_client_name,
300 DBUS_TYPE_STRING,
301 &alsa_port_name,
302 DBUS_TYPE_INVALID))
304 dbus_message_unref(reply_ptr);
305 dbus_error_free(&g_dbus_error);
306 error_msg("decoding reply of map_jack_port_to_alsa failed.");
307 return false;
310 alsa_client_name_ref = alsa_client_name;
311 alsa_port_name_ref = alsa_port_name;
312 alsa_client_id_ref = alsa_client_id;
314 dbus_message_unref(reply_ptr);
316 return true;
319 bool
320 a2j_proxy_impl::is_started()
322 DBusMessage * reply_ptr;
323 dbus_bool_t started;
325 if (!call(true, A2J_IFACE_CONTROL, "is_started", &reply_ptr, DBUS_TYPE_INVALID))
327 return false;
330 if (!dbus_message_get_args(reply_ptr, &g_dbus_error, DBUS_TYPE_BOOLEAN, &started, DBUS_TYPE_INVALID))
332 dbus_message_unref(reply_ptr);
333 dbus_error_free(&g_dbus_error);
334 error_msg("decoding reply of is_started failed.");
335 return false;
338 dbus_message_unref(reply_ptr);
340 return started;
343 void
344 a2j_proxy::start_bridge()
346 DBusMessage * reply_ptr;
348 if (!_impl_ptr->call(true, A2J_IFACE_CONTROL, "start", &reply_ptr, DBUS_TYPE_INVALID))
350 return;
353 dbus_message_unref(reply_ptr);
356 void
357 a2j_proxy::stop_bridge()
359 DBusMessage * reply_ptr;
361 if (!_impl_ptr->call(true, A2J_IFACE_CONTROL, "stop", &reply_ptr, DBUS_TYPE_INVALID))
363 return;
366 dbus_message_unref(reply_ptr);