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.

1341 lines
33KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008 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. #include <stdint.h>
  17. #include <string.h>
  18. #include <dbus/dbus.h>
  19. #include "controller.h"
  20. #include "controller_internal.h"
  21. #include "xml.h"
  22. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  23. {
  24. &g_jack_controller_iface_introspectable,
  25. &g_jack_controller_iface_control,
  26. &g_jack_controller_iface_configure,
  27. &g_jack_controller_iface_patchbay,
  28. &g_jack_controller_iface_transport,
  29. NULL
  30. };
  31. jackctl_driver_t *
  32. jack_controller_find_driver(
  33. jackctl_server_t *server,
  34. const char *driver_name)
  35. {
  36. const JSList * node_ptr;
  37. node_ptr = jackctl_server_get_drivers_list(server);
  38. while (node_ptr)
  39. {
  40. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  41. {
  42. return node_ptr->data;
  43. }
  44. node_ptr = jack_slist_next(node_ptr);
  45. }
  46. return NULL;
  47. }
  48. jackctl_parameter_t *
  49. jack_controller_find_parameter(
  50. const JSList * parameters_list,
  51. const char * parameter_name)
  52. {
  53. while (parameters_list)
  54. {
  55. if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
  56. {
  57. return parameters_list->data;
  58. }
  59. parameters_list = jack_slist_next(parameters_list);
  60. }
  61. return NULL;
  62. }
  63. bool
  64. jack_controller_select_driver(
  65. struct jack_controller * controller_ptr,
  66. const char * driver_name)
  67. {
  68. jackctl_driver_t *driver;
  69. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  70. if (driver == NULL)
  71. {
  72. return false;
  73. }
  74. jack_info("driver \"%s\" selected", driver_name);
  75. controller_ptr->driver = driver;
  76. return true;
  77. }
  78. static
  79. int
  80. jack_controller_xrun(void * arg)
  81. {
  82. ((struct jack_controller *)arg)->xruns++;
  83. return 0;
  84. }
  85. bool
  86. jack_controller_start_server(
  87. struct jack_controller * controller_ptr,
  88. void *dbus_call_context_ptr)
  89. {
  90. int ret;
  91. jack_info("Starting jack server...");
  92. if (controller_ptr->started)
  93. {
  94. jack_info("Already started.");
  95. return TRUE;
  96. }
  97. if (controller_ptr->driver == NULL)
  98. {
  99. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!");
  100. goto fail;
  101. }
  102. controller_ptr->xruns = 0;
  103. if (!jackctl_server_start(
  104. controller_ptr->server,
  105. controller_ptr->driver))
  106. {
  107. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  108. goto fail;
  109. }
  110. controller_ptr->client = jack_client_open(
  111. "dbusapi",
  112. JackNoStartServer,
  113. NULL);
  114. if (controller_ptr->client == NULL)
  115. {
  116. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  117. goto fail_stop_server;
  118. }
  119. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  120. if (ret != 0)
  121. {
  122. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  123. goto fail_close_client;
  124. }
  125. if (!jack_controller_patchbay_init(controller_ptr))
  126. {
  127. jack_error("Failed to initialize patchbay district");
  128. goto fail_close_client;
  129. }
  130. ret = jack_activate(controller_ptr->client);
  131. if (ret != 0)
  132. {
  133. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  134. goto fail_patchbay_uninit;
  135. }
  136. controller_ptr->started = true;
  137. return TRUE;
  138. fail_patchbay_uninit:
  139. jack_controller_patchbay_uninit(controller_ptr);
  140. fail_close_client:
  141. ret = jack_client_close(controller_ptr->client);
  142. if (ret != 0)
  143. {
  144. jack_error("jack_client_close() failed with error %d", ret);
  145. }
  146. controller_ptr->client = NULL;
  147. fail_stop_server:
  148. if (!jackctl_server_stop(controller_ptr->server))
  149. {
  150. jack_error("failed to stop jack server");
  151. }
  152. fail:
  153. return FALSE;
  154. }
  155. bool
  156. jack_controller_stop_server(
  157. struct jack_controller * controller_ptr,
  158. void *dbus_call_context_ptr)
  159. {
  160. int ret;
  161. jack_info("Stopping jack server...");
  162. if (!controller_ptr->started)
  163. {
  164. jack_info("Already stopped.");
  165. return TRUE;
  166. }
  167. ret = jack_deactivate(controller_ptr->client);
  168. if (ret != 0)
  169. {
  170. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to deactivate dbusapi jack client. error is %d", ret);
  171. }
  172. jack_controller_patchbay_uninit(controller_ptr);
  173. ret = jack_client_close(controller_ptr->client);
  174. if (ret != 0)
  175. {
  176. jack_error("jack_client_close() failed with error %d", ret);
  177. }
  178. controller_ptr->client = NULL;
  179. if (!jackctl_server_stop(controller_ptr->server))
  180. {
  181. return FALSE;
  182. }
  183. controller_ptr->started = false;
  184. return TRUE;
  185. }
  186. void *
  187. jack_controller_create(
  188. DBusConnection *connection)
  189. {
  190. struct jack_controller *controller_ptr;
  191. const JSList * node_ptr;
  192. const char ** driver_name_target;
  193. JSList * drivers;
  194. DBusObjectPathVTable vtable =
  195. {
  196. jack_dbus_message_handler_unregister,
  197. jack_dbus_message_handler,
  198. NULL
  199. };
  200. controller_ptr = malloc(sizeof(struct jack_controller));
  201. if (!controller_ptr)
  202. {
  203. jack_error("Ran out of memory trying to allocate struct jack_controller");
  204. goto fail;
  205. }
  206. controller_ptr->server = jackctl_server_create();
  207. if (controller_ptr->server == NULL)
  208. {
  209. jack_error("Failed to create server object");
  210. goto fail_free;
  211. }
  212. controller_ptr->client = NULL;
  213. controller_ptr->started = false;
  214. drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server);
  215. controller_ptr->drivers_count = jack_slist_length(drivers);
  216. controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *));
  217. if (controller_ptr->driver_names == NULL)
  218. {
  219. jack_error("Ran out of memory trying to allocate driver names array");
  220. goto fail_destroy_server;
  221. }
  222. driver_name_target = controller_ptr->driver_names;
  223. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  224. while (node_ptr != NULL)
  225. {
  226. *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data);
  227. node_ptr = jack_slist_next(node_ptr);
  228. driver_name_target++;
  229. }
  230. controller_ptr->dbus_descriptor.context = controller_ptr;
  231. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  232. if (!dbus_connection_register_object_path(
  233. connection,
  234. JACK_CONTROLLER_OBJECT_PATH,
  235. &vtable,
  236. &controller_ptr->dbus_descriptor))
  237. {
  238. jack_error("Ran out of memory trying to register D-Bus object path");
  239. goto fail_free_driver_names_array;
  240. }
  241. jack_controller_settings_load(controller_ptr);
  242. return controller_ptr;
  243. fail_free_driver_names_array:
  244. free(controller_ptr->driver_names);
  245. fail_destroy_server:
  246. jackctl_server_destroy(controller_ptr->server);
  247. fail_free:
  248. free(controller_ptr);
  249. fail:
  250. return NULL;
  251. }
  252. #define controller_ptr ((struct jack_controller *)context)
  253. void
  254. jack_controller_destroy(
  255. void * context)
  256. {
  257. if (controller_ptr->started)
  258. {
  259. jack_controller_stop_server(controller_ptr, NULL);
  260. }
  261. free(controller_ptr->driver_names);
  262. jackctl_server_destroy(controller_ptr->server);
  263. free(controller_ptr);
  264. }
  265. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  266. /*
  267. Copyright (C) 2007,2008 Nedko Arnaudov
  268. Copyright (C) 2007-2008 Juuso Alasuutari
  269. This program is free software; you can redistribute it and/or modify
  270. it under the terms of the GNU General Public License as published by
  271. the Free Software Foundation; either version 2 of the License.
  272. This program is distributed in the hope that it will be useful,
  273. but WITHOUT ANY WARRANTY; without even the implied warranty of
  274. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  275. GNU General Public License for more details.
  276. You should have received a copy of the GNU General Public License
  277. along with this program; if not, write to the Free Software
  278. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  279. */
  280. #include <stdint.h>
  281. #include <string.h>
  282. #include <dbus/dbus.h>
  283. #include "controller.h"
  284. #include "controller_internal.h"
  285. #include "xml.h"
  286. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  287. {
  288. &g_jack_controller_iface_introspectable,
  289. &g_jack_controller_iface_control,
  290. &g_jack_controller_iface_configure,
  291. &g_jack_controller_iface_patchbay,
  292. &g_jack_controller_iface_transport,
  293. NULL
  294. };
  295. jackctl_driver_t *
  296. jack_controller_find_driver(
  297. jackctl_server_t *server,
  298. const char *driver_name)
  299. {
  300. const JSList * node_ptr;
  301. node_ptr = jackctl_server_get_drivers_list(server);
  302. while (node_ptr)
  303. {
  304. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  305. {
  306. return node_ptr->data;
  307. }
  308. node_ptr = jack_slist_next(node_ptr);
  309. }
  310. return NULL;
  311. }
  312. jackctl_parameter_t *
  313. jack_controller_find_parameter(
  314. const JSList * parameters_list,
  315. const char * parameter_name)
  316. {
  317. while (parameters_list)
  318. {
  319. if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
  320. {
  321. return parameters_list->data;
  322. }
  323. parameters_list = jack_slist_next(parameters_list);
  324. }
  325. return NULL;
  326. }
  327. bool
  328. jack_controller_select_driver(
  329. struct jack_controller * controller_ptr,
  330. const char * driver_name)
  331. {
  332. jackctl_driver_t *driver;
  333. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  334. if (driver == NULL)
  335. {
  336. return false;
  337. }
  338. jack_info("driver \"%s\" selected", driver_name);
  339. controller_ptr->driver = driver;
  340. return true;
  341. }
  342. static
  343. int
  344. jack_controller_xrun(void * arg)
  345. {
  346. ((struct jack_controller *)arg)->xruns++;
  347. return 0;
  348. }
  349. bool
  350. jack_controller_start_server(
  351. struct jack_controller * controller_ptr,
  352. void *dbus_call_context_ptr)
  353. {
  354. int ret;
  355. jack_info("Starting jack server...");
  356. if (controller_ptr->started)
  357. {
  358. jack_info("Already started.");
  359. return TRUE;
  360. }
  361. if (controller_ptr->driver == NULL)
  362. {
  363. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!");
  364. goto fail;
  365. }
  366. controller_ptr->xruns = 0;
  367. if (!jackctl_server_start(
  368. controller_ptr->server,
  369. controller_ptr->driver))
  370. {
  371. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  372. goto fail;
  373. }
  374. controller_ptr->client = jack_client_open(
  375. "dbusapi",
  376. JackNoStartServer,
  377. NULL);
  378. if (controller_ptr->client == NULL)
  379. {
  380. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  381. goto fail_stop_server;
  382. }
  383. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  384. if (ret != 0)
  385. {
  386. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  387. goto fail_close_client;
  388. }
  389. if (!jack_controller_patchbay_init(controller_ptr))
  390. {
  391. jack_error("Failed to initialize patchbay district");
  392. goto fail_close_client;
  393. }
  394. ret = jack_activate(controller_ptr->client);
  395. if (ret != 0)
  396. {
  397. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  398. goto fail_patchbay_uninit;
  399. }
  400. controller_ptr->started = true;
  401. return TRUE;
  402. fail_patchbay_uninit:
  403. jack_controller_patchbay_uninit(controller_ptr);
  404. fail_close_client:
  405. ret = jack_client_close(controller_ptr->client);
  406. if (ret != 0)
  407. {
  408. jack_error("jack_client_close() failed with error %d", ret);
  409. }
  410. controller_ptr->client = NULL;
  411. fail_stop_server:
  412. if (!jackctl_server_stop(controller_ptr->server))
  413. {
  414. jack_error("failed to stop jack server");
  415. }
  416. fail:
  417. return FALSE;
  418. }
  419. bool
  420. jack_controller_stop_server(
  421. struct jack_controller * controller_ptr,
  422. void *dbus_call_context_ptr)
  423. {
  424. int ret;
  425. jack_info("Stopping jack server...");
  426. if (!controller_ptr->started)
  427. {
  428. jack_info("Already stopped.");
  429. return TRUE;
  430. }
  431. ret = jack_deactivate(controller_ptr->client);
  432. if (ret != 0)
  433. {
  434. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to deactivate dbusapi jack client. error is %d", ret);
  435. }
  436. jack_controller_patchbay_uninit(controller_ptr);
  437. ret = jack_client_close(controller_ptr->client);
  438. if (ret != 0)
  439. {
  440. jack_error("jack_client_close() failed with error %d", ret);
  441. }
  442. controller_ptr->client = NULL;
  443. if (!jackctl_server_stop(controller_ptr->server))
  444. {
  445. return FALSE;
  446. }
  447. controller_ptr->started = false;
  448. return TRUE;
  449. }
  450. void *
  451. jack_controller_create(
  452. DBusConnection *connection)
  453. {
  454. struct jack_controller *controller_ptr;
  455. const JSList * node_ptr;
  456. const char ** driver_name_target;
  457. JSList * drivers;
  458. DBusObjectPathVTable vtable =
  459. {
  460. jack_dbus_message_handler_unregister,
  461. jack_dbus_message_handler,
  462. NULL
  463. };
  464. controller_ptr = malloc(sizeof(struct jack_controller));
  465. if (!controller_ptr)
  466. {
  467. jack_error("Ran out of memory trying to allocate struct jack_controller");
  468. goto fail;
  469. }
  470. controller_ptr->server = jackctl_server_create();
  471. if (controller_ptr->server == NULL)
  472. {
  473. jack_error("Failed to create server object");
  474. goto fail_free;
  475. }
  476. controller_ptr->client = NULL;
  477. controller_ptr->started = false;
  478. drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server);
  479. controller_ptr->drivers_count = jack_slist_length(drivers);
  480. controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *));
  481. if (controller_ptr->driver_names == NULL)
  482. {
  483. jack_error("Ran out of memory trying to allocate driver names array");
  484. goto fail_destroy_server;
  485. }
  486. driver_name_target = controller_ptr->driver_names;
  487. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  488. while (node_ptr != NULL)
  489. {
  490. *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data);
  491. node_ptr = jack_slist_next(node_ptr);
  492. driver_name_target++;
  493. }
  494. controller_ptr->dbus_descriptor.context = controller_ptr;
  495. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  496. if (!dbus_connection_register_object_path(
  497. connection,
  498. JACK_CONTROLLER_OBJECT_PATH,
  499. &vtable,
  500. &controller_ptr->dbus_descriptor))
  501. {
  502. jack_error("Ran out of memory trying to register D-Bus object path");
  503. goto fail_free_driver_names_array;
  504. }
  505. jack_controller_settings_load(controller_ptr);
  506. return controller_ptr;
  507. fail_free_driver_names_array:
  508. free(controller_ptr->driver_names);
  509. fail_destroy_server:
  510. jackctl_server_destroy(controller_ptr->server);
  511. fail_free:
  512. free(controller_ptr);
  513. fail:
  514. return NULL;
  515. }
  516. #define controller_ptr ((struct jack_controller *)context)
  517. void
  518. jack_controller_destroy(
  519. void * context)
  520. {
  521. if (controller_ptr->started)
  522. {
  523. jack_controller_stop_server(controller_ptr, NULL);
  524. }
  525. free(controller_ptr->driver_names);
  526. jackctl_server_destroy(controller_ptr->server);
  527. free(controller_ptr);
  528. }
  529. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  530. /*
  531. Copyright (C) 2007,2008 Nedko Arnaudov
  532. Copyright (C) 2007-2008 Juuso Alasuutari
  533. This program is free software; you can redistribute it and/or modify
  534. it under the terms of the GNU General Public License as published by
  535. the Free Software Foundation; either version 2 of the License.
  536. This program is distributed in the hope that it will be useful,
  537. but WITHOUT ANY WARRANTY; without even the implied warranty of
  538. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  539. GNU General Public License for more details.
  540. You should have received a copy of the GNU General Public License
  541. along with this program; if not, write to the Free Software
  542. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  543. */
  544. #include <stdint.h>
  545. #include <string.h>
  546. #include <dbus/dbus.h>
  547. #include "controller.h"
  548. #include "controller_internal.h"
  549. #include "xml.h"
  550. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  551. {
  552. &g_jack_controller_iface_introspectable,
  553. &g_jack_controller_iface_control,
  554. &g_jack_controller_iface_configure,
  555. &g_jack_controller_iface_patchbay,
  556. &g_jack_controller_iface_transport,
  557. NULL
  558. };
  559. jackctl_driver_t *
  560. jack_controller_find_driver(
  561. jackctl_server_t *server,
  562. const char *driver_name)
  563. {
  564. const JSList * node_ptr;
  565. node_ptr = jackctl_server_get_drivers_list(server);
  566. while (node_ptr)
  567. {
  568. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  569. {
  570. return node_ptr->data;
  571. }
  572. node_ptr = jack_slist_next(node_ptr);
  573. }
  574. return NULL;
  575. }
  576. jackctl_parameter_t *
  577. jack_controller_find_parameter(
  578. const JSList * parameters_list,
  579. const char * parameter_name)
  580. {
  581. while (parameters_list)
  582. {
  583. if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
  584. {
  585. return parameters_list->data;
  586. }
  587. parameters_list = jack_slist_next(parameters_list);
  588. }
  589. return NULL;
  590. }
  591. bool
  592. jack_controller_select_driver(
  593. struct jack_controller * controller_ptr,
  594. const char * driver_name)
  595. {
  596. jackctl_driver_t *driver;
  597. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  598. if (driver == NULL)
  599. {
  600. return false;
  601. }
  602. jack_info("driver \"%s\" selected", driver_name);
  603. controller_ptr->driver = driver;
  604. return true;
  605. }
  606. static
  607. int
  608. jack_controller_xrun(void * arg)
  609. {
  610. ((struct jack_controller *)arg)->xruns++;
  611. return 0;
  612. }
  613. bool
  614. jack_controller_start_server(
  615. struct jack_controller * controller_ptr,
  616. void *dbus_call_context_ptr)
  617. {
  618. int ret;
  619. jack_info("Starting jack server...");
  620. if (controller_ptr->started)
  621. {
  622. jack_info("Already started.");
  623. return TRUE;
  624. }
  625. if (controller_ptr->driver == NULL)
  626. {
  627. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!");
  628. goto fail;
  629. }
  630. controller_ptr->xruns = 0;
  631. if (!jackctl_server_start(
  632. controller_ptr->server,
  633. controller_ptr->driver))
  634. {
  635. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  636. goto fail;
  637. }
  638. controller_ptr->client = jack_client_open(
  639. "dbusapi",
  640. JackNoStartServer,
  641. NULL);
  642. if (controller_ptr->client == NULL)
  643. {
  644. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  645. goto fail_stop_server;
  646. }
  647. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  648. if (ret != 0)
  649. {
  650. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  651. goto fail_close_client;
  652. }
  653. if (!jack_controller_patchbay_init(controller_ptr))
  654. {
  655. jack_error("Failed to initialize patchbay district");
  656. goto fail_close_client;
  657. }
  658. ret = jack_activate(controller_ptr->client);
  659. if (ret != 0)
  660. {
  661. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  662. goto fail_patchbay_uninit;
  663. }
  664. controller_ptr->started = true;
  665. return TRUE;
  666. fail_patchbay_uninit:
  667. jack_controller_patchbay_uninit(controller_ptr);
  668. fail_close_client:
  669. ret = jack_client_close(controller_ptr->client);
  670. if (ret != 0)
  671. {
  672. jack_error("jack_client_close() failed with error %d", ret);
  673. }
  674. controller_ptr->client = NULL;
  675. fail_stop_server:
  676. if (!jackctl_server_stop(controller_ptr->server))
  677. {
  678. jack_error("failed to stop jack server");
  679. }
  680. fail:
  681. return FALSE;
  682. }
  683. bool
  684. jack_controller_stop_server(
  685. struct jack_controller * controller_ptr,
  686. void *dbus_call_context_ptr)
  687. {
  688. int ret;
  689. jack_info("Stopping jack server...");
  690. if (!controller_ptr->started)
  691. {
  692. jack_info("Already stopped.");
  693. return TRUE;
  694. }
  695. ret = jack_deactivate(controller_ptr->client);
  696. if (ret != 0)
  697. {
  698. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to deactivate dbusapi jack client. error is %d", ret);
  699. }
  700. jack_controller_patchbay_uninit(controller_ptr);
  701. ret = jack_client_close(controller_ptr->client);
  702. if (ret != 0)
  703. {
  704. jack_error("jack_client_close() failed with error %d", ret);
  705. }
  706. controller_ptr->client = NULL;
  707. if (!jackctl_server_stop(controller_ptr->server))
  708. {
  709. return FALSE;
  710. }
  711. controller_ptr->started = false;
  712. return TRUE;
  713. }
  714. void *
  715. jack_controller_create(
  716. DBusConnection *connection)
  717. {
  718. struct jack_controller *controller_ptr;
  719. const JSList * node_ptr;
  720. const char ** driver_name_target;
  721. JSList * drivers;
  722. DBusObjectPathVTable vtable =
  723. {
  724. jack_dbus_message_handler_unregister,
  725. jack_dbus_message_handler,
  726. NULL
  727. };
  728. controller_ptr = malloc(sizeof(struct jack_controller));
  729. if (!controller_ptr)
  730. {
  731. jack_error("Ran out of memory trying to allocate struct jack_controller");
  732. goto fail;
  733. }
  734. controller_ptr->server = jackctl_server_create();
  735. if (controller_ptr->server == NULL)
  736. {
  737. jack_error("Failed to create server object");
  738. goto fail_free;
  739. }
  740. controller_ptr->client = NULL;
  741. controller_ptr->started = false;
  742. drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server);
  743. controller_ptr->drivers_count = jack_slist_length(drivers);
  744. controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *));
  745. if (controller_ptr->driver_names == NULL)
  746. {
  747. jack_error("Ran out of memory trying to allocate driver names array");
  748. goto fail_destroy_server;
  749. }
  750. driver_name_target = controller_ptr->driver_names;
  751. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  752. while (node_ptr != NULL)
  753. {
  754. *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data);
  755. node_ptr = jack_slist_next(node_ptr);
  756. driver_name_target++;
  757. }
  758. controller_ptr->dbus_descriptor.context = controller_ptr;
  759. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  760. if (!dbus_connection_register_object_path(
  761. connection,
  762. JACK_CONTROLLER_OBJECT_PATH,
  763. &vtable,
  764. &controller_ptr->dbus_descriptor))
  765. {
  766. jack_error("Ran out of memory trying to register D-Bus object path");
  767. goto fail_free_driver_names_array;
  768. }
  769. jack_controller_settings_load(controller_ptr);
  770. return controller_ptr;
  771. fail_free_driver_names_array:
  772. free(controller_ptr->driver_names);
  773. fail_destroy_server:
  774. jackctl_server_destroy(controller_ptr->server);
  775. fail_free:
  776. free(controller_ptr);
  777. fail:
  778. return NULL;
  779. }
  780. #define controller_ptr ((struct jack_controller *)context)
  781. void
  782. jack_controller_destroy(
  783. void * context)
  784. {
  785. if (controller_ptr->started)
  786. {
  787. jack_controller_stop_server(controller_ptr, NULL);
  788. }
  789. free(controller_ptr->driver_names);
  790. jackctl_server_destroy(controller_ptr->server);
  791. free(controller_ptr);
  792. }
  793. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  794. /*
  795. Copyright (C) 2007,2008 Nedko Arnaudov
  796. Copyright (C) 2007-2008 Juuso Alasuutari
  797. This program is free software; you can redistribute it and/or modify
  798. it under the terms of the GNU General Public License as published by
  799. the Free Software Foundation; either version 2 of the License.
  800. This program is distributed in the hope that it will be useful,
  801. but WITHOUT ANY WARRANTY; without even the implied warranty of
  802. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  803. GNU General Public License for more details.
  804. You should have received a copy of the GNU General Public License
  805. along with this program; if not, write to the Free Software
  806. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  807. */
  808. #include <stdint.h>
  809. #include <string.h>
  810. #include <dbus/dbus.h>
  811. #include "controller.h"
  812. #include "controller_internal.h"
  813. #include "xml.h"
  814. struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] =
  815. {
  816. &g_jack_controller_iface_introspectable,
  817. &g_jack_controller_iface_control,
  818. &g_jack_controller_iface_configure,
  819. &g_jack_controller_iface_patchbay,
  820. &g_jack_controller_iface_transport,
  821. NULL
  822. };
  823. jackctl_driver_t *
  824. jack_controller_find_driver(
  825. jackctl_server_t *server,
  826. const char *driver_name)
  827. {
  828. const JSList * node_ptr;
  829. node_ptr = jackctl_server_get_drivers_list(server);
  830. while (node_ptr)
  831. {
  832. if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0)
  833. {
  834. return node_ptr->data;
  835. }
  836. node_ptr = jack_slist_next(node_ptr);
  837. }
  838. return NULL;
  839. }
  840. jackctl_parameter_t *
  841. jack_controller_find_parameter(
  842. const JSList * parameters_list,
  843. const char * parameter_name)
  844. {
  845. while (parameters_list)
  846. {
  847. if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
  848. {
  849. return parameters_list->data;
  850. }
  851. parameters_list = jack_slist_next(parameters_list);
  852. }
  853. return NULL;
  854. }
  855. bool
  856. jack_controller_select_driver(
  857. struct jack_controller * controller_ptr,
  858. const char * driver_name)
  859. {
  860. jackctl_driver_t *driver;
  861. driver = jack_controller_find_driver(controller_ptr->server, driver_name);
  862. if (driver == NULL)
  863. {
  864. return false;
  865. }
  866. jack_info("driver \"%s\" selected", driver_name);
  867. controller_ptr->driver = driver;
  868. return true;
  869. }
  870. static
  871. int
  872. jack_controller_xrun(void * arg)
  873. {
  874. ((struct jack_controller *)arg)->xruns++;
  875. return 0;
  876. }
  877. bool
  878. jack_controller_start_server(
  879. struct jack_controller * controller_ptr,
  880. void *dbus_call_context_ptr)
  881. {
  882. int ret;
  883. jack_info("Starting jack server...");
  884. if (controller_ptr->started)
  885. {
  886. jack_info("Already started.");
  887. return TRUE;
  888. }
  889. if (controller_ptr->driver == NULL)
  890. {
  891. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!");
  892. goto fail;
  893. }
  894. controller_ptr->xruns = 0;
  895. if (!jackctl_server_start(
  896. controller_ptr->server,
  897. controller_ptr->driver))
  898. {
  899. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server");
  900. goto fail;
  901. }
  902. controller_ptr->client = jack_client_open(
  903. "dbusapi",
  904. JackNoStartServer,
  905. NULL);
  906. if (controller_ptr->client == NULL)
  907. {
  908. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to create dbusapi jack client");
  909. goto fail_stop_server;
  910. }
  911. ret = jack_set_xrun_callback(controller_ptr->client, jack_controller_xrun, controller_ptr);
  912. if (ret != 0)
  913. {
  914. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to set xrun callback. error is %d", ret);
  915. goto fail_close_client;
  916. }
  917. if (!jack_controller_patchbay_init(controller_ptr))
  918. {
  919. jack_error("Failed to initialize patchbay district");
  920. goto fail_close_client;
  921. }
  922. ret = jack_activate(controller_ptr->client);
  923. if (ret != 0)
  924. {
  925. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to activate dbusapi jack client. error is %d", ret);
  926. goto fail_patchbay_uninit;
  927. }
  928. controller_ptr->started = true;
  929. return TRUE;
  930. fail_patchbay_uninit:
  931. jack_controller_patchbay_uninit(controller_ptr);
  932. fail_close_client:
  933. ret = jack_client_close(controller_ptr->client);
  934. if (ret != 0)
  935. {
  936. jack_error("jack_client_close() failed with error %d", ret);
  937. }
  938. controller_ptr->client = NULL;
  939. fail_stop_server:
  940. if (!jackctl_server_stop(controller_ptr->server))
  941. {
  942. jack_error("failed to stop jack server");
  943. }
  944. fail:
  945. return FALSE;
  946. }
  947. bool
  948. jack_controller_stop_server(
  949. struct jack_controller * controller_ptr,
  950. void *dbus_call_context_ptr)
  951. {
  952. int ret;
  953. jack_info("Stopping jack server...");
  954. if (!controller_ptr->started)
  955. {
  956. jack_info("Already stopped.");
  957. return TRUE;
  958. }
  959. ret = jack_deactivate(controller_ptr->client);
  960. if (ret != 0)
  961. {
  962. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "failed to deactivate dbusapi jack client. error is %d", ret);
  963. }
  964. jack_controller_patchbay_uninit(controller_ptr);
  965. ret = jack_client_close(controller_ptr->client);
  966. if (ret != 0)
  967. {
  968. jack_error("jack_client_close() failed with error %d", ret);
  969. }
  970. controller_ptr->client = NULL;
  971. if (!jackctl_server_stop(controller_ptr->server))
  972. {
  973. return FALSE;
  974. }
  975. controller_ptr->started = false;
  976. return TRUE;
  977. }
  978. void *
  979. jack_controller_create(
  980. DBusConnection *connection)
  981. {
  982. struct jack_controller *controller_ptr;
  983. const JSList * node_ptr;
  984. const char ** driver_name_target;
  985. JSList * drivers;
  986. DBusObjectPathVTable vtable =
  987. {
  988. jack_dbus_message_handler_unregister,
  989. jack_dbus_message_handler,
  990. NULL
  991. };
  992. controller_ptr = malloc(sizeof(struct jack_controller));
  993. if (!controller_ptr)
  994. {
  995. jack_error("Ran out of memory trying to allocate struct jack_controller");
  996. goto fail;
  997. }
  998. controller_ptr->server = jackctl_server_create();
  999. if (controller_ptr->server == NULL)
  1000. {
  1001. jack_error("Failed to create server object");
  1002. goto fail_free;
  1003. }
  1004. controller_ptr->client = NULL;
  1005. controller_ptr->started = false;
  1006. drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server);
  1007. controller_ptr->drivers_count = jack_slist_length(drivers);
  1008. controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *));
  1009. if (controller_ptr->driver_names == NULL)
  1010. {
  1011. jack_error("Ran out of memory trying to allocate driver names array");
  1012. goto fail_destroy_server;
  1013. }
  1014. driver_name_target = controller_ptr->driver_names;
  1015. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  1016. while (node_ptr != NULL)
  1017. {
  1018. *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data);
  1019. node_ptr = jack_slist_next(node_ptr);
  1020. driver_name_target++;
  1021. }
  1022. controller_ptr->dbus_descriptor.context = controller_ptr;
  1023. controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
  1024. if (!dbus_connection_register_object_path(
  1025. connection,
  1026. JACK_CONTROLLER_OBJECT_PATH,
  1027. &vtable,
  1028. &controller_ptr->dbus_descriptor))
  1029. {
  1030. jack_error("Ran out of memory trying to register D-Bus object path");
  1031. goto fail_free_driver_names_array;
  1032. }
  1033. jack_controller_settings_load(controller_ptr);
  1034. return controller_ptr;
  1035. fail_free_driver_names_array:
  1036. free(controller_ptr->driver_names);
  1037. fail_destroy_server:
  1038. jackctl_server_destroy(controller_ptr->server);
  1039. fail_free:
  1040. free(controller_ptr);
  1041. fail:
  1042. return NULL;
  1043. }
  1044. #define controller_ptr ((struct jack_controller *)context)
  1045. void
  1046. jack_controller_destroy(
  1047. void * context)
  1048. {
  1049. if (controller_ptr->started)
  1050. {
  1051. jack_controller_stop_server(controller_ptr, NULL);
  1052. }
  1053. free(controller_ptr->driver_names);
  1054. jackctl_server_destroy(controller_ptr->server);
  1055. free(controller_ptr);
  1056. }