1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
3 Copyright (C) 2007,2008,2010,2011 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>
31 #include "controller.h"
32 #include "controller_internal.h"
36 struct jack_dbus_interface_descriptor
* g_jackcontroller_interfaces
[] =
38 &g_jack_controller_iface_introspectable
,
39 &g_jack_controller_iface_control
,
40 &g_jack_controller_iface_configure
,
41 &g_jack_controller_iface_patchbay
,
42 &g_jack_controller_iface_session_manager
,
43 &g_jack_controller_iface_transport
,
49 jack_controller_find_driver(
50 jackctl_server_t
*server
,
51 const char *driver_name
)
53 const JSList
* node_ptr
;
55 node_ptr
= jackctl_server_get_drivers_list(server
);
59 if (strcmp(jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
), driver_name
) == 0)
61 return node_ptr
->data
;
64 node_ptr
= jack_slist_next(node_ptr
);
70 static bool jack_controller_check_slave_driver(struct jack_controller
* controller_ptr
, const char * name
)
72 struct list_head
* node_ptr
;
73 struct jack_controller_slave_driver
* driver_ptr
;
75 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
77 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
78 if (strcmp(name
, driver_ptr
->name
) == 0)
87 static bool jack_controller_load_slave_drivers(struct jack_controller
* controller_ptr
)
89 struct list_head
* node_ptr
;
90 struct jack_controller_slave_driver
* driver_ptr
;
92 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
94 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
96 assert(driver_ptr
->handle
!= NULL
);
97 assert(!driver_ptr
->loaded
);
99 if (!jackctl_server_add_slave(controller_ptr
->server
, driver_ptr
->handle
))
101 jack_error("Driver \"%s\" cannot be loaded", driver_ptr
->name
);
105 driver_ptr
->loaded
= true;
111 static void jack_controller_unload_slave_drivers(struct jack_controller
* controller_ptr
)
113 struct list_head
* node_ptr
;
114 struct jack_controller_slave_driver
* driver_ptr
;
116 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
118 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
119 if (driver_ptr
->loaded
)
121 jackctl_server_remove_slave(controller_ptr
->server
, driver_ptr
->handle
);
122 driver_ptr
->loaded
= false;
127 static void jack_controller_remove_slave_drivers(struct jack_controller
* controller_ptr
)
129 struct jack_controller_slave_driver
* driver_ptr
;
131 while (!list_empty(&controller_ptr
->slave_drivers
))
133 driver_ptr
= list_entry(controller_ptr
->slave_drivers
.next
, struct jack_controller_slave_driver
, siblings
);
134 assert(!driver_ptr
->loaded
);
135 list_del(&driver_ptr
->siblings
);
136 free(driver_ptr
->name
);
140 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
145 jack_controller_find_internal(
146 jackctl_server_t
*server
,
147 const char *internal_name
)
149 const JSList
* node_ptr
;
151 node_ptr
= jackctl_server_get_internals_list(server
);
155 if (strcmp(jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
), internal_name
) == 0)
157 return node_ptr
->data
;
160 node_ptr
= jack_slist_next(node_ptr
);
167 jack_controller_select_driver(
168 struct jack_controller
* controller_ptr
,
169 const char * driver_name
)
171 if (!jack_params_set_driver(controller_ptr
->params
, driver_name
))
176 jack_info("driver \"%s\" selected", driver_name
);
183 jack_controller_xrun(void * arg
)
185 ((struct jack_controller
*)arg
)->xruns
++;
191 jack_controller_start_server(
192 struct jack_controller
* controller_ptr
,
193 void *dbus_call_context_ptr
)
197 jack_info("Starting jack server...");
199 assert(!controller_ptr
->started
); /* should be ensured by caller */
201 controller_ptr
->xruns
= 0;
203 if (!jackctl_server_open(
204 controller_ptr
->server
,
205 jack_params_get_driver(controller_ptr
->params
)))
207 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to open server");
211 jack_controller_load_slave_drivers(controller_ptr
);
213 if (!jackctl_server_start(
214 controller_ptr
->server
))
216 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to start server");
217 goto fail_close_server
;
220 controller_ptr
->client
= jack_client_open(
224 if (controller_ptr
->client
== NULL
)
226 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to create dbusapi jack client");
227 goto fail_stop_server
;
230 ret
= jack_set_xrun_callback(controller_ptr
->client
, jack_controller_xrun
, controller_ptr
);
233 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to set xrun callback. error is %d", ret
);
234 goto fail_close_client
;
237 if (!jack_controller_patchbay_init(controller_ptr
))
239 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to initialize patchbay district");
240 goto fail_close_client
;
243 ret
= jack_activate(controller_ptr
->client
);
246 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to activate dbusapi jack client. error is %d", ret
);
247 goto fail_patchbay_uninit
;
250 controller_ptr
->started
= true;
254 fail_patchbay_uninit
:
255 jack_controller_patchbay_uninit(controller_ptr
);
258 ret
= jack_client_close(controller_ptr
->client
);
261 jack_error("jack_client_close() failed with error %d", ret
);
264 controller_ptr
->client
= NULL
;
267 if (!jackctl_server_stop(controller_ptr
->server
))
269 jack_error("failed to stop jack server");
273 jack_controller_unload_slave_drivers(controller_ptr
);
275 if (!jackctl_server_close(controller_ptr
->server
))
277 jack_error("failed to close jack server");
285 jack_controller_stop_server(
286 struct jack_controller
* controller_ptr
,
287 void *dbus_call_context_ptr
)
291 pthread_mutex_lock(&controller_ptr
->lock
);
292 if (!list_empty(&controller_ptr
->session_pending_commands
))
294 pthread_mutex_unlock(&controller_ptr
->lock
);
295 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Refusing to stop JACK server because of pending session commands");
298 pthread_mutex_unlock(&controller_ptr
->lock
);
300 jack_info("Stopping jack server...");
302 assert(controller_ptr
->started
); /* should be ensured by caller */
304 ret
= jack_deactivate(controller_ptr
->client
);
307 jack_error("failed to deactivate dbusapi jack client. error is %d", ret
);
310 jack_controller_patchbay_uninit(controller_ptr
);
312 ret
= jack_client_close(controller_ptr
->client
);
315 jack_error("jack_client_close() failed with error %d", ret
);
318 controller_ptr
->client
= NULL
;
320 if (!jackctl_server_stop(controller_ptr
->server
))
322 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to stop server");
326 jack_controller_unload_slave_drivers(controller_ptr
);
328 if (!jackctl_server_close(controller_ptr
->server
))
330 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to close server");
334 controller_ptr
->started
= false;
340 jack_controller_switch_master(
341 struct jack_controller
* controller_ptr
,
342 void *dbus_call_context_ptr
)
344 assert(controller_ptr
->started
); /* should be ensured by caller */
346 if (!jackctl_server_switch_master(
347 controller_ptr
->server
,
348 jack_params_get_driver(controller_ptr
->params
)))
350 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to switch master");
351 controller_ptr
->started
= false;
360 typedef struct reserved_audio_device
{
362 char device_name
[64];
363 rd_device
* reserved_device
;
365 } reserved_audio_device
;
368 int g_device_count
= 0;
369 static reserved_audio_device g_reserved_device
[DEVICE_MAX
];
373 on_device_acquire(const char * device_name
)
379 &g_reserved_device
[g_device_count
].reserved_device
,
388 jack_error("Failed to acquire device name : %s error : %s", device_name
, (error
.message
? error
.message
: strerror(-ret
)));
392 strcpy(g_reserved_device
[g_device_count
].device_name
, device_name
);
394 jack_info("Acquired audio card %s", device_name
);
400 on_device_release(const char * device_name
)
404 // Look for corresponding reserved device
405 for (i
= 0; i
< DEVICE_MAX
; i
++) {
406 if (strcmp(g_reserved_device
[i
].device_name
, device_name
) == 0)
410 if (i
< DEVICE_MAX
) {
411 jack_info("Released audio card %s", device_name
);
412 rd_release(g_reserved_device
[i
].reserved_device
);
414 jack_error("Audio card %s not found!!", device_name
);
420 #define controller_ptr ((struct jack_controller *)obj)
422 static bool slave_drivers_parameter_is_set(void * obj
)
424 return controller_ptr
->slave_drivers_set
;
427 static bool slave_drivers_parameter_reset(void * obj
)
429 if (controller_ptr
->started
)
431 jack_error("Cannot modify slave-drivers when server is started");
435 jack_controller_remove_slave_drivers(controller_ptr
);
436 controller_ptr
->slave_drivers_set
= false;
440 static union jackctl_parameter_value
slave_drivers_parameter_get_value(void * obj
)
442 return controller_ptr
->slave_drivers_vparam_value
;
445 static bool slave_drivers_parameter_set_value(void * obj
, const union jackctl_parameter_value
* value_ptr
)
450 struct list_head old_list
;
451 struct list_head new_list
;
452 union jackctl_parameter_value old_value
;
453 union jackctl_parameter_value new_value
;
456 if (controller_ptr
->started
)
458 jack_error("Cannot modify slave-drivers when server is started");
462 old_set
= controller_ptr
->slave_drivers_set
;
463 old_value
= controller_ptr
->slave_drivers_vparam_value
;
464 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
465 old_list
= controller_ptr
->slave_drivers
;
466 INIT_LIST_HEAD(&controller_ptr
->slave_drivers
);
468 buffer
= strdup(value_ptr
->str
);
471 jack_error("strdup() failed.");
475 token
= strtok_r(buffer
, ",", &save
);
478 //jack_info("slave driver '%s'", token);
479 if (!jack_controller_add_slave_driver(controller_ptr
, token
))
481 jack_controller_remove_slave_drivers(controller_ptr
);
482 controller_ptr
->slave_drivers
= old_list
;
483 controller_ptr
->slave_drivers_vparam_value
= old_value
;
484 controller_ptr
->slave_drivers_set
= old_set
;
491 token
= strtok_r(NULL
, ",", &save
);
494 new_value
= controller_ptr
->slave_drivers_vparam_value
;
495 new_list
= controller_ptr
->slave_drivers
;
496 controller_ptr
->slave_drivers
= old_list
;
497 jack_controller_remove_slave_drivers(controller_ptr
);
498 controller_ptr
->slave_drivers_vparam_value
= new_value
;
499 controller_ptr
->slave_drivers
= new_list
;
500 controller_ptr
->slave_drivers_set
= true;
507 static union jackctl_parameter_value
slave_drivers_parameter_get_default_value(void * obj
)
509 union jackctl_parameter_value value
;
514 #undef controller_ptr
517 jack_controller_create(
518 DBusConnection
*connection
)
521 struct jack_controller
*controller_ptr
;
522 const char * address
[PARAM_ADDRESS_SIZE
];
523 DBusObjectPathVTable vtable
=
525 jack_dbus_message_handler_unregister
,
526 jack_dbus_message_handler
,
530 controller_ptr
= malloc(sizeof(struct jack_controller
));
533 jack_error("Ran out of memory trying to allocate struct jack_controller");
537 error
= pthread_mutex_init(&controller_ptr
->lock
, NULL
);
540 jack_error("Failed to initialize mutex. error %d", error
);
544 INIT_LIST_HEAD(&controller_ptr
->session_pending_commands
);
546 controller_ptr
->server
= jackctl_server_create(on_device_acquire
, on_device_release
);
547 if (controller_ptr
->server
== NULL
)
549 jack_error("Failed to create server object");
550 goto fail_uninit_mutex
;
553 controller_ptr
->params
= jack_params_create(controller_ptr
->server
);
554 if (controller_ptr
->params
== NULL
)
556 jack_error("Failed to initialize parameter tree");
557 goto fail_destroy_server
;
560 controller_ptr
->client
= NULL
;
561 controller_ptr
->started
= false;
563 INIT_LIST_HEAD(&controller_ptr
->slave_drivers
);
564 controller_ptr
->slave_drivers_set
= false;
565 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
567 controller_ptr
->slave_drivers_vparam
.obj
= controller_ptr
;
569 controller_ptr
->slave_drivers_vparam
.vtable
.is_set
= slave_drivers_parameter_is_set
;
570 controller_ptr
->slave_drivers_vparam
.vtable
.reset
= slave_drivers_parameter_reset
;
571 controller_ptr
->slave_drivers_vparam
.vtable
.get_value
= slave_drivers_parameter_get_value
;
572 controller_ptr
->slave_drivers_vparam
.vtable
.set_value
= slave_drivers_parameter_set_value
;
573 controller_ptr
->slave_drivers_vparam
.vtable
.get_default_value
= slave_drivers_parameter_get_default_value
;
575 controller_ptr
->slave_drivers_vparam
.type
= JackParamString
;
576 controller_ptr
->slave_drivers_vparam
.name
= "slave-drivers";
577 controller_ptr
->slave_drivers_vparam
.short_decr
= "Slave drivers to use";
578 controller_ptr
->slave_drivers_vparam
.long_descr
= "A comma separated list of slave drivers";
579 controller_ptr
->slave_drivers_vparam
.constraint_flags
= 0;
581 address
[0] = PTNODE_ENGINE
;
583 jack_params_add_parameter(controller_ptr
->params
, address
, true, &controller_ptr
->slave_drivers_vparam
);
585 controller_ptr
->dbus_descriptor
.context
= controller_ptr
;
586 controller_ptr
->dbus_descriptor
.interfaces
= g_jackcontroller_interfaces
;
588 if (!dbus_connection_register_object_path(
590 JACK_CONTROLLER_OBJECT_PATH
,
592 &controller_ptr
->dbus_descriptor
))
594 jack_error("Ran out of memory trying to register D-Bus object path");
595 goto fail_destroy_params
;
598 jack_controller_settings_load(controller_ptr
);
600 return controller_ptr
;
603 jack_params_destroy(controller_ptr
->params
);
606 jackctl_server_destroy(controller_ptr
->server
);
609 pthread_mutex_destroy(&controller_ptr
->lock
);
612 free(controller_ptr
);
619 jack_controller_add_slave_driver(
620 struct jack_controller
* controller_ptr
,
621 const char * driver_name
)
623 jackctl_driver_t
* driver
;
624 struct jack_controller_slave_driver
* driver_ptr
;
628 len_old
= strlen(controller_ptr
->slave_drivers_vparam_value
.str
);
629 len_new
= strlen(driver_name
);
630 if (len_old
+ len_new
+ 2 > sizeof(controller_ptr
->slave_drivers_vparam_value
.str
))
632 jack_error("No more space for slave drivers.");
636 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
639 jack_error("Unknown driver \"%s\"", driver_name
);
643 if (jack_controller_check_slave_driver(controller_ptr
, driver_name
))
645 jack_info("Driver \"%s\" is already slave", driver_name
);
649 driver_ptr
= malloc(sizeof(struct jack_controller_slave_driver
));
650 if (driver_ptr
== NULL
)
652 jack_error("malloc() failed to allocate jack_controller_slave_driver struct");
656 driver_ptr
->name
= strdup(driver_name
);
657 if (driver_ptr
->name
== NULL
)
659 jack_error("strdup() failed for slave driver name \"%s\"", driver_name
);
664 driver_ptr
->handle
= driver
;
665 driver_ptr
->loaded
= false;
667 jack_info("driver \"%s\" set as slave", driver_name
);
669 list_add_tail(&driver_ptr
->siblings
, &controller_ptr
->slave_drivers
);
673 controller_ptr
->slave_drivers_vparam_value
.str
[len_old
++] = ',';
676 memcpy(controller_ptr
->slave_drivers_vparam_value
.str
+ len_old
, driver_name
, len_new
+ 1);
677 controller_ptr
->slave_drivers_set
= true;
683 jack_controller_remove_slave_driver(
684 struct jack_controller
* controller_ptr
,
685 const char * driver_name
)
687 struct list_head
* node_ptr
;
688 struct jack_controller_slave_driver
* driver_ptr
;
690 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
692 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
693 if (strcmp(driver_ptr
->name
, driver_name
) == 0)
695 list_del(&driver_ptr
->siblings
);
696 free(driver_ptr
->name
);
699 /* update the slave-drivers param value */
700 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
701 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
703 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
704 if (controller_ptr
->slave_drivers_vparam_value
.str
[0] != 0)
706 strcat(controller_ptr
->slave_drivers_vparam_value
.str
, ",");
709 strcat(controller_ptr
->slave_drivers_vparam_value
.str
, driver_ptr
->name
);
712 jack_info("driver \"%s\" is not slave anymore", driver_name
);
722 jack_controller_load_internal(
723 struct jack_controller
*controller_ptr
,
724 const char * internal_name
)
726 jackctl_internal_t
*internal
;
728 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
729 if (internal
== NULL
)
734 jack_info("internal \"%s\" selected", internal_name
);
736 return jackctl_server_load_internal(controller_ptr
->server
, internal
);
740 jack_controller_unload_internal(
741 struct jack_controller
*controller_ptr
,
742 const char * internal_name
)
744 jackctl_internal_t
*internal
;
746 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
747 if (internal
== NULL
)
752 jack_info("internal \"%s\" selected", internal_name
);
754 return jackctl_server_unload_internal(controller_ptr
->server
, internal
);
757 #define controller_ptr ((struct jack_controller *)context)
760 jack_controller_destroy(
763 if (controller_ptr
->started
)
765 while (!jack_controller_stop_server(controller_ptr
, NULL
))
767 jack_info("jack server failed to stop, retrying in 3 seconds...");
772 jack_controller_remove_slave_drivers(controller_ptr
);
773 jack_params_destroy(controller_ptr
->params
);
774 jackctl_server_destroy(controller_ptr
->server
);
775 pthread_mutex_destroy(&controller_ptr
->lock
);
776 free(controller_ptr
);