Jack2
1.9.8
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2004-2008 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 */ 00020 00021 #include "JackSystemDeps.h" 00022 #include "JackServerGlobals.h" 00023 #include "JackGraphManager.h" 00024 #include "JackConstants.h" 00025 #include "JackInternalClient.h" 00026 #include "JackLockedEngine.h" 00027 #include "JackServer.h" 00028 #include "JackEngineControl.h" 00029 #include "JackClientControl.h" 00030 #include "JackInternalClientChannel.h" 00031 #include "JackTools.h" 00032 #include <assert.h> 00033 00034 namespace Jack 00035 { 00036 00037 JackGraphManager* JackInternalClient::fGraphManager = NULL; 00038 JackEngineControl* JackInternalClient::fEngineControl = NULL; 00039 00040 // Used for external C API (JackAPI.cpp) 00041 SERVER_EXPORT JackGraphManager* GetGraphManager() 00042 { 00043 return JackServerGlobals::fInstance->GetGraphManager(); 00044 } 00045 00046 SERVER_EXPORT JackEngineControl* GetEngineControl() 00047 { 00048 return JackServerGlobals::fInstance->GetEngineControl(); 00049 } 00050 00051 SERVER_EXPORT JackSynchro* GetSynchroTable() 00052 { 00053 return JackServerGlobals::fInstance->GetSynchroTable(); 00054 } 00055 00056 JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table) 00057 { 00058 fChannel = new JackInternalClientChannel(server); 00059 } 00060 00061 JackInternalClient::~JackInternalClient() 00062 { 00063 delete fChannel; 00064 } 00065 00066 int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) 00067 { 00068 int result; 00069 char name_res[JACK_CLIENT_NAME_SIZE + 1]; 00070 jack_log("JackInternalClient::Open name = %s", name); 00071 00072 strncpy(fServerName, server_name, sizeof(fServerName)); 00073 00074 fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, false); 00075 if (result < 0) { 00076 int status1 = *status; 00077 if (status1 & JackVersionError) { 00078 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); 00079 } else { 00080 jack_error("Client name = %s conflits with another running client", name); 00081 } 00082 goto error; 00083 } 00084 00085 strcpy(fClientControl.fName, name_res); 00086 00087 // Require new client 00088 fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result); 00089 if (result < 0) { 00090 jack_error("Cannot open client name = %s", name_res); 00091 goto error; 00092 } 00093 00094 SetupDriverSync(false); 00095 JackGlobals::fClientTable[fClientControl.fRefNum] = this; 00096 JackGlobals::fServerRunning = true; 00097 jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum); 00098 return 0; 00099 00100 error: 00101 fChannel->Stop(); 00102 fChannel->Close(); 00103 return -1; 00104 } 00105 00106 JackGraphManager* JackInternalClient::GetGraphManager() const 00107 { 00108 assert(fGraphManager); 00109 return fGraphManager; 00110 } 00111 00112 JackEngineControl* JackInternalClient::GetEngineControl() const 00113 { 00114 assert(fEngineControl); 00115 return fEngineControl; 00116 } 00117 00118 JackClientControl* JackInternalClient::GetClientControl() const 00119 { 00120 return const_cast<JackClientControl*>(&fClientControl); 00121 } 00122 00123 int JackLoadableInternalClient::Init(const char* so_name) 00124 { 00125 char path_to_so[JACK_PATH_MAX + 1]; 00126 BuildClientPath(path_to_so, sizeof(path_to_so), so_name); 00127 00128 fHandle = LoadJackModule(path_to_so); 00129 jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); 00130 00131 if (fHandle == NULL) { 00132 PrintLoadError(so_name); 00133 return -1; 00134 } 00135 00136 fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish"); 00137 if (fFinish == NULL) { 00138 UnloadJackModule(fHandle); 00139 jack_error("symbol jack_finish cannot be found in %s", so_name); 00140 return -1; 00141 } 00142 00143 fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor"); 00144 if (fDescriptor == NULL) { 00145 jack_info("No jack_get_descriptor entry-point for %s", so_name); 00146 } 00147 return 0; 00148 } 00149 00150 int JackLoadableInternalClient1::Init(const char* so_name) 00151 { 00152 if (JackLoadableInternalClient::Init(so_name) < 0) { 00153 return -1; 00154 } 00155 00156 fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); 00157 if (fInitialize == NULL) { 00158 UnloadJackModule(fHandle); 00159 jack_error("symbol jack_initialize cannot be found in %s", so_name); 00160 return -1; 00161 } 00162 00163 return 0; 00164 } 00165 00166 int JackLoadableInternalClient2::Init(const char* so_name) 00167 { 00168 if (JackLoadableInternalClient::Init(so_name) < 0) { 00169 return -1; 00170 } 00171 00172 fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); 00173 if (fInitialize == NULL) { 00174 UnloadJackModule(fHandle); 00175 jack_error("symbol jack_internal_initialize cannot be found in %s", so_name); 00176 return -1; 00177 } 00178 00179 return 0; 00180 } 00181 00182 JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) 00183 : JackLoadableInternalClient(server, table) 00184 { 00185 strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); 00186 } 00187 00188 JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) 00189 : JackLoadableInternalClient(server, table) 00190 { 00191 fParameters = parameters; 00192 } 00193 00194 JackLoadableInternalClient::~JackLoadableInternalClient() 00195 { 00196 if (fFinish != NULL) 00197 fFinish(fProcessArg); 00198 if (fHandle != NULL) 00199 UnloadJackModule(fHandle); 00200 } 00201 00202 int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) 00203 { 00204 int res = -1; 00205 00206 if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { 00207 if (fInitialize((jack_client_t*)this, fObjectData) == 0) { 00208 res = 0; 00209 } else { 00210 JackInternalClient::Close(); 00211 fFinish = NULL; 00212 } 00213 } 00214 00215 return res; 00216 } 00217 00218 int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) 00219 { 00220 int res = -1; 00221 00222 if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) { 00223 if (fInitialize((jack_client_t*)this, fParameters) == 0) { 00224 res = 0; 00225 } else { 00226 JackInternalClient::Close(); 00227 fFinish = NULL; 00228 } 00229 } 00230 00231 return res; 00232 } 00233 00234 } // end of namespace 00235