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.

634 lines
16KB

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