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.

215 lines
6.5KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2004-2008 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  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 Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "JackDebugClient.h"
  17. #include "JackLibClient.h"
  18. #include "JackChannel.h"
  19. #include "JackLibGlobals.h"
  20. #include "JackGlobals.h"
  21. #include "JackCompilerDeps.h"
  22. #include "JackTools.h"
  23. #include "JackSystemDeps.h"
  24. #include "JackServerLaunch.h"
  25. #include "JackMetadata.h"
  26. #include <assert.h>
  27. using namespace Jack;
  28. #ifdef __cplusplus
  29. extern "C"
  30. {
  31. #endif
  32. jack_client_t * jack_client_new_aux (const char *client_name,
  33. jack_options_t options,
  34. jack_status_t *status);
  35. LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
  36. jack_options_t options,
  37. jack_status_t *status, ...);
  38. LIB_EXPORT int jack_client_close (jack_client_t *client);
  39. LIB_EXPORT int jack_get_client_pid (const char *name);
  40. #ifdef __cplusplus
  41. }
  42. #endif
  43. static jack_client_t * jack_client_open_aux (const char *client_name,
  44. jack_options_t options,
  45. jack_status_t *status, va_list ap);
  46. JackLibGlobals* JackLibGlobals::fGlobals = NULL;
  47. int JackLibGlobals::fClientCount = 0;
  48. jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
  49. {
  50. jack_varargs_t va; /* variable arguments */
  51. jack_status_t my_status;
  52. JackClient* client;
  53. if (client_name == NULL) {
  54. jack_error("jack_client_new called with a NULL client_name");
  55. return NULL;
  56. }
  57. jack_log("jack_client_new %s", client_name);
  58. if (status == NULL) /* no status from caller? */
  59. status = &my_status; /* use local status word */
  60. *status = (jack_status_t)0;
  61. /* validate parameters */
  62. if ((options & ~JackOpenOptions)) {
  63. int my_status1 = *status | (JackFailure | JackInvalidOption);
  64. *status = (jack_status_t)my_status1;
  65. return NULL;
  66. }
  67. /* parse variable arguments */
  68. jack_varargs_init(&va);
  69. JackLibGlobals::Init(); // jack library initialisation
  70. if (try_start_server(&va, options, status)) {
  71. jack_error("jack server is not running or cannot be started");
  72. JackLibGlobals::Destroy(); // jack library destruction
  73. return 0;
  74. }
  75. if (JACK_DEBUG) {
  76. client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
  77. } else {
  78. client = new JackLibClient(GetSynchroTable());
  79. }
  80. int res = client->Open(va.server_name, client_name, va.session_id, options, status);
  81. if (res < 0) {
  82. delete client;
  83. JackLibGlobals::Destroy(); // jack library destruction
  84. int my_status1 = (JackFailure | JackServerError);
  85. *status = (jack_status_t)my_status1;
  86. return NULL;
  87. } else {
  88. return (jack_client_t*)client;
  89. }
  90. }
  91. static jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
  92. {
  93. jack_varargs_t va; /* variable arguments */
  94. jack_status_t my_status;
  95. JackClient* client;
  96. if (client_name == NULL) {
  97. jack_error("jack_client_open called with a NULL client_name");
  98. return NULL;
  99. }
  100. jack_log("jack_client_open %s", client_name);
  101. if (status == NULL) /* no status from caller? */
  102. status = &my_status; /* use local status word */
  103. *status = (jack_status_t)0;
  104. /* validate parameters */
  105. if ((options & ~JackOpenOptions)) {
  106. int my_status1 = *status | (JackFailure | JackInvalidOption);
  107. *status = (jack_status_t)my_status1;
  108. return NULL;
  109. }
  110. /* parse variable arguments */
  111. jack_varargs_parse(options, ap, &va);
  112. JackLibGlobals::Init(); // jack library initialisation
  113. if (try_start_server(&va, options, status)) {
  114. jack_error("jack server is not running or cannot be started");
  115. JackLibGlobals::Destroy(); // jack library destruction
  116. return 0;
  117. }
  118. if (JACK_DEBUG) {
  119. client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
  120. } else {
  121. client = new JackLibClient(GetSynchroTable());
  122. }
  123. int res = client->Open(va.server_name, client_name, va.session_id, options, status);
  124. if (res < 0) {
  125. delete client;
  126. JackLibGlobals::Destroy(); // jack library destruction
  127. int my_status1 = (JackFailure | JackServerError);
  128. *status = (jack_status_t)my_status1;
  129. return NULL;
  130. } else {
  131. return (jack_client_t*)client;
  132. }
  133. }
  134. LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
  135. {
  136. JackGlobals::CheckContext("jack_client_open");
  137. try {
  138. assert(JackGlobals::fOpenMutex);
  139. JackGlobals::fOpenMutex->Lock();
  140. va_list ap;
  141. va_start(ap, status);
  142. jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
  143. va_end(ap);
  144. JackGlobals::fOpenMutex->Unlock();
  145. return res;
  146. } catch (std::bad_alloc& e) {
  147. jack_error("Memory allocation error...");
  148. return NULL;
  149. } catch (...) {
  150. jack_error("Unknown error...");
  151. return NULL;
  152. }
  153. }
  154. LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
  155. {
  156. JackGlobals::CheckContext("jack_client_close");
  157. assert(JackGlobals::fOpenMutex);
  158. JackGlobals::fOpenMutex->Lock();
  159. int res = -1;
  160. jack_log("jack_client_close");
  161. JackClient* client = (JackClient*)ext_client;
  162. if (client == NULL) {
  163. jack_error("jack_client_close called with a NULL client");
  164. } else {
  165. res = client->Close();
  166. delete client;
  167. JackLibGlobals::Destroy(); // jack library destruction
  168. jack_log("jack_client_close res = %d", res);
  169. }
  170. JackGlobals::fOpenMutex->Unlock();
  171. return res;
  172. }
  173. LIB_EXPORT int jack_get_client_pid(const char *name)
  174. {
  175. jack_error("jack_get_client_pid : not implemented on library side");
  176. return 0;
  177. }