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"
33 struct jack_dbus_interface_descriptor
* g_jackcontroller_interfaces
[] =
35 &g_jack_controller_iface_introspectable
,
36 &g_jack_controller_iface_control
,
37 &g_jack_controller_iface_configure
,
38 &g_jack_controller_iface_patchbay
,
39 &g_jack_controller_iface_transport
,
44 jack_controller_find_driver(
45 jackctl_server_t
*server
,
46 const char *driver_name
)
48 const JSList
* node_ptr
;
50 node_ptr
= jackctl_server_get_drivers_list(server
);
54 if (strcmp(jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
), driver_name
) == 0)
56 return node_ptr
->data
;
59 node_ptr
= jack_slist_next(node_ptr
);
66 jack_controller_find_internal(
67 jackctl_server_t
*server
,
68 const char *internal_name
)
70 const JSList
* node_ptr
;
72 node_ptr
= jackctl_server_get_internals_list(server
);
76 if (strcmp(jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
), internal_name
) == 0)
78 return node_ptr
->data
;
81 node_ptr
= jack_slist_next(node_ptr
);
88 jack_controller_find_parameter(
89 const JSList
* parameters_list
,
90 const char * parameter_name
)
92 while (parameters_list
)
94 if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t
*)parameters_list
->data
), parameter_name
) == 0)
96 return parameters_list
->data
;
99 parameters_list
= jack_slist_next(parameters_list
);
106 jack_controller_select_driver(
107 struct jack_controller
* controller_ptr
,
108 const char * driver_name
)
110 jackctl_driver_t
*driver
;
112 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
118 jack_info("driver \"%s\" selected", driver_name
);
120 controller_ptr
->driver
= driver
;
121 controller_ptr
->driver_set
= true;
128 jack_controller_xrun(void * arg
)
130 ((struct jack_controller
*)arg
)->xruns
++;
136 jack_controller_start_server(
137 struct jack_controller
* controller_ptr
,
138 void *dbus_call_context_ptr
)
142 jack_info("Starting jack server...");
144 if (controller_ptr
->started
)
146 jack_info("Already started.");
150 if (controller_ptr
->driver
== NULL
)
152 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Select driver first!");
156 controller_ptr
->xruns
= 0;
158 if (!jackctl_server_start(
159 controller_ptr
->server
,
160 controller_ptr
->driver
))
162 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to start server");
166 controller_ptr
->client
= jack_client_open(
170 if (controller_ptr
->client
== NULL
)
172 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to create dbusapi jack client");
174 goto fail_stop_server
;
177 ret
= jack_set_xrun_callback(controller_ptr
->client
, jack_controller_xrun
, controller_ptr
);
180 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to set xrun callback. error is %d", ret
);
182 goto fail_close_client
;
185 if (!jack_controller_patchbay_init(controller_ptr
))
187 jack_error("Failed to initialize patchbay district");
188 goto fail_close_client
;
191 ret
= jack_activate(controller_ptr
->client
);
194 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to activate dbusapi jack client. error is %d", ret
);
196 goto fail_patchbay_uninit
;
199 controller_ptr
->started
= true;
203 fail_patchbay_uninit
:
204 jack_controller_patchbay_uninit(controller_ptr
);
207 ret
= jack_client_close(controller_ptr
->client
);
210 jack_error("jack_client_close() failed with error %d", ret
);
213 controller_ptr
->client
= NULL
;
216 if (!jackctl_server_stop(controller_ptr
->server
))
218 jack_error("failed to stop jack server");
226 jack_controller_stop_server(
227 struct jack_controller
* controller_ptr
,
228 void *dbus_call_context_ptr
)
232 jack_info("Stopping jack server...");
234 if (!controller_ptr
->started
)
236 jack_info("Already stopped.");
240 ret
= jack_deactivate(controller_ptr
->client
);
243 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to deactivate dbusapi jack client. error is %d", ret
);
246 jack_controller_patchbay_uninit(controller_ptr
);
248 ret
= jack_client_close(controller_ptr
->client
);
251 jack_error("jack_client_close() failed with error %d", ret
);
254 controller_ptr
->client
= NULL
;
256 if (!jackctl_server_stop(controller_ptr
->server
))
261 controller_ptr
->started
= false;
267 jack_controller_switch_master(
268 struct jack_controller
* controller_ptr
,
269 void *dbus_call_context_ptr
)
271 if (!jackctl_server_switch_master(
272 controller_ptr
->server
,
273 controller_ptr
->driver
))
275 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to switch master");
283 jack_controller_create(
284 DBusConnection
*connection
)
286 struct jack_controller
*controller_ptr
;
287 const JSList
* node_ptr
;
288 const char ** driver_name_target
;
289 const char ** internal_name_target
;
292 DBusObjectPathVTable vtable
=
294 jack_dbus_message_handler_unregister
,
295 jack_dbus_message_handler
,
299 controller_ptr
= malloc(sizeof(struct jack_controller
));
302 jack_error("Ran out of memory trying to allocate struct jack_controller");
306 controller_ptr
->server
= jackctl_server_create();
307 if (controller_ptr
->server
== NULL
)
309 jack_error("Failed to create server object");
313 controller_ptr
->client
= NULL
;
314 controller_ptr
->started
= false;
315 controller_ptr
->driver
= NULL
;
316 controller_ptr
->driver_set
= false;
318 drivers
= (JSList
*)jackctl_server_get_drivers_list(controller_ptr
->server
);
319 controller_ptr
->drivers_count
= jack_slist_length(drivers
);
320 controller_ptr
->driver_names
= malloc(controller_ptr
->drivers_count
* sizeof(const char *));
321 if (controller_ptr
->driver_names
== NULL
)
323 jack_error("Ran out of memory trying to allocate driver names array");
324 goto fail_destroy_server
;
327 driver_name_target
= controller_ptr
->driver_names
;
328 node_ptr
= jackctl_server_get_drivers_list(controller_ptr
->server
);
329 while (node_ptr
!= NULL
)
331 *driver_name_target
= jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
);
333 /* select default driver */
334 if (controller_ptr
->driver
== NULL
&& strcmp(*driver_name_target
, DEFAULT_DRIVER
) == 0)
336 controller_ptr
->driver
= (jackctl_driver_t
*)node_ptr
->data
;
339 node_ptr
= jack_slist_next(node_ptr
);
340 driver_name_target
++;
343 internals
= (JSList
*)jackctl_server_get_internals_list(controller_ptr
->server
);
344 controller_ptr
->internals_count
= jack_slist_length(internals
);
345 controller_ptr
->internal_names
= malloc(controller_ptr
->internals_count
* sizeof(const char *));
346 if (controller_ptr
->internal_names
== NULL
)
348 jack_error("Ran out of memory trying to allocate internals names array");
349 goto fail_free_driver_names_array
;
352 internal_name_target
= controller_ptr
->internal_names
;
353 node_ptr
= jackctl_server_get_internals_list(controller_ptr
->server
);
354 while (node_ptr
!= NULL
)
356 *internal_name_target
= jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
);
357 node_ptr
= jack_slist_next(node_ptr
);
358 internal_name_target
++;
361 controller_ptr
->dbus_descriptor
.context
= controller_ptr
;
362 controller_ptr
->dbus_descriptor
.interfaces
= g_jackcontroller_interfaces
;
364 if (!dbus_connection_register_object_path(
366 JACK_CONTROLLER_OBJECT_PATH
,
368 &controller_ptr
->dbus_descriptor
))
370 jack_error("Ran out of memory trying to register D-Bus object path");
371 goto fail_free_internal_names_array
;
374 jack_controller_settings_load(controller_ptr
);
376 return controller_ptr
;
378 fail_free_internal_names_array
:
379 free(controller_ptr
->internal_names
);
381 fail_free_driver_names_array
:
382 free(controller_ptr
->driver_names
);
385 jackctl_server_destroy(controller_ptr
->server
);
388 free(controller_ptr
);
395 jack_controller_add_slave(
396 struct jack_controller
*controller_ptr
,
397 const char * driver_name
)
399 jackctl_driver_t
*driver
;
401 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
408 jack_info("driver \"%s\" selected", driver_name
);
410 return jackctl_server_add_slave(controller_ptr
->server
, driver
);
414 jack_controller_remove_slave(
415 struct jack_controller
*controller_ptr
,
416 const char * driver_name
)
418 jackctl_driver_t
*driver
;
420 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
427 jack_info("driver \"%s\" selected", driver_name
);
429 return jackctl_server_remove_slave(controller_ptr
->server
, driver
);
433 jack_controller_load_internal(
434 struct jack_controller
*controller_ptr
,
435 const char * internal_name
)
437 jackctl_internal_t
*internal
;
439 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
440 if (internal
== NULL
)
445 jack_info("internal \"%s\" selected", internal_name
);
447 return jackctl_server_load_internal(controller_ptr
->server
, internal
);
451 jack_controller_unload_internal(
452 struct jack_controller
*controller_ptr
,
453 const char * internal_name
)
455 jackctl_internal_t
*internal
;
457 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
458 if (internal
== NULL
)
463 jack_info("internal \"%s\" selected", internal_name
);
465 return jackctl_server_unload_internal(controller_ptr
->server
, internal
);
468 #define controller_ptr ((struct jack_controller *)context)
471 jack_controller_destroy(
474 if (controller_ptr
->started
)
476 jack_controller_stop_server(controller_ptr
, NULL
);
479 free(controller_ptr
->driver_names
);
480 free(controller_ptr
->internal_names
);
482 jackctl_server_destroy(controller_ptr
->server
);
484 free(controller_ptr
);