jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

560 lines
14KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008,2010 Nedko Arnaudov
  4. Copyright (C) 2007-2008 Juuso Alasuutari
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #if defined(HAVE_CONFIG_H)
  17. #include "config.h"
  18. #endif
  19. #include <stdint.h>
  20. #include <string.h>
  21. #include <dbus/dbus.h>
  22. #include <assert.h>
  23. #include "controller.h"
  24. #include "controller_internal.h"
  25. #include "xml.h"
  26. #include "reserve.h"
  27. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  28. {
  29. &g_jack_controller_iface_introspectable,
  30. &g_jack_controller_iface_control,
  31. &g_jack_controller_iface_configure,
  32. &g_jack_controller_iface_patchbay,
  33. &g_jack_controller_iface_transport,
  34. NULL
  35. };
  36. jackctl_driver_t *
  37. jack_controller_find_driver(
  38. jackctl_server_t *server,
  39. const char *driver_name)
  40. {
  41. const JSList * node_ptr;
  42. node_ptr = jackctl_server_get_drivers_list(server);
  43. while (node_ptr)
  44. {
  45. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  46. {
  47. return node_ptr->data;
  48. }
  49. node_ptr = jack_slist_next(node_ptr);
  50. }
  51. return NULL;
  52. }
  53. jackctl_internal_t *
  54. jack_controller_find_internal(
  55. jackctl_server_t *server,
  56. const char *internal_name)
  57. {
  58. const JSList * node_ptr;
  59. node_ptr = jackctl_server_get_internals_list(server);
  60. while (node_ptr)
  61. {
  62. if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0)
  63. {
  64. return node_ptr->data;
  65. }
  66. node_ptr = jack_slist_next(node_ptr);
  67. }
  68. return NULL;
  69. }
  70. jackctl_parameter_t *
  71. jack_controller_find_parameter(
  72. const JSList * parameters_list,
  73. const char * parameter_name)
  74. {
  75. while (parameters_list)
  76. {
  77. if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
  78. {
  79. return parameters_list->data;
  80. }
  81. parameters_list = jack_slist_next(parameters_list);
  82. }
  83. return NULL;
  84. }
  85. bool
  86. jack_controller_select_driver(
  87. struct jack_controller * controller_ptr,
  88. const char * driver_name)
  89. {
  90. jackctl_driver_t *driver;
  91. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  92. if (driver == NULL)
  93. {
  94. return false;
  95. }
  96. jack_info("driver \"%s\" selected", driver_name);
  97. controller_ptr->driver = driver;
  98. controller_ptr->driver_set = true;
  99. return true;
  100. }
  101. static
  102. int
  103. jack_controller_xrun(void * arg)
  104. {
  105. ((struct jack_controller *)arg)->xruns++;
  106. return 0;
  107. }
  108. bool
  109. jack_controller_start_server(
  110. struct jack_controller * controller_ptr,
  111. void *dbus_call_context_ptr)
  112. {
  113. int ret;
  114. jack_info("Starting jack server...");
  115. assert(!controller_ptr->started); /* should be ensured by caller */
  116. if (controller_ptr->driver == NULL)
  117. {
  118. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!");
  119. goto fail;
  120. }
  121. controller_ptr->xruns = 0;
  122. if (!jackctl_server_open(
  123. controller_ptr->server,
  124. controller_ptr->driver))
  125. {
  126. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server");
  127. goto fail;
  128. }
  129. if (!jackctl_server_start(
  130. controller_ptr->server))
  131. {
  132. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  133. goto fail_close_server;
  134. }
  135. controller_ptr->client = jack_client_open(
  136. "dbusapi",
  137. JackNoStartServer,
  138. NULL);
  139. if (controller_ptr->client == NULL)
  140. {
  141. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  142. goto fail_stop_server;
  143. }
  144. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  145. if (ret != 0)
  146. {
  147. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  148. goto fail_close_client;
  149. }
  150. if (!jack_controller_patchbay_init(controller_ptr))
  151. {
  152. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to initialize patchbay district");
  153. goto fail_close_client;
  154. }
  155. ret = jack_activate(controller_ptr->client);
  156. if (ret != 0)
  157. {
  158. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  159. goto fail_patchbay_uninit;
  160. }
  161. controller_ptr->started = true;
  162. return TRUE;
  163. fail_patchbay_uninit:
  164. jack_controller_patchbay_uninit(controller_ptr);
  165. fail_close_client:
  166. ret = jack_client_close(controller_ptr->client);
  167. if (ret != 0)
  168. {
  169. jack_error("jack_client_close() failed with error %d", ret);
  170. }
  171. controller_ptr->client = NULL;
  172. fail_stop_server:
  173. if (!jackctl_server_stop(controller_ptr->server))
  174. {
  175. jack_error("failed to stop jack server");
  176. }
  177. fail_close_server:
  178. if (!jackctl_server_close(controller_ptr->server))
  179. {
  180. jack_error("failed to close jack server");
  181. }
  182. fail:
  183. return FALSE;
  184. }
  185. bool
  186. jack_controller_stop_server(
  187. struct jack_controller * controller_ptr,
  188. void *dbus_call_context_ptr)
  189. {
  190. int ret;
  191. jack_info("Stopping jack server...");
  192. assert(controller_ptr->started); /* should be ensured by caller */
  193. ret = jack_deactivate(controller_ptr->client);
  194. if (ret != 0)
  195. {
  196. jack_error("failed to deactivate dbusapi jack client. error is %d", ret);
  197. }
  198. jack_controller_patchbay_uninit(controller_ptr);
  199. ret = jack_client_close(controller_ptr->client);
  200. if (ret != 0)
  201. {
  202. jack_error("jack_client_close() failed with error %d", ret);
  203. }
  204. controller_ptr->client = NULL;
  205. if (!jackctl_server_stop(controller_ptr->server))
  206. {
  207. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to stop server");
  208. return FALSE;
  209. }
  210. if (!jackctl_server_close(controller_ptr->server))
  211. {
  212. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to close server");
  213. return FALSE;
  214. }
  215. controller_ptr->started = false;
  216. return TRUE;
  217. }
  218. bool
  219. jack_controller_switch_master(
  220. struct jack_controller * controller_ptr,
  221. void *dbus_call_context_ptr)
  222. {
  223. if (!jackctl_server_switch_master(
  224. controller_ptr->server,
  225. controller_ptr->driver))
  226. {
  227. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to switch master");
  228. return FALSE;
  229. }
  230. return TRUE;
  231. }
  232. #define DEVICE_MAX 2
  233. typedef struct reserved_audio_device {
  234. char device_name[64];
  235. rd_device * reserved_device;
  236. } reserved_audio_device;
  237. int g_device_count = 0;
  238. static reserved_audio_device g_reserved_device[DEVICE_MAX];
  239. static
  240. bool
  241. on_device_acquire(const char * device_name)
  242. {
  243. int ret;
  244. DBusError error;
  245. ret = rd_acquire(
  246. &g_reserved_device[g_device_count].reserved_device,
  247. g_connection,
  248. device_name,
  249. "Jack audio server",
  250. INT32_MAX,
  251. NULL,
  252. &error);
  253. if (ret < 0)
  254. {
  255. jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
  256. return false;
  257. }
  258. strcpy(g_reserved_device[g_device_count].device_name, device_name);
  259. g_device_count++;
  260. jack_info("Acquired audio card %s", device_name);
  261. return true;
  262. }
  263. static
  264. void
  265. on_device_release(const char * device_name)
  266. {
  267. int i;
  268. // Look for corresponding reserved device
  269. for (i = 0; i < DEVICE_MAX; i++) {
  270. if (strcmp(g_reserved_device[i].device_name, device_name) == 0)
  271. break;
  272. }
  273. if (i < DEVICE_MAX) {
  274. jack_info("Released audio card %s", device_name);
  275. rd_release(g_reserved_device[i].reserved_device);
  276. } else {
  277. jack_error("Audio card %s not found!!", device_name);
  278. }
  279. g_device_count--;
  280. }
  281. void *
  282. jack_controller_create(
  283. DBusConnection *connection)
  284. {
  285. struct jack_controller *controller_ptr;
  286. const JSList * node_ptr;
  287. const char ** driver_name_target;
  288. const char ** internal_name_target;
  289. JSList * drivers;
  290. JSList * internals;
  291. DBusObjectPathVTable vtable =
  292. {
  293. jack_dbus_message_handler_unregister,
  294. jack_dbus_message_handler,
  295. NULL
  296. };
  297. controller_ptr = malloc(sizeof(struct jack_controller));
  298. if (!controller_ptr)
  299. {
  300. jack_error("Ran out of memory trying to allocate struct jack_controller");
  301. goto fail;
  302. }
  303. controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release);
  304. if (controller_ptr->server == NULL)
  305. {
  306. jack_error("Failed to create server object");
  307. goto fail_free;
  308. }
  309. controller_ptr->client = NULL;
  310. controller_ptr->started = false;
  311. controller_ptr->driver = NULL;
  312. controller_ptr->driver_set = false;
  313. drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server);
  314. controller_ptr->drivers_count = jack_slist_length(drivers);
  315. controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *));
  316. if (controller_ptr->driver_names == NULL)
  317. {
  318. jack_error("Ran out of memory trying to allocate driver names array");
  319. goto fail_destroy_server;
  320. }
  321. driver_name_target = controller_ptr->driver_names;
  322. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  323. while (node_ptr != NULL)
  324. {
  325. *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data);
  326. /* select default driver */
  327. if (controller_ptr->driver == NULL && strcmp(*driver_name_target, DEFAULT_DRIVER) == 0)
  328. {
  329. controller_ptr->driver = (jackctl_driver_t *)node_ptr->data;
  330. }
  331. node_ptr = jack_slist_next(node_ptr);
  332. driver_name_target++;
  333. }
  334. internals = (JSList *)jackctl_server_get_internals_list(controller_ptr->server);
  335. controller_ptr->internals_count = jack_slist_length(internals);
  336. controller_ptr->internal_names = malloc(controller_ptr->internals_count * sizeof(const char *));
  337. if (controller_ptr->internal_names == NULL)
  338. {
  339. jack_error("Ran out of memory trying to allocate internals names array");
  340. goto fail_free_driver_names_array;
  341. }
  342. internal_name_target = controller_ptr->internal_names;
  343. node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
  344. while (node_ptr != NULL)
  345. {
  346. *internal_name_target = jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data);
  347. node_ptr = jack_slist_next(node_ptr);
  348. internal_name_target++;
  349. }
  350. controller_ptr->dbus_descriptor.context = controller_ptr;
  351. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  352. if (!dbus_connection_register_object_path(
  353. connection,
  354. JACK_CONTROLLER_OBJECT_PATH,
  355. &vtable,
  356. &controller_ptr->dbus_descriptor))
  357. {
  358. jack_error("Ran out of memory trying to register D-Bus object path");
  359. goto fail_free_internal_names_array;
  360. }
  361. jack_controller_settings_load(controller_ptr);
  362. return controller_ptr;
  363. fail_free_internal_names_array:
  364. free(controller_ptr->internal_names);
  365. fail_free_driver_names_array:
  366. free(controller_ptr->driver_names);
  367. fail_destroy_server:
  368. jackctl_server_destroy(controller_ptr->server);
  369. fail_free:
  370. free(controller_ptr);
  371. fail:
  372. return NULL;
  373. }
  374. bool
  375. jack_controller_add_slave(
  376. struct jack_controller *controller_ptr,
  377. const char * driver_name)
  378. {
  379. jackctl_driver_t *driver;
  380. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  381. if (driver == NULL)
  382. {
  383. return false;
  384. }
  385. jack_info("driver \"%s\" selected", driver_name);
  386. return jackctl_server_add_slave(controller_ptr->server, driver);
  387. }
  388. bool
  389. jack_controller_remove_slave(
  390. struct jack_controller *controller_ptr,
  391. const char * driver_name)
  392. {
  393. jackctl_driver_t *driver;
  394. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  395. if (driver == NULL)
  396. {
  397. return false;
  398. }
  399. jack_info("driver \"%s\" selected", driver_name);
  400. return jackctl_server_remove_slave(controller_ptr->server, driver);
  401. }
  402. bool
  403. jack_controller_load_internal(
  404. struct jack_controller *controller_ptr,
  405. const char * internal_name)
  406. {
  407. jackctl_internal_t *internal;
  408. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  409. if (internal == NULL)
  410. {
  411. return false;
  412. }
  413. jack_info("internal \"%s\" selected", internal_name);
  414. return jackctl_server_load_internal(controller_ptr->server, internal);
  415. }
  416. bool
  417. jack_controller_unload_internal(
  418. struct jack_controller *controller_ptr,
  419. const char * internal_name)
  420. {
  421. jackctl_internal_t *internal;
  422. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  423. if (internal == NULL)
  424. {
  425. return false;
  426. }
  427. jack_info("internal \"%s\" selected", internal_name);
  428. return jackctl_server_unload_internal(controller_ptr->server, internal);
  429. }
  430. #define controller_ptr ((struct jack_controller *)context)
  431. void
  432. jack_controller_destroy(
  433. void * context)
  434. {
  435. if (controller_ptr->started)
  436. {
  437. jack_controller_stop_server(controller_ptr, NULL);
  438. }
  439. free(controller_ptr->driver_names);
  440. free(controller_ptr->internal_names);
  441. jackctl_server_destroy(controller_ptr->server);
  442. free(controller_ptr);
  443. }