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.

321 lines
9.6KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2011 Nedko Arnaudov
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #if defined(HAVE_CONFIG_H)
  16. #include "config.h"
  17. #endif
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <assert.h>
  22. #include <dbus/dbus.h>
  23. #include "jackdbus.h"
  24. #include "controller_internal.h"
  25. #include "jack/session.h"
  26. #define controller_ptr ((struct jack_controller *)call->context)
  27. static
  28. void
  29. jack_controller_dbus_session_notify(
  30. struct jack_dbus_method_call * call)
  31. {
  32. const char * target;
  33. dbus_uint32_t u32;
  34. const char * path;
  35. jack_session_event_type_t type;
  36. jack_session_command_t * commands;
  37. const jack_session_command_t * cmd_ptr;
  38. DBusMessageIter top_iter, array_iter, struct_iter;
  39. if (!jack_dbus_get_method_args(
  40. call,
  41. DBUS_TYPE_STRING,
  42. &target,
  43. DBUS_TYPE_UINT32,
  44. &u32,
  45. DBUS_TYPE_STRING,
  46. &path,
  47. DBUS_TYPE_INVALID))
  48. {
  49. /* The method call had invalid arguments meaning that jack_dbus_get_method_args() has constructed an error for us. */
  50. goto exit;
  51. }
  52. jack_info("Session notify initiated. target='%s', type=%"PRIu32", path='%s'", target, u32, path);
  53. if (*target == 0)
  54. {
  55. target = NULL;
  56. }
  57. type = (jack_session_event_type_t)u32;
  58. if (type != JackSessionSave &&
  59. type != JackSessionSaveAndQuit &&
  60. type != JackSessionSaveTemplate)
  61. {
  62. jack_dbus_error(call, JACK_DBUS_ERROR_INVALID_ARGS, "Invalid session event type %" PRIu32, u32);
  63. goto exit;
  64. }
  65. commands = jack_session_notify(controller_ptr->client, target, type, path);
  66. if (commands == NULL)
  67. {
  68. jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "jack_session_notify() failed");
  69. goto exit;
  70. }
  71. jack_info("Session notify complete, commands follow:");
  72. call->reply = dbus_message_new_method_return(call->message);
  73. if (call->reply == NULL)
  74. {
  75. goto oom;
  76. }
  77. dbus_message_iter_init_append(call->reply, &top_iter);
  78. if (!dbus_message_iter_open_container(&top_iter, DBUS_TYPE_ARRAY, "(sssu)", &array_iter))
  79. {
  80. goto unref;
  81. }
  82. for (cmd_ptr = commands; cmd_ptr->uuid != NULL; cmd_ptr++)
  83. {
  84. if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
  85. {
  86. goto close_array;
  87. }
  88. if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &cmd_ptr->uuid))
  89. {
  90. goto close_struct;
  91. }
  92. if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &cmd_ptr->client_name))
  93. {
  94. goto close_struct;
  95. }
  96. if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &cmd_ptr->command))
  97. {
  98. goto close_struct;
  99. }
  100. u32 = cmd_ptr->flags;
  101. if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &u32))
  102. {
  103. goto close_struct;
  104. }
  105. jack_info("uuid='%s', client='%s', command='%s', flags=0x%"PRIX32, cmd_ptr->uuid, cmd_ptr->client_name, cmd_ptr->command, u32);
  106. if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
  107. {
  108. goto close_array;
  109. }
  110. }
  111. jack_info("End of session commands.");
  112. if (!dbus_message_iter_close_container(&top_iter, &array_iter))
  113. {
  114. goto unref;
  115. }
  116. goto free;
  117. close_struct:
  118. dbus_message_iter_close_container(&array_iter, &struct_iter);
  119. close_array:
  120. dbus_message_iter_close_container(&top_iter, &array_iter);
  121. unref:
  122. dbus_message_unref(call->reply);
  123. call->reply = NULL;
  124. oom:
  125. jack_error("Ran out of memory trying to construct method return");
  126. free:
  127. jack_session_commands_free(commands);
  128. exit:
  129. return;
  130. }
  131. static
  132. void
  133. jack_controller_dbus_get_uuid_for_client_name(
  134. struct jack_dbus_method_call * call)
  135. {
  136. const char * client_name;
  137. char * client_uuid;
  138. if (!jack_dbus_get_method_args(
  139. call,
  140. DBUS_TYPE_STRING,
  141. &client_name,
  142. DBUS_TYPE_INVALID))
  143. {
  144. /* The method call had invalid arguments meaning that jack_dbus_get_method_args() has constructed an error for us. */
  145. return;
  146. }
  147. client_uuid = jack_get_uuid_for_client_name(controller_ptr->client, client_name);
  148. if (client_uuid == NULL)
  149. {
  150. jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "jack_get_uuid_for_client_name(\"%s\") failed", client_name);
  151. return;
  152. }
  153. jack_dbus_construct_method_return_single(call, DBUS_TYPE_STRING, (message_arg_t)(const char *)client_uuid);
  154. free(client_uuid);
  155. }
  156. static
  157. void
  158. jack_controller_dbus_get_client_name_by_uuid(
  159. struct jack_dbus_method_call * call)
  160. {
  161. const char * client_uuid;
  162. char * client_name;
  163. if (!jack_dbus_get_method_args(
  164. call,
  165. DBUS_TYPE_STRING,
  166. &client_uuid,
  167. DBUS_TYPE_INVALID))
  168. {
  169. /* The method call had invalid arguments meaning that jack_dbus_get_method_args() has constructed an error for us. */
  170. return;
  171. }
  172. client_name = jack_get_client_name_by_uuid(controller_ptr->client, client_uuid);
  173. if (client_name == NULL)
  174. {
  175. jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "jack_get_client_name_by_uuid(\"%s\") failed", client_uuid);
  176. return;
  177. }
  178. jack_dbus_construct_method_return_single(call, DBUS_TYPE_STRING, (message_arg_t)(const char *)client_name);
  179. free(client_name);
  180. }
  181. static
  182. void
  183. jack_controller_dbus_reserve_client_name(
  184. struct jack_dbus_method_call * call)
  185. {
  186. int ret;
  187. const char * client_name;
  188. const char * client_uuid;
  189. if (!jack_dbus_get_method_args(
  190. call,
  191. DBUS_TYPE_STRING,
  192. &client_name,
  193. DBUS_TYPE_STRING,
  194. &client_uuid,
  195. DBUS_TYPE_INVALID))
  196. {
  197. /* The method call had invalid arguments meaning that jack_dbus_get_method_args() has constructed an error for us. */
  198. return;
  199. }
  200. ret = jack_reserve_client_name(controller_ptr->client, client_name, client_uuid);
  201. if (ret < 0)
  202. {
  203. jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "jack_reserve_client_name(name=\"%s\", uuid=\"%s\") failed (%d)", client_name, client_uuid, ret);
  204. return;
  205. }
  206. jack_dbus_construct_method_return_empty(call);
  207. }
  208. static
  209. void
  210. jack_controller_dbus_has_session_callback(
  211. struct jack_dbus_method_call * call)
  212. {
  213. int ret;
  214. const char * client_name;
  215. message_arg_t retval;
  216. if (!jack_dbus_get_method_args(
  217. call,
  218. DBUS_TYPE_STRING,
  219. &client_name,
  220. DBUS_TYPE_INVALID))
  221. {
  222. /* The method call had invalid arguments meaning that jack_dbus_get_method_args() has constructed an error for us. */
  223. return;
  224. }
  225. ret = jack_client_has_session_callback(controller_ptr->client, client_name);
  226. if (ret < 0)
  227. {
  228. jack_dbus_error(call, JACK_DBUS_ERROR_GENERIC, "jack_client_has_session_callback(\"%s\") failed (%d)", client_name, ret);
  229. return;
  230. }
  231. retval.boolean = ret;
  232. jack_dbus_construct_method_return_single(call, DBUS_TYPE_BOOLEAN, retval);
  233. }
  234. #undef controller_ptr
  235. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(Notify)
  236. JACK_DBUS_METHOD_ARGUMENT("target", DBUS_TYPE_STRING_AS_STRING, false)
  237. JACK_DBUS_METHOD_ARGUMENT("type", DBUS_TYPE_UINT32_AS_STRING, false)
  238. JACK_DBUS_METHOD_ARGUMENT("path", DBUS_TYPE_STRING_AS_STRING, false)
  239. JACK_DBUS_METHOD_ARGUMENT("result", "a(sssu)", true)
  240. JACK_DBUS_METHOD_ARGUMENTS_END
  241. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetUuidForClientName)
  242. JACK_DBUS_METHOD_ARGUMENT("name", DBUS_TYPE_STRING_AS_STRING, false)
  243. JACK_DBUS_METHOD_ARGUMENT("uuid", DBUS_TYPE_STRING_AS_STRING, true)
  244. JACK_DBUS_METHOD_ARGUMENTS_END
  245. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetClientNameByUuid)
  246. JACK_DBUS_METHOD_ARGUMENT("uuid", DBUS_TYPE_STRING_AS_STRING, false)
  247. JACK_DBUS_METHOD_ARGUMENT("name", DBUS_TYPE_STRING_AS_STRING, true)
  248. JACK_DBUS_METHOD_ARGUMENTS_END
  249. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ReserveClientName)
  250. JACK_DBUS_METHOD_ARGUMENT("name", DBUS_TYPE_STRING_AS_STRING, false)
  251. JACK_DBUS_METHOD_ARGUMENT("uuid", DBUS_TYPE_STRING_AS_STRING, false)
  252. JACK_DBUS_METHOD_ARGUMENTS_END
  253. JACK_DBUS_METHOD_ARGUMENTS_BEGIN(HasSessionCallback)
  254. JACK_DBUS_METHOD_ARGUMENT("client_name", DBUS_TYPE_STRING_AS_STRING, false)
  255. JACK_DBUS_METHOD_ARGUMENT("has_session_callback", DBUS_TYPE_BOOLEAN_AS_STRING, true)
  256. JACK_DBUS_METHOD_ARGUMENTS_END
  257. JACK_DBUS_METHODS_BEGIN
  258. JACK_DBUS_METHOD_DESCRIBE(Notify, jack_controller_dbus_session_notify)
  259. JACK_DBUS_METHOD_DESCRIBE(GetUuidForClientName, jack_controller_dbus_get_uuid_for_client_name)
  260. JACK_DBUS_METHOD_DESCRIBE(GetClientNameByUuid, jack_controller_dbus_get_client_name_by_uuid)
  261. JACK_DBUS_METHOD_DESCRIBE(ReserveClientName, jack_controller_dbus_reserve_client_name)
  262. JACK_DBUS_METHOD_DESCRIBE(HasSessionCallback, jack_controller_dbus_has_session_callback)
  263. JACK_DBUS_METHODS_END
  264. JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_session_manager, "org.jackaudio.SessionManager")
  265. JACK_DBUS_IFACE_EXPOSE_METHODS
  266. JACK_DBUS_IFACE_END