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.

559 lines
14KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008,2010,2011 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. static
  37. jackctl_driver_t *
  38. jack_controller_find_driver(
  39. jackctl_server_t *server,
  40. const char *driver_name)
  41. {
  42. const JSList * node_ptr;
  43. node_ptr = jackctl_server_get_drivers_list(server);
  44. while (node_ptr)
  45. {
  46. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  47. {
  48. return node_ptr->data;
  49. }
  50. node_ptr = jack_slist_next(node_ptr);
  51. }
  52. return NULL;
  53. }
  54. bool
  55. jack_controller_add_slave_drivers(
  56. struct jack_controller * controller_ptr)
  57. {
  58. struct list_head * node_ptr;
  59. struct jack_controller_slave_driver * driver_ptr;
  60. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  61. {
  62. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  63. driver_ptr->handle = jack_controller_find_driver(controller_ptr->server, driver_ptr->name);
  64. if (driver_ptr->handle == NULL)
  65. {
  66. jack_error("Unknown driver \"%s\"", driver_ptr->name);
  67. goto fail;
  68. }
  69. if (!jackctl_server_add_slave(controller_ptr->server, driver_ptr->handle))
  70. {
  71. jack_error("Driver \"%s\" cannot be loaded", driver_ptr->name);
  72. goto fail;
  73. }
  74. }
  75. return true;
  76. fail:
  77. driver_ptr->handle = NULL;
  78. return false;
  79. }
  80. void
  81. jack_controller_remove_slave_drivers(
  82. struct jack_controller * controller_ptr)
  83. {
  84. struct list_head * node_ptr;
  85. struct jack_controller_slave_driver * driver_ptr;
  86. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  87. {
  88. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  89. if (driver_ptr->handle != NULL)
  90. {
  91. jackctl_server_remove_slave(controller_ptr->server, driver_ptr->handle);
  92. driver_ptr->handle = NULL;
  93. }
  94. }
  95. }
  96. static
  97. jackctl_internal_t *
  98. jack_controller_find_internal(
  99. jackctl_server_t *server,
  100. const char *internal_name)
  101. {
  102. const JSList * node_ptr;
  103. node_ptr = jackctl_server_get_internals_list(server);
  104. while (node_ptr)
  105. {
  106. if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0)
  107. {
  108. return node_ptr->data;
  109. }
  110. node_ptr = jack_slist_next(node_ptr);
  111. }
  112. return NULL;
  113. }
  114. bool
  115. jack_controller_select_driver(
  116. struct jack_controller * controller_ptr,
  117. const char * driver_name)
  118. {
  119. if (!jack_params_set_driver(controller_ptr->params, driver_name))
  120. {
  121. return false;
  122. }
  123. jack_info("driver \"%s\" selected", driver_name);
  124. return true;
  125. }
  126. static
  127. int
  128. jack_controller_xrun(void * arg)
  129. {
  130. ((struct jack_controller *)arg)->xruns++;
  131. return 0;
  132. }
  133. bool
  134. jack_controller_start_server(
  135. struct jack_controller * controller_ptr,
  136. void *dbus_call_context_ptr)
  137. {
  138. int ret;
  139. jack_info("Starting jack server...");
  140. assert(!controller_ptr->started); /* should be ensured by caller */
  141. controller_ptr->xruns = 0;
  142. if (!jackctl_server_open(
  143. controller_ptr->server,
  144. jack_params_get_driver(controller_ptr->params)))
  145. {
  146. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server");
  147. goto fail;
  148. }
  149. jack_controller_add_slave_drivers(controller_ptr);
  150. if (!jackctl_server_start(
  151. controller_ptr->server))
  152. {
  153. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  154. goto fail_close_server;
  155. }
  156. controller_ptr->client = jack_client_open(
  157. "dbusapi",
  158. JackNoStartServer,
  159. NULL);
  160. if (controller_ptr->client == NULL)
  161. {
  162. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  163. goto fail_stop_server;
  164. }
  165. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  166. if (ret != 0)
  167. {
  168. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  169. goto fail_close_client;
  170. }
  171. if (!jack_controller_patchbay_init(controller_ptr))
  172. {
  173. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to initialize patchbay district");
  174. goto fail_close_client;
  175. }
  176. ret = jack_activate(controller_ptr->client);
  177. if (ret != 0)
  178. {
  179. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  180. goto fail_patchbay_uninit;
  181. }
  182. controller_ptr->started = true;
  183. return TRUE;
  184. fail_patchbay_uninit:
  185. jack_controller_patchbay_uninit(controller_ptr);
  186. fail_close_client:
  187. ret = jack_client_close(controller_ptr->client);
  188. if (ret != 0)
  189. {
  190. jack_error("jack_client_close() failed with error %d", ret);
  191. }
  192. controller_ptr->client = NULL;
  193. fail_stop_server:
  194. if (!jackctl_server_stop(controller_ptr->server))
  195. {
  196. jack_error("failed to stop jack server");
  197. }
  198. fail_close_server:
  199. jack_controller_remove_slave_drivers(controller_ptr);
  200. if (!jackctl_server_close(controller_ptr->server))
  201. {
  202. jack_error("failed to close jack server");
  203. }
  204. fail:
  205. return FALSE;
  206. }
  207. bool
  208. jack_controller_stop_server(
  209. struct jack_controller * controller_ptr,
  210. void *dbus_call_context_ptr)
  211. {
  212. int ret;
  213. jack_info("Stopping jack server...");
  214. assert(controller_ptr->started); /* should be ensured by caller */
  215. ret = jack_deactivate(controller_ptr->client);
  216. if (ret != 0)
  217. {
  218. jack_error("failed to deactivate dbusapi jack client. error is %d", ret);
  219. }
  220. jack_controller_patchbay_uninit(controller_ptr);
  221. ret = jack_client_close(controller_ptr->client);
  222. if (ret != 0)
  223. {
  224. jack_error("jack_client_close() failed with error %d", ret);
  225. }
  226. controller_ptr->client = NULL;
  227. if (!jackctl_server_stop(controller_ptr->server))
  228. {
  229. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to stop server");
  230. return FALSE;
  231. }
  232. jack_controller_remove_slave_drivers(controller_ptr);
  233. if (!jackctl_server_close(controller_ptr->server))
  234. {
  235. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to close server");
  236. return FALSE;
  237. }
  238. controller_ptr->started = false;
  239. return TRUE;
  240. }
  241. bool
  242. jack_controller_switch_master(
  243. struct jack_controller * controller_ptr,
  244. void *dbus_call_context_ptr)
  245. {
  246. if (!jackctl_server_switch_master(
  247. controller_ptr->server,
  248. jack_params_get_driver(controller_ptr->params)))
  249. {
  250. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to switch master");
  251. return FALSE;
  252. }
  253. return TRUE;
  254. }
  255. #define DEVICE_MAX 2
  256. typedef struct reserved_audio_device {
  257. char device_name[64];
  258. rd_device * reserved_device;
  259. } reserved_audio_device;
  260. int g_device_count = 0;
  261. static reserved_audio_device g_reserved_device[DEVICE_MAX];
  262. static
  263. bool
  264. on_device_acquire(const char * device_name)
  265. {
  266. int ret;
  267. DBusError error;
  268. ret = rd_acquire(
  269. &g_reserved_device[g_device_count].reserved_device,
  270. g_connection,
  271. device_name,
  272. "Jack audio server",
  273. INT32_MAX,
  274. NULL,
  275. &error);
  276. if (ret < 0)
  277. {
  278. jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
  279. return false;
  280. }
  281. strcpy(g_reserved_device[g_device_count].device_name, device_name);
  282. g_device_count++;
  283. jack_info("Acquired audio card %s", device_name);
  284. return true;
  285. }
  286. static
  287. void
  288. on_device_release(const char * device_name)
  289. {
  290. int i;
  291. // Look for corresponding reserved device
  292. for (i = 0; i < DEVICE_MAX; i++) {
  293. if (strcmp(g_reserved_device[i].device_name, device_name) == 0)
  294. break;
  295. }
  296. if (i < DEVICE_MAX) {
  297. jack_info("Released audio card %s", device_name);
  298. rd_release(g_reserved_device[i].reserved_device);
  299. } else {
  300. jack_error("Audio card %s not found!!", device_name);
  301. }
  302. g_device_count--;
  303. }
  304. void *
  305. jack_controller_create(
  306. DBusConnection *connection)
  307. {
  308. struct jack_controller *controller_ptr;
  309. DBusObjectPathVTable vtable =
  310. {
  311. jack_dbus_message_handler_unregister,
  312. jack_dbus_message_handler,
  313. NULL
  314. };
  315. controller_ptr = malloc(sizeof(struct jack_controller));
  316. if (!controller_ptr)
  317. {
  318. jack_error("Ran out of memory trying to allocate struct jack_controller");
  319. goto fail;
  320. }
  321. controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release);
  322. if (controller_ptr->server == NULL)
  323. {
  324. jack_error("Failed to create server object");
  325. goto fail_free;
  326. }
  327. controller_ptr->params = jack_params_create(controller_ptr->server);
  328. if (controller_ptr->params == NULL)
  329. {
  330. jack_error("Failed to initialize parameter tree");
  331. goto fail_destroy_server;
  332. }
  333. controller_ptr->client = NULL;
  334. controller_ptr->started = false;
  335. INIT_LIST_HEAD(&controller_ptr->slave_drivers);
  336. controller_ptr->dbus_descriptor.context = controller_ptr;
  337. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  338. if (!dbus_connection_register_object_path(
  339. connection,
  340. JACK_CONTROLLER_OBJECT_PATH,
  341. &vtable,
  342. &controller_ptr->dbus_descriptor))
  343. {
  344. jack_error("Ran out of memory trying to register D-Bus object path");
  345. goto fail_destroy_params;
  346. }
  347. jack_controller_settings_load(controller_ptr);
  348. return controller_ptr;
  349. fail_destroy_params:
  350. jack_params_destroy(controller_ptr->params);
  351. fail_destroy_server:
  352. jackctl_server_destroy(controller_ptr->server);
  353. fail_free:
  354. free(controller_ptr);
  355. fail:
  356. return NULL;
  357. }
  358. bool
  359. jack_controller_add_slave_driver(
  360. struct jack_controller * controller_ptr,
  361. const char * driver_name)
  362. {
  363. struct jack_controller_slave_driver * driver_ptr;
  364. driver_ptr = malloc(sizeof(struct jack_controller_slave_driver));
  365. if (driver_ptr == NULL)
  366. {
  367. jack_error("malloc() failed to allocate jack_controller_slave_driver struct");
  368. return false;
  369. }
  370. driver_ptr->name = strdup(driver_name);
  371. if (driver_ptr->name == NULL)
  372. {
  373. jack_error("strdup() failed for slave driver name \"%s\"", driver_name);
  374. free(driver_ptr);
  375. return false;
  376. }
  377. driver_ptr->handle = NULL;
  378. jack_info("slave driver \"%s\" added", driver_name);
  379. list_add_tail(&driver_ptr->siblings, &controller_ptr->slave_drivers);
  380. return true;
  381. }
  382. bool
  383. jack_controller_remove_slave_driver(
  384. struct jack_controller * controller_ptr,
  385. const char * driver_name)
  386. {
  387. struct list_head * node_ptr;
  388. struct jack_controller_slave_driver * driver_ptr;
  389. list_for_each(node_ptr, &controller_ptr->slave_drivers)
  390. {
  391. driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
  392. if (strcmp(driver_ptr->name, driver_name) == 0)
  393. {
  394. jack_info("slave driver \"%s\" removed", driver_name);
  395. list_del(&driver_ptr->siblings);
  396. free(driver_ptr->name);
  397. free(driver_ptr);
  398. return true;
  399. }
  400. }
  401. return false;
  402. }
  403. bool
  404. jack_controller_load_internal(
  405. struct jack_controller *controller_ptr,
  406. const char * internal_name)
  407. {
  408. jackctl_internal_t *internal;
  409. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  410. if (internal == NULL)
  411. {
  412. return false;
  413. }
  414. jack_info("internal \"%s\" selected", internal_name);
  415. return jackctl_server_load_internal(controller_ptr->server, internal);
  416. }
  417. bool
  418. jack_controller_unload_internal(
  419. struct jack_controller *controller_ptr,
  420. const char * internal_name)
  421. {
  422. jackctl_internal_t *internal;
  423. internal = jack_controller_find_internal(controller_ptr->server, internal_name);
  424. if (internal == NULL)
  425. {
  426. return false;
  427. }
  428. jack_info("internal \"%s\" selected", internal_name);
  429. return jackctl_server_unload_internal(controller_ptr->server, internal);
  430. }
  431. #define controller_ptr ((struct jack_controller *)context)
  432. void
  433. jack_controller_destroy(
  434. void * context)
  435. {
  436. if (controller_ptr->started)
  437. {
  438. jack_controller_stop_server(controller_ptr, NULL);
  439. }
  440. jack_params_destroy(controller_ptr->params);
  441. jackctl_server_destroy(controller_ptr->server);
  442. free(controller_ptr);
  443. }