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.

341 lines
9.9KB

  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. #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 (!jack_controller_start_server(controller_ptr, call))
  73. {
  74. jack_error ("Failed to start server");
  75. }
  76. else
  77. {
  78. jack_controller_control_send_signal_server_started();
  79. }
  80. }
  81. else if (strcmp (call->method_name, "StopServer") == 0)
  82. {
  83. if (!jack_controller_stop_server(controller_ptr, call))
  84. {
  85. jack_error ("Failed to stop server");
  86. }
  87. else
  88. {
  89. jack_controller_control_send_signal_server_stopped();
  90. }
  91. }
  92. else if (strcmp (call->method_name, "SwitchMaster") == 0)
  93. {
  94. if (!jack_controller_switch_master(controller_ptr, call))
  95. {
  96. jack_error ("Failed to switch master");
  97. }
  98. else
  99. {
  100. jack_controller_control_send_signal_server_stopped();
  101. }
  102. }
  103. else if (strcmp (call->method_name, "GetLoad") == 0)
  104. {
  105. if (!controller_ptr->started)
  106. {
  107. goto not_started;
  108. }
  109. type = DBUS_TYPE_DOUBLE;
  110. arg.doubl = jack_cpu_load(controller_ptr->client);
  111. }
  112. else if (strcmp (call->method_name, "GetXruns") == 0)
  113. {
  114. type = DBUS_TYPE_UINT32;
  115. arg.uint32 = controller_ptr->xruns;
  116. }
  117. else if (strcmp (call->method_name, "GetSampleRate") == 0)
  118. {
  119. if (!controller_ptr->started)
  120. {
  121. goto not_started;
  122. }
  123. type = DBUS_TYPE_UINT32;
  124. arg.uint32 = jack_get_sample_rate(controller_ptr->client);
  125. }
  126. else if (strcmp (call->method_name, "GetLatency") == 0)
  127. {
  128. if (!controller_ptr->started)
  129. {
  130. goto not_started;
  131. }
  132. type = DBUS_TYPE_DOUBLE;
  133. arg.doubl = ((float)jack_get_buffer_size(controller_ptr->client) / (float)jack_get_sample_rate(controller_ptr->client)) * 1000.0f;
  134. }
  135. else if (strcmp (call->method_name, "GetBufferSize") == 0)
  136. {
  137. if (!controller_ptr->started)
  138. {
  139. goto not_started;
  140. }
  141. type = DBUS_TYPE_UINT32;
  142. arg.uint32 = jack_get_buffer_size(controller_ptr->client);
  143. }
  144. else if (strcmp (call->method_name, "SetBufferSize") == 0)
  145. {
  146. dbus_uint32_t buffer_size;
  147. if (!controller_ptr->started)
  148. {
  149. goto not_started;
  150. }
  151. if (!jack_dbus_get_method_args(call, DBUS_TYPE_UINT32, &buffer_size, DBUS_TYPE_INVALID))
  152. {
  153. /* jack_dbus_get_method_args() has set reply for us */
  154. goto exit;
  155. }
  156. ret = jack_set_buffer_size(controller_ptr->client, buffer_size);
  157. if (ret != 0)
  158. {
  159. jack_dbus_error(
  160. call,
  161. JACK_DBUS_ERROR_GENERIC,
  162. "jack_set_buffer_size(%u) failed with error %d", (unsigned int)buffer_size, ret);
  163. goto exit;
  164. }
  165. }
  166. else if (strcmp (call->method_name, "IsRealtime") == 0)
  167. {
  168. type = DBUS_TYPE_BOOLEAN;
  169. arg.boolean = jack_is_realtime(controller_ptr->client) ? TRUE : FALSE;
  170. }
  171. else if (strcmp (call->method_name, "ResetXruns") == 0)
  172. {
  173. controller_ptr->xruns = 0;
  174. }
  175. else if (strcmp (call->method_name, "LoadInternal") == 0)
  176. {
  177. const char *internal_name;
  178. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
  179. {
  180. /* The method call had invalid arguments meaning that
  181. * get_method_args() has constructed an error for us.
  182. */
  183. goto exit;
  184. }
  185. if (!jack_controller_load_internal(controller_ptr, internal_name)) {
  186. jack_dbus_error(
  187. call,
  188. JACK_DBUS_ERROR_GENERIC,
  189. "jack_controller_load_internal failed for internal (%s)", internal_name);
  190. }
  191. }
  192. else if (strcmp (call->method_name, "UnloadInternal") == 0)
  193. {
  194. const char *internal_name;
  195. if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
  196. {
  197. /* The method call had invalid arguments meaning that
  198. * get_method_args() has constructed an error for us.
  199. */
  200. goto exit;
  201. }
  202. if (!jack_controller_unload_internal(controller_ptr, internal_name)) {
  203. jack_dbus_error(
  204. call,
  205. JACK_DBUS_ERROR_GENERIC,
  206. "jack_controller_unload_internal failed for internal (%s)", internal_name);
  207. }
  208. }
  209. else
  210. {
  211. return false;
  212. }
  213. jack_dbus_construct_method_return_single(call, type, arg);
  214. return true;
  215. not_started:
  216. jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING,
  217. "Can't execute method '%s' with stopped JACK server", call->method_name);
  218. exit:
  219. return true;
  220. }
  221. #undef controller_ptr
  222. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsStarted)
  223. JACK_DBUS_METHOD_ARGUMENT("started", "b", true)
  224. JACK_DBUS_METHOD_ARGUMENTS_END
  225. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StartServer)
  226. JACK_DBUS_METHOD_ARGUMENTS_END
  227. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer)
  228. JACK_DBUS_METHOD_ARGUMENTS_END
  229. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SwitchMaster)
  230. JACK_DBUS_METHOD_ARGUMENTS_END
  231. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad)
  232. JACK_DBUS_METHOD_ARGUMENT("load", "d", true)
  233. JACK_DBUS_METHOD_ARGUMENTS_END
  234. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetXruns)
  235. JACK_DBUS_METHOD_ARGUMENT("xruns_count", "u", true)
  236. JACK_DBUS_METHOD_ARGUMENTS_END
  237. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetSampleRate)
  238. JACK_DBUS_METHOD_ARGUMENT("sample_rate", "u", true)
  239. JACK_DBUS_METHOD_ARGUMENTS_END
  240. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLatency)
  241. JACK_DBUS_METHOD_ARGUMENT("latency_ms", "d", true)
  242. JACK_DBUS_METHOD_ARGUMENTS_END
  243. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetBufferSize)
  244. JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", true)
  245. JACK_DBUS_METHOD_ARGUMENTS_END
  246. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetBufferSize)
  247. JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", false)
  248. JACK_DBUS_METHOD_ARGUMENTS_END
  249. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsRealtime)
  250. JACK_DBUS_METHOD_ARGUMENT("realtime", "b", true)
  251. JACK_DBUS_METHOD_ARGUMENTS_END
  252. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns)
  253. JACK_DBUS_METHOD_ARGUMENTS_END
  254. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(LoadInternal)
  255. JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
  256. JACK_DBUS_METHOD_ARGUMENTS_END
  257. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnlooadInternal)
  258. JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
  259. JACK_DBUS_METHOD_ARGUMENTS_END
  260. JACK_DBUS_METHODS_BEGIN
  261. JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL)
  262. JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL)
  263. JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL)
  264. JACK_DBUS_METHOD_DESCRIBE(SwitchMaster, NULL)
  265. JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL)
  266. JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL)
  267. JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL)
  268. JACK_DBUS_METHOD_DESCRIBE(GetLatency, NULL)
  269. JACK_DBUS_METHOD_DESCRIBE(GetBufferSize, NULL)
  270. JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL)
  271. JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL)
  272. JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL)
  273. JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL)
  274. JACK_DBUS_METHOD_DESCRIBE(UnlooadInternal, NULL)
  275. JACK_DBUS_METHODS_END
  276. JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStarted)
  277. JACK_DBUS_SIGNAL_ARGUMENTS_END
  278. JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStopped)
  279. JACK_DBUS_SIGNAL_ARGUMENTS_END
  280. JACK_DBUS_SIGNALS_BEGIN
  281. JACK_DBUS_SIGNAL_DESCRIBE(ServerStarted)
  282. JACK_DBUS_SIGNAL_DESCRIBE(ServerStopped)
  283. JACK_DBUS_SIGNALS_END
  284. JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, JACK_DBUS_IFACE_NAME)
  285. JACK_DBUS_IFACE_HANDLER(jack_control_run_method)
  286. JACK_DBUS_IFACE_EXPOSE_METHODS
  287. JACK_DBUS_IFACE_EXPOSE_SIGNALS
  288. JACK_DBUS_IFACE_END