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.

239 lines
6.7KB

  1. /*
  2. Copyright (C) 2001 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 General Public License as published by
  6. the Free Software Foundation; either version 2 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 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 "JackSystemDeps.h"
  17. #include "JackServerGlobals.h"
  18. #include "JackGraphManager.h"
  19. #include "JackConstants.h"
  20. #include "JackInternalClient.h"
  21. #include "JackLockedEngine.h"
  22. #include "JackServer.h"
  23. #include "JackEngineControl.h"
  24. #include "JackClientControl.h"
  25. #include "JackInternalClientChannel.h"
  26. #include "JackGenericClientChannel.h"
  27. #include "JackTools.h"
  28. #include <assert.h>
  29. namespace Jack
  30. {
  31. JackGraphManager* JackInternalClient::fGraphManager = NULL;
  32. JackEngineControl* JackInternalClient::fEngineControl = NULL;
  33. // Used for external C API (JackAPI.cpp)
  34. SERVER_EXPORT JackGraphManager* GetGraphManager()
  35. {
  36. return JackServerGlobals::fInstance->GetGraphManager();
  37. }
  38. SERVER_EXPORT JackEngineControl* GetEngineControl()
  39. {
  40. return JackServerGlobals::fInstance->GetEngineControl();
  41. }
  42. SERVER_EXPORT JackSynchro* GetSynchroTable()
  43. {
  44. return JackServerGlobals::fInstance->GetSynchroTable();
  45. }
  46. JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table)
  47. {
  48. fChannel = new JackInternalClientChannel(server);
  49. //fChannel = new JackGenericClientChannel();
  50. }
  51. JackInternalClient::~JackInternalClient()
  52. {
  53. delete fChannel;
  54. }
  55. int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
  56. {
  57. int result;
  58. char name_res[JACK_CLIENT_NAME_SIZE + 1];
  59. jack_log("JackInternalClient::Open name = %s", name);
  60. strncpy(fServerName, server_name, sizeof(fServerName));
  61. fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, false);
  62. if (result < 0) {
  63. int status1 = *status;
  64. if (status1 & JackVersionError) {
  65. jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
  66. } else {
  67. jack_error("Client name = %s conflits with another running client", name);
  68. }
  69. goto error;
  70. }
  71. strcpy(fClientControl.fName, name_res);
  72. // Require new client
  73. fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result);
  74. if (result < 0) {
  75. jack_error("Cannot open client name = %s", name_res);
  76. goto error;
  77. }
  78. SetupDriverSync(false);
  79. JackGlobals::fClientTable[fClientControl.fRefNum] = this;
  80. JackGlobals::fServerRunning = true;
  81. jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum);
  82. return 0;
  83. error:
  84. fChannel->Close();
  85. return -1;
  86. }
  87. JackGraphManager* JackInternalClient::GetGraphManager() const
  88. {
  89. assert(fGraphManager);
  90. return fGraphManager;
  91. }
  92. JackEngineControl* JackInternalClient::GetEngineControl() const
  93. {
  94. assert(fEngineControl);
  95. return fEngineControl;
  96. }
  97. JackClientControl* JackInternalClient::GetClientControl() const
  98. {
  99. return const_cast<JackClientControl*>(&fClientControl);
  100. }
  101. int JackLoadableInternalClient::Init(const char* so_name)
  102. {
  103. char path_to_so[JACK_PATH_MAX + 1];
  104. BuildClientPath(path_to_so, sizeof(path_to_so), so_name);
  105. fHandle = LoadJackModule(path_to_so);
  106. jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so);
  107. if (fHandle == NULL) {
  108. PrintLoadError(so_name);
  109. return -1;
  110. }
  111. fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish");
  112. if (fFinish == NULL) {
  113. UnloadJackModule(fHandle);
  114. jack_error("symbol jack_finish cannot be found in %s", so_name);
  115. return -1;
  116. }
  117. fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor");
  118. if (fDescriptor == NULL) {
  119. jack_info("No jack_get_descriptor entry-point for %s", so_name);
  120. }
  121. return 0;
  122. }
  123. int JackLoadableInternalClient1::Init(const char* so_name)
  124. {
  125. if (JackLoadableInternalClient::Init(so_name) < 0) {
  126. return -1;
  127. }
  128. fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize");
  129. if (fInitialize == NULL) {
  130. UnloadJackModule(fHandle);
  131. jack_error("symbol jack_initialize cannot be found in %s", so_name);
  132. return -1;
  133. }
  134. return 0;
  135. }
  136. int JackLoadableInternalClient2::Init(const char* so_name)
  137. {
  138. if (JackLoadableInternalClient::Init(so_name) < 0) {
  139. return -1;
  140. }
  141. fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize");
  142. if (fInitialize == NULL) {
  143. UnloadJackModule(fHandle);
  144. jack_error("symbol jack_internal_initialize cannot be found in %s", so_name);
  145. return -1;
  146. }
  147. return 0;
  148. }
  149. JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data)
  150. : JackLoadableInternalClient(server, table)
  151. {
  152. strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT);
  153. }
  154. JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters)
  155. : JackLoadableInternalClient(server, table)
  156. {
  157. fParameters = parameters;
  158. }
  159. JackLoadableInternalClient::~JackLoadableInternalClient()
  160. {
  161. if (fFinish != NULL)
  162. fFinish(fProcessArg);
  163. if (fHandle != NULL)
  164. UnloadJackModule(fHandle);
  165. }
  166. int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
  167. {
  168. int res = -1;
  169. if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) {
  170. if (fInitialize((jack_client_t*)this, fObjectData) == 0) {
  171. res = 0;
  172. } else {
  173. JackInternalClient::Close();
  174. fFinish = NULL;
  175. }
  176. }
  177. return res;
  178. }
  179. int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
  180. {
  181. int res = -1;
  182. if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) {
  183. if (fInitialize((jack_client_t*)this, fParameters) == 0) {
  184. res = 0;
  185. } else {
  186. JackInternalClient::Close();
  187. fFinish = NULL;
  188. }
  189. }
  190. return res;
  191. }
  192. } // end of namespace