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.

423 lines
12KB

  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 <stdio.h>
  22. #include <assert.h>
  23. #include <dbus/dbus.h>
  24. #include "jackdbus.h"
  25. #include "controller_internal.h"
  26. #define JACK_DBUS_IFACE_NAME "org.jackaudio.JackControl"
  27. void
  28. jack_controller_control_send_signal_server_started()
  29. {
  30. jack_dbus_send_signal(
  31. JACK_CONTROLLER_OBJECT_PATH,
  32. JACK_DBUS_IFACE_NAME,
  33. "ServerStarted",
  34. DBUS_TYPE_INVALID);
  35. }
  36. void
  37. jack_controller_control_send_signal_server_stopped()
  38. {
  39. jack_dbus_send_signal(
  40. JACK_CONTROLLER_OBJECT_PATH,
  41. JACK_DBUS_IFACE_NAME,
  42. "ServerStopped",
  43. DBUS_TYPE_INVALID);
  44. }
  45. #define controller_ptr ((struct jack_controller *)call->context)
  46. /*
  47. * Check if the supplied method name exists in org.jackaudio.JackControl,
  48. * if it does execute it and return true. Otherwise return false.
  49. */
  50. static
  51. bool
  52. jack_control_run_method(
  53. struct jack_dbus_method_call * call,
  54. const struct jack_dbus_interface_method_descriptor * methods)
  55. {
  56. int ret;
  57. int type;
  58. message_arg_t arg;
  59. /* use empty reply if not overriden in the code that follows */
  60. type = DBUS_TYPE_INVALID;
  61. if (strcmp (call->method_name, "Exit") == 0)
  62. {
  63. g_exit_command = TRUE;
  64. }
  65. else if (strcmp (call->method_name, "IsStarted") == 0)
  66. {
  67. type = DBUS_TYPE_BOOLEAN;
  68. arg.boolean = (dbus_bool_t) (controller_ptr->started ? TRUE : FALSE);
  69. }
  70. else if (strcmp (call->method_name, "StartServer") == 0)
  71. {
  72. if (controller_ptr->started)
  73. {
  74. jack_info("Ignoring JACK server start request because server is already started.");
  75. }
  76. else
  77. {
  78. if (!jack_controller_start_server(controller_ptr, call))
  79. {
  80. /* the reply is set by the failed function */
  81. assert(call->reply != NULL);
  82. return true;
  83. }
  84. jack_controller_control_send_signal_server_started();
  85. }
  86. }
  87. else if (strcmp (call->method_name, "StopServer") == 0)
  88. {
  89. if (!controller_ptr->started)
  90. {
  91. jack_info("Ignoring JACK server stop request because server is already stopped.");
  92. }
  93. else
  94. {
  95. if (!jack_controller_stop_server(controller_ptr, call))
  96. {
  97. /* the reply is set by the failed function */
  98. assert(call->reply != NULL);
  99. return true;
  100. }
  101. jack_controller_control_send_signal_server_stopped();
  102. }
  103. }
  104. else if (strcmp (call->method_name, "SwitchMaster") == 0)
  105. {
  106. if (!jack_controller_switch_master(controller_ptr, call))
  107. {
  108. /* the reply is set by the failed function */
  109. assert(call->reply != NULL);
  110. return true;
  111. }
  112. }
  113. else if (strcmp (call->method_name, "GetLoad") == 0)
  114. {
  115. if (!controller_ptr->started)
  116. {
  117. goto not_started;
  118. }
  119. type = DBUS_TYPE_DOUBLE;
  120. arg.doubl = jack_cpu_load(controller_ptr->client);
  121. }
  122. else if (strcmp (call->method_name, "GetXruns") == 0)
  123. {
  124. type = DBUS_TYPE_UINT32;
  125. arg.uint32 = controller_ptr->xruns;
  126. }
  127. else if (strcmp (call->method_name, "GetSampleRate") == 0)
  128. {
  129. if (!controller_ptr->started)
  130. {
  131. goto not_started;
  132. }
  133. type = DBUS_TYPE_UINT32;
  134. arg.uint32 = jack_get_sample_rate(controller_ptr->client);
  135. }
  136. else if (strcmp (call->method_name, "GetLatency") == 0)
  137. {
  138. if (!controller_ptr->started)
  139. {
  140. goto not_started;
  141. }
  142. type = DBUS_TYPE_DOUBLE;
  143. arg.doubl = ((float)jack_get_buffer_size(controller_ptr->client) / (float)jack_get_sample_rate(controller_ptr->client)) * 1000.0f;
  144. }
  145. else if (strcmp (call->method_name, "GetBufferSize") == 0)
  146. {
  147. if (!controller_ptr->started)
  148. {
  149. goto not_started;
  150. }
  151. type = DBUS_TYPE_UINT32;
  152. arg.uint32 = jack_get_buffer_size(controller_ptr->client);
  153. }
  154. else if (strcmp (call->method_name, "SetBufferSize") == 0)
  155. {
  156. dbus_uint32_t buffer_size;
  157. if (!controller_ptr->started)
  158. {
  159. goto not_started;
  160. }
  161. if (!jack_dbus_get_method_args(call, DBUS_TYPE_UINT32, &buffer_size, DBUS_TYPE_INVALID))
  162. {
  163. /* jack_dbus_get_method_args() has set reply for us */
  164. goto exit;
  165. }
  166. ret = jack_set_buffer_size(controller_ptr->client, buffer_size);
  167. if (ret != 0)
  168. {
  169. jack_dbus_error(
  170. call,
  171. JACK_DBUS_ERROR_GENERIC,
  172. "jack_set_buffer_size(%u) failed with error %d", (unsigned int)buffer_size, ret);
  173. goto exit;
  174. }
  175. }
  176. else if (strcmp (call->method_name, "IsRealtime") == 0)
  177. {
  178. type = DBUS_TYPE_BOOLEAN;
  179. arg.boolean = jack_is_realtime(controller_ptr->client) ? TRUE : FALSE;
  180. }
  181. else if (strcmp (call->method_name, "ResetXruns") == 0)
  182. {
  183. controller_ptr->xruns = 0;
  184. }
  185. else if (strcmp (call->method_name, "LoadInternal") == 0)
  186. {
  187. const char *internal_name;
  188. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
  189. {
  190. /* The method call had invalid arguments meaning that
  191. * get_method_args() has constructed an error for us.
  192. */
  193. goto exit;
  194. }
  195. if (!jack_controller_load_internal(controller_ptr, internal_name)) {
  196. jack_dbus_error(
  197. call,
  198. JACK_DBUS_ERROR_GENERIC,
  199. "jack_controller_load_internal failed for internal (%s)", internal_name);
  200. }
  201. }
  202. else if (strcmp (call->method_name, "AddSlaveDriver") == 0)
  203. {
  204. const char *driver_name;
  205. if (controller_ptr->started)
  206. {
  207. goto fail_started;
  208. }
  209. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &driver_name, DBUS_TYPE_INVALID))
  210. {
  211. /* The method call had invalid arguments meaning that
  212. * get_method_args() has constructed an error for us.
  213. */
  214. goto exit;
  215. }
  216. if (!jack_controller_add_slave_driver(controller_ptr, driver_name)) {
  217. jack_dbus_error(
  218. call,
  219. JACK_DBUS_ERROR_GENERIC,
  220. "jack_controller_add_slave_driver failed for driver (%s)", driver_name);
  221. }
  222. }
  223. else if (strcmp (call->method_name, "RemoveSlaveDriver") == 0)
  224. {
  225. const char *driver_name;
  226. if (controller_ptr->started)
  227. {
  228. goto fail_started;
  229. }
  230. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &driver_name, DBUS_TYPE_INVALID))
  231. {
  232. /* The method call had invalid arguments meaning that
  233. * get_method_args() has constructed an error for us.
  234. */
  235. goto exit;
  236. }
  237. if (!jack_controller_remove_slave_driver(controller_ptr, driver_name)) {
  238. jack_dbus_error(
  239. call,
  240. JACK_DBUS_ERROR_GENERIC,
  241. "jack_controller_remove_slave_driver failed for driver (%s)", driver_name);
  242. }
  243. }
  244. else if (strcmp (call->method_name, "UnloadInternal") == 0)
  245. {
  246. const char *internal_name;
  247. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
  248. {
  249. /* The method call had invalid arguments meaning that
  250. * get_method_args() has constructed an error for us.
  251. */
  252. goto exit;
  253. }
  254. if (!jack_controller_unload_internal(controller_ptr, internal_name)) {
  255. jack_dbus_error(
  256. call,
  257. JACK_DBUS_ERROR_GENERIC,
  258. "jack_controller_unload_internal failed for internal (%s)", internal_name);
  259. }
  260. }
  261. else
  262. {
  263. return false;
  264. }
  265. jack_dbus_construct_method_return_single(call, type, arg);
  266. goto exit;
  267. not_started:
  268. jack_dbus_only_error(
  269. call,
  270. JACK_DBUS_ERROR_SERVER_NOT_RUNNING,
  271. "Can't execute method '%s' with stopped JACK server",
  272. call->method_name);
  273. goto exit;
  274. fail_started:
  275. jack_dbus_only_error(
  276. call,
  277. JACK_DBUS_ERROR_SERVER_RUNNING,
  278. "Can't execute method '%s' with started JACK server",
  279. call->method_name);
  280. goto exit;
  281. exit:
  282. return true;
  283. }
  284. #undef controller_ptr
  285. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsStarted)
  286. JACK_DBUS_METHOD_ARGUMENT("started", "b", true)
  287. JACK_DBUS_METHOD_ARGUMENTS_END
  288. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StartServer)
  289. JACK_DBUS_METHOD_ARGUMENTS_END
  290. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer)
  291. JACK_DBUS_METHOD_ARGUMENTS_END
  292. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SwitchMaster)
  293. JACK_DBUS_METHOD_ARGUMENTS_END
  294. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad)
  295. JACK_DBUS_METHOD_ARGUMENT("load", "d", true)
  296. JACK_DBUS_METHOD_ARGUMENTS_END
  297. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetXruns)
  298. JACK_DBUS_METHOD_ARGUMENT("xruns_count", "u", true)
  299. JACK_DBUS_METHOD_ARGUMENTS_END
  300. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetSampleRate)
  301. JACK_DBUS_METHOD_ARGUMENT("sample_rate", "u", true)
  302. JACK_DBUS_METHOD_ARGUMENTS_END
  303. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLatency)
  304. JACK_DBUS_METHOD_ARGUMENT("latency_ms", "d", true)
  305. JACK_DBUS_METHOD_ARGUMENTS_END
  306. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetBufferSize)
  307. JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", true)
  308. JACK_DBUS_METHOD_ARGUMENTS_END
  309. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetBufferSize)
  310. JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", false)
  311. JACK_DBUS_METHOD_ARGUMENTS_END
  312. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsRealtime)
  313. JACK_DBUS_METHOD_ARGUMENT("realtime", "b", true)
  314. JACK_DBUS_METHOD_ARGUMENTS_END
  315. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns)
  316. JACK_DBUS_METHOD_ARGUMENTS_END
  317. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(LoadInternal)
  318. JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
  319. JACK_DBUS_METHOD_ARGUMENTS_END
  320. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnloadInternal)
  321. JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
  322. JACK_DBUS_METHOD_ARGUMENTS_END
  323. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(AddSlaveDriver)
  324. JACK_DBUS_METHOD_ARGUMENT("driver_name", "s", false)
  325. JACK_DBUS_METHOD_ARGUMENTS_END
  326. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(RemoveSlaveDriver)
  327. JACK_DBUS_METHOD_ARGUMENT("driver_name", "s", false)
  328. JACK_DBUS_METHOD_ARGUMENTS_END
  329. JACK_DBUS_METHODS_BEGIN
  330. JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL)
  331. JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL)
  332. JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL)
  333. JACK_DBUS_METHOD_DESCRIBE(SwitchMaster, NULL)
  334. JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL)
  335. JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL)
  336. JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL)
  337. JACK_DBUS_METHOD_DESCRIBE(GetLatency, NULL)
  338. JACK_DBUS_METHOD_DESCRIBE(GetBufferSize, NULL)
  339. JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL)
  340. JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL)
  341. JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL)
  342. JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL)
  343. JACK_DBUS_METHOD_DESCRIBE(UnloadInternal, NULL)
  344. JACK_DBUS_METHOD_DESCRIBE(AddSlaveDriver, NULL)
  345. JACK_DBUS_METHOD_DESCRIBE(RemoveSlaveDriver, NULL)
  346. JACK_DBUS_METHODS_END
  347. JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStarted)
  348. JACK_DBUS_SIGNAL_ARGUMENTS_END
  349. JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStopped)
  350. JACK_DBUS_SIGNAL_ARGUMENTS_END
  351. JACK_DBUS_SIGNALS_BEGIN
  352. JACK_DBUS_SIGNAL_DESCRIBE(ServerStarted)
  353. JACK_DBUS_SIGNAL_DESCRIBE(ServerStopped)
  354. JACK_DBUS_SIGNALS_END
  355. JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, JACK_DBUS_IFACE_NAME)
  356. JACK_DBUS_IFACE_HANDLER(jack_control_run_method)
  357. JACK_DBUS_IFACE_EXPOSE_METHODS
  358. JACK_DBUS_IFACE_EXPOSE_SIGNALS
  359. JACK_DBUS_IFACE_END