Jack2 1.9.6
|
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 EXPORT JackGraphManager* GetGraphManager() 00042 { 00043 return JackServerGlobals::fInstance->GetGraphManager(); 00044 } 00045 00046 EXPORT JackEngineControl* GetEngineControl() 00047 { 00048 return JackServerGlobals::fInstance->GetEngineControl(); 00049 } 00050 00051 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, 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, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); 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 goto error; 00082 } 00083 00084 strcpy(fClientControl.fName, name_res); 00085 00086 // Require new client 00087 fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result); 00088 if (result < 0) { 00089 jack_error("Cannot open client name = %s", name_res); 00090 goto error; 00091 } 00092 00093 SetupDriverSync(false); 00094 JackGlobals::fClientTable[fClientControl.fRefNum] = this; 00095 JackGlobals::fServerRunning = true; 00096 jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum); 00097 return 0; 00098 00099 error: 00100 fChannel->Stop(); 00101 fChannel->Close(); 00102 return -1; 00103 } 00104 00105 JackGraphManager* JackInternalClient::GetGraphManager() const 00106 { 00107 assert(fGraphManager); 00108 return fGraphManager; 00109 } 00110 00111 JackEngineControl* JackInternalClient::GetEngineControl() const 00112 { 00113 assert(fEngineControl); 00114 return fEngineControl; 00115 } 00116 00117 JackClientControl* JackInternalClient::GetClientControl() const 00118 { 00119 return const_cast<JackClientControl*>(&fClientControl); 00120 } 00121 00122 int JackLoadableInternalClient::Init(const char* so_name) 00123 { 00124 char path_to_so[JACK_PATH_MAX + 1]; 00125 BuildClientPath(path_to_so, sizeof(path_to_so), so_name); 00126 00127 fHandle = LoadJackModule(path_to_so); 00128 jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so); 00129 00130 if (fHandle == NULL) { 00131 PrintLoadError(so_name); 00132 return -1; 00133 } 00134 00135 fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish"); 00136 if (fFinish == NULL) { 00137 UnloadJackModule(fHandle); 00138 jack_error("symbol jack_finish cannot be found in %s", so_name); 00139 return -1; 00140 } 00141 00142 fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor"); 00143 if (fDescriptor == NULL) { 00144 jack_info("No jack_get_descriptor entry-point for %s", so_name); 00145 } 00146 return 0; 00147 } 00148 00149 int JackLoadableInternalClient1::Init(const char* so_name) 00150 { 00151 if (JackLoadableInternalClient::Init(so_name) < 0) { 00152 return -1; 00153 } 00154 00155 fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize"); 00156 if (fInitialize == NULL) { 00157 UnloadJackModule(fHandle); 00158 jack_error("symbol jack_initialize cannot be found in %s", so_name); 00159 return -1; 00160 } 00161 00162 return 0; 00163 } 00164 00165 int JackLoadableInternalClient2::Init(const char* so_name) 00166 { 00167 if (JackLoadableInternalClient::Init(so_name) < 0) { 00168 return -1; 00169 } 00170 00171 fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize"); 00172 if (fInitialize == NULL) { 00173 UnloadJackModule(fHandle); 00174 jack_error("symbol jack_internal_initialize cannot be found in %s", so_name); 00175 return -1; 00176 } 00177 00178 return 0; 00179 } 00180 00181 JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) 00182 : JackLoadableInternalClient(server, table) 00183 { 00184 strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); 00185 } 00186 00187 JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) 00188 : JackLoadableInternalClient(server, table) 00189 { 00190 fParameters = parameters; 00191 } 00192 00193 JackLoadableInternalClient::~JackLoadableInternalClient() 00194 { 00195 if (fFinish != NULL) 00196 fFinish(fProcessArg); 00197 if (fHandle != NULL) 00198 UnloadJackModule(fHandle); 00199 } 00200 00201 int JackLoadableInternalClient1::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) 00202 { 00203 int res = -1; 00204 00205 if (JackInternalClient::Open(server_name, name, options, status) == 0) { 00206 if (fInitialize((jack_client_t*)this, fObjectData) == 0) { 00207 res = 0; 00208 } else { 00209 JackInternalClient::Close(); 00210 fFinish = NULL; 00211 } 00212 } 00213 00214 return res; 00215 } 00216 00217 int JackLoadableInternalClient2::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) 00218 { 00219 int res = -1; 00220 00221 if (JackInternalClient::Open(server_name, name, options, status) == 0) { 00222 if (fInitialize((jack_client_t*)this, fParameters) == 0) { 00223 res = 0; 00224 } else { 00225 JackInternalClient::Close(); 00226 fFinish = NULL; 00227 } 00228 } 00229 00230 return res; 00231 } 00232 00233 } // end of namespace 00234