1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
3 Copyright (C) 2007,2008 Nedko Arnaudov
4 Copyright (C) 2007-2008 Juuso Alasuutari
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #if defined(HAVE_CONFIG_H)
27 #include <dbus/dbus.h>
29 #include "controller.h"
30 #include "controller_internal.h"
34 struct jack_dbus_interface_descriptor
* g_jackcontroller_interfaces
[] =
36 &g_jack_controller_iface_introspectable
,
37 &g_jack_controller_iface_control
,
38 &g_jack_controller_iface_configure
,
39 &g_jack_controller_iface_patchbay
,
40 &g_jack_controller_iface_transport
,
45 jack_controller_find_driver(
46 jackctl_server_t
*server
,
47 const char *driver_name
)
49 const JSList
* node_ptr
;
51 node_ptr
= jackctl_server_get_drivers_list(server
);
55 if (strcmp(jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
), driver_name
) == 0)
57 return node_ptr
->data
;
60 node_ptr
= jack_slist_next(node_ptr
);
67 jack_controller_find_internal(
68 jackctl_server_t
*server
,
69 const char *internal_name
)
71 const JSList
* node_ptr
;
73 node_ptr
= jackctl_server_get_internals_list(server
);
77 if (strcmp(jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
), internal_name
) == 0)
79 return node_ptr
->data
;
82 node_ptr
= jack_slist_next(node_ptr
);
89 jack_controller_find_parameter(
90 const JSList
* parameters_list
,
91 const char * parameter_name
)
93 while (parameters_list
)
95 if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t
*)parameters_list
->data
), parameter_name
) == 0)
97 return parameters_list
->data
;
100 parameters_list
= jack_slist_next(parameters_list
);
107 jack_controller_select_driver(
108 struct jack_controller
* controller_ptr
,
109 const char * driver_name
)
111 jackctl_driver_t
*driver
;
113 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
119 jack_info("driver \"%s\" selected", driver_name
);
121 controller_ptr
->driver
= driver
;
122 controller_ptr
->driver_set
= true;
129 jack_controller_xrun(void * arg
)
131 ((struct jack_controller
*)arg
)->xruns
++;
137 jack_controller_start_server(
138 struct jack_controller
* controller_ptr
,
139 void *dbus_call_context_ptr
)
143 jack_info("Starting jack server...");
145 if (controller_ptr
->started
)
147 jack_info("Already started.");
151 if (controller_ptr
->driver
== NULL
)
153 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Select driver first!");
157 controller_ptr
->xruns
= 0;
159 if (!jackctl_server_start(
160 controller_ptr
->server
,
161 controller_ptr
->driver
))
163 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to start server");
167 controller_ptr
->client
= jack_client_open(
171 if (controller_ptr
->client
== NULL
)
173 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to create dbusapi jack client");
175 goto fail_stop_server
;
178 ret
= jack_set_xrun_callback(controller_ptr
->client
, jack_controller_xrun
, controller_ptr
);
181 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to set xrun callback. error is %d", ret
);
183 goto fail_close_client
;
186 if (!jack_controller_patchbay_init(controller_ptr
))
188 jack_error("Failed to initialize patchbay district");
189 goto fail_close_client
;
192 ret
= jack_activate(controller_ptr
->client
);
195 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to activate dbusapi jack client. error is %d", ret
);
197 goto fail_patchbay_uninit
;
200 controller_ptr
->started
= true;
204 fail_patchbay_uninit
:
205 jack_controller_patchbay_uninit(controller_ptr
);
208 ret
= jack_client_close(controller_ptr
->client
);
211 jack_error("jack_client_close() failed with error %d", ret
);
214 controller_ptr
->client
= NULL
;
217 if (!jackctl_server_stop(controller_ptr
->server
))
219 jack_error("failed to stop jack server");
227 jack_controller_stop_server(
228 struct jack_controller
* controller_ptr
,
229 void *dbus_call_context_ptr
)
233 jack_info("Stopping jack server...");
235 if (!controller_ptr
->started
)
237 jack_info("Already stopped.");
241 ret
= jack_deactivate(controller_ptr
->client
);
244 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to deactivate dbusapi jack client. error is %d", ret
);
247 jack_controller_patchbay_uninit(controller_ptr
);
249 ret
= jack_client_close(controller_ptr
->client
);
252 jack_error("jack_client_close() failed with error %d", ret
);
255 controller_ptr
->client
= NULL
;
257 if (!jackctl_server_stop(controller_ptr
->server
))
262 controller_ptr
->started
= false;
268 jack_controller_switch_master(
269 struct jack_controller
* controller_ptr
,
270 void *dbus_call_context_ptr
)
272 if (!jackctl_server_switch_master(
273 controller_ptr
->server
,
274 controller_ptr
->driver
))
276 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to switch master");
285 typedef struct reserved_audio_device
{
287 char device_name
[64];
288 rd_device
* reserved_device
;
290 } reserved_audio_device
;
293 int g_device_count
= 0;
294 static reserved_audio_device g_reserved_device
[DEVICE_MAX
];
298 on_device_acquire(const char * device_name
)
304 &g_reserved_device
[g_device_count
].reserved_device
,
313 jack_error("Failed to acquire device name : %s error : %s", device_name
, (error
.message
? error
.message
: strerror(-ret
)));
317 strcpy(g_reserved_device
[g_device_count
].device_name
, device_name
);
319 jack_info("Acquired audio card %s", device_name
);
325 on_device_release(const char * device_name
)
329 // Look for corresponding reserved device
330 for (i
= 0; i
< DEVICE_MAX
; i
++) {
331 if (strcmp(g_reserved_device
[i
].device_name
, device_name
) == 0)
335 if (i
< DEVICE_MAX
) {
336 jack_info("Released audio card %s", device_name
);
337 rd_release(g_reserved_device
[i
].reserved_device
);
339 jack_error("Audio card %s not found!!", device_name
);
346 jack_controller_create(
347 DBusConnection
*connection
)
349 struct jack_controller
*controller_ptr
;
350 const JSList
* node_ptr
;
351 const char ** driver_name_target
;
352 const char ** internal_name_target
;
355 DBusObjectPathVTable vtable
=
357 jack_dbus_message_handler_unregister
,
358 jack_dbus_message_handler
,
362 controller_ptr
= malloc(sizeof(struct jack_controller
));
365 jack_error("Ran out of memory trying to allocate struct jack_controller");
369 controller_ptr
->server
= jackctl_server_create(on_device_acquire
, on_device_release
);
370 if (controller_ptr
->server
== NULL
)
372 jack_error("Failed to create server object");
376 controller_ptr
->client
= NULL
;
377 controller_ptr
->started
= false;
378 controller_ptr
->driver
= NULL
;
379 controller_ptr
->driver_set
= false;
381 drivers
= (JSList
*)jackctl_server_get_drivers_list(controller_ptr
->server
);
382 controller_ptr
->drivers_count
= jack_slist_length(drivers
);
383 controller_ptr
->driver_names
= malloc(controller_ptr
->drivers_count
* sizeof(const char *));
384 if (controller_ptr
->driver_names
== NULL
)
386 jack_error("Ran out of memory trying to allocate driver names array");
387 goto fail_destroy_server
;
390 driver_name_target
= controller_ptr
->driver_names
;
391 node_ptr
= jackctl_server_get_drivers_list(controller_ptr
->server
);
392 while (node_ptr
!= NULL
)
394 *driver_name_target
= jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
);
396 /* select default driver */
397 if (controller_ptr
->driver
== NULL
&& strcmp(*driver_name_target
, DEFAULT_DRIVER
) == 0)
399 controller_ptr
->driver
= (jackctl_driver_t
*)node_ptr
->data
;
402 node_ptr
= jack_slist_next(node_ptr
);
403 driver_name_target
++;
406 internals
= (JSList
*)jackctl_server_get_internals_list(controller_ptr
->server
);
407 controller_ptr
->internals_count
= jack_slist_length(internals
);
408 controller_ptr
->internal_names
= malloc(controller_ptr
->internals_count
* sizeof(const char *));
409 if (controller_ptr
->internal_names
== NULL
)
411 jack_error("Ran out of memory trying to allocate internals names array");
412 goto fail_free_driver_names_array
;
415 internal_name_target
= controller_ptr
->internal_names
;
416 node_ptr
= jackctl_server_get_internals_list(controller_ptr
->server
);
417 while (node_ptr
!= NULL
)
419 *internal_name_target
= jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
);
420 node_ptr
= jack_slist_next(node_ptr
);
421 internal_name_target
++;
424 controller_ptr
->dbus_descriptor
.context
= controller_ptr
;
425 controller_ptr
->dbus_descriptor
.interfaces
= g_jackcontroller_interfaces
;
427 if (!dbus_connection_register_object_path(
429 JACK_CONTROLLER_OBJECT_PATH
,
431 &controller_ptr
->dbus_descriptor
))
433 jack_error("Ran out of memory trying to register D-Bus object path");
434 goto fail_free_internal_names_array
;
437 jack_controller_settings_load(controller_ptr
);
439 return controller_ptr
;
441 fail_free_internal_names_array
:
442 free(controller_ptr
->internal_names
);
444 fail_free_driver_names_array
:
445 free(controller_ptr
->driver_names
);
448 jackctl_server_destroy(controller_ptr
->server
);
451 free(controller_ptr
);
458 jack_controller_add_slave(
459 struct jack_controller
*controller_ptr
,
460 const char * driver_name
)
462 jackctl_driver_t
*driver
;
464 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
471 jack_info("driver \"%s\" selected", driver_name
);
473 return jackctl_server_add_slave(controller_ptr
->server
, driver
);
477 jack_controller_remove_slave(
478 struct jack_controller
*controller_ptr
,
479 const char * driver_name
)
481 jackctl_driver_t
*driver
;
483 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
490 jack_info("driver \"%s\" selected", driver_name
);
492 return jackctl_server_remove_slave(controller_ptr
->server
, driver
);
496 jack_controller_load_internal(
497 struct jack_controller
*controller_ptr
,
498 const char * internal_name
)
500 jackctl_internal_t
*internal
;
502 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
503 if (internal
== NULL
)
508 jack_info("internal \"%s\" selected", internal_name
);
510 return jackctl_server_load_internal(controller_ptr
->server
, internal
);
514 jack_controller_unload_internal(
515 struct jack_controller
*controller_ptr
,
516 const char * internal_name
)
518 jackctl_internal_t
*internal
;
520 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
521 if (internal
== NULL
)
526 jack_info("internal \"%s\" selected", internal_name
);
528 return jackctl_server_unload_internal(controller_ptr
->server
, internal
);
531 #define controller_ptr ((struct jack_controller *)context)
534 jack_controller_destroy(
537 if (controller_ptr
->started
)
539 jack_controller_stop_server(controller_ptr
, NULL
);
542 free(controller_ptr
->driver_names
);
543 free(controller_ptr
->internal_names
);
545 jackctl_server_destroy(controller_ptr
->server
);
547 free(controller_ptr
);