00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackSystemDeps.h"
00022 #include "JackGraphManager.h"
00023 #include "JackConstants.h"
00024 #include "JackInternalClient.h"
00025 #include "JackLockedEngine.h"
00026 #include "JackServer.h"
00027 #include "JackEngineControl.h"
00028 #include "JackClientControl.h"
00029 #include "JackInternalClientChannel.h"
00030 #include "JackTools.h"
00031 #include <assert.h>
00032
00033 namespace Jack
00034 {
00035
00036 #ifdef WIN32
00037
00038 static void BuildClientPath(char* path_to_so, int path_len, const char* so_name)
00039 {
00040 snprintf(path_to_so, path_len, ADDON_DIR "/%s.dll", so_name);
00041 }
00042
00043 static void PrintLoadError(const char* so_name)
00044 {
00045
00046 LPVOID lpMsgBuf;
00047 LPVOID lpDisplayBuf;
00048 DWORD dw = GetLastError();
00049
00050 FormatMessage(
00051 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00052 FORMAT_MESSAGE_FROM_SYSTEM |
00053 FORMAT_MESSAGE_IGNORE_INSERTS,
00054 NULL,
00055 dw,
00056 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00057 (LPTSTR) &lpMsgBuf,
00058 0, NULL );
00059
00060
00061 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
00062 (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)so_name) + 40) * sizeof(TCHAR));
00063 _snprintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR),
00064 TEXT("error loading %s err = %s"), so_name, lpMsgBuf);
00065
00066 jack_error((LPCTSTR)lpDisplayBuf);
00067
00068 LocalFree(lpMsgBuf);
00069 LocalFree(lpDisplayBuf);
00070 }
00071
00072 #else
00073
00074 static void BuildClientPath(char* path_to_so, int path_len, const char* so_name)
00075 {
00076 const char* driver_dir;
00077 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0)
00078 driver_dir = ADDON_DIR;
00079 snprintf(path_to_so, path_len, "%s/%s.so", driver_dir, so_name);
00080 }
00081
00082 #endif
00083
00084 JackGraphManager* JackInternalClient::fGraphManager = NULL;
00085 JackEngineControl* JackInternalClient::fEngineControl = NULL;
00086
00087
00088 JackGraphManager* GetGraphManager()
00089 {
00090 return JackServer::fInstance->GetGraphManager();
00091 }
00092
00093 JackEngineControl* GetEngineControl()
00094 {
00095 return JackServer::fInstance->GetEngineControl();
00096 }
00097
00098 JackSynchro* GetSynchroTable()
00099 {
00100 return JackServer::fInstance->GetSynchroTable();
00101 }
00102
00103 JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table)
00104 {
00105 fChannel = new JackInternalClientChannel(server);
00106 }
00107
00108 JackInternalClient::~JackInternalClient()
00109 {
00110 delete fChannel;
00111 }
00112
00113 int JackInternalClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00114 {
00115 int result;
00116 char name_res[JACK_CLIENT_NAME_SIZE + 1];
00117 jack_log("JackInternalClient::Open name = %s", name);
00118
00119 snprintf(fServerName, sizeof(fServerName), server_name);
00120
00121 fChannel->ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00122 if (result < 0) {
00123 int status1 = *status;
00124 if (status1 & JackVersionError)
00125 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
00126 else
00127 jack_error("Client name = %s conflits with another running client", name);
00128 goto error;
00129 }
00130
00131 strcpy(fClientControl.fName, name_res);
00132
00133
00134 fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result);
00135 if (result < 0) {
00136 jack_error("Cannot open client name = %s", name_res);
00137 goto error;
00138 }
00139
00140 SetupDriverSync(false);
00141 JackGlobals::fClientTable[fClientControl.fRefNum] = this;
00142 JackGlobals::fServerRunning = true;
00143 jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum);
00144 return 0;
00145
00146 error:
00147 fChannel->Stop();
00148 fChannel->Close();
00149 return -1;
00150 }
00151
00152 JackGraphManager* JackInternalClient::GetGraphManager() const
00153 {
00154 assert(fGraphManager);
00155 return fGraphManager;
00156 }
00157
00158 JackEngineControl* JackInternalClient::GetEngineControl() const
00159 {
00160 assert(fEngineControl);
00161 return fEngineControl;
00162 }
00163
00164 JackClientControl* JackInternalClient::GetClientControl() const
00165 {
00166 return const_cast<JackClientControl*>(&fClientControl);
00167 }
00168
00169 int JackLoadableInternalClient::Init(const char* so_name)
00170 {
00171 char path_to_so[JACK_PATH_MAX + 1];
00172 BuildClientPath(path_to_so, sizeof(path_to_so), so_name);
00173
00174 fHandle = LoadJackModule(path_to_so);
00175 jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so);
00176
00177 if (fHandle == 0) {
00178 PrintLoadError(so_name);
00179 return -1;
00180 }
00181
00182 fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish");
00183 if (!fFinish) {
00184 UnloadJackModule(fHandle);
00185 jack_error("symbol jack_finish cannot be found in %s", so_name);
00186 return -1;
00187 }
00188
00189 fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor");
00190 if (!fDescriptor) {
00191 jack_info("No jack_get_descriptor entry-point for %s", so_name);
00192 }
00193 return 0;
00194 }
00195
00196 int JackLoadableInternalClient1::Init(const char* so_name)
00197 {
00198 if (JackLoadableInternalClient::Init(so_name) < 0) {
00199 return -1;
00200 }
00201
00202 fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize");
00203 if (!fInitialize) {
00204 UnloadJackModule(fHandle);
00205 jack_error("symbol jack_initialize cannot be found in %s", so_name);
00206 return -1;
00207 }
00208
00209 return 0;
00210 }
00211
00212 int JackLoadableInternalClient2::Init(const char* so_name)
00213 {
00214 if (JackLoadableInternalClient::Init(so_name) < 0) {
00215 return -1;
00216 }
00217
00218 fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize");
00219 if (!fInitialize) {
00220 UnloadJackModule(fHandle);
00221 jack_error("symbol jack_internal_initialize cannot be found in %s", so_name);
00222 return -1;
00223 }
00224
00225 return 0;
00226 }
00227
00228 JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* so_name, const char* object_data)
00229 : JackLoadableInternalClient(server, table)
00230 {
00231 snprintf(fObjectData, JACK_LOAD_INIT_LIMIT, object_data);
00232 }
00233
00234 JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const char* so_name, const JSList* parameters)
00235 : JackLoadableInternalClient(server, table)
00236 {
00237 fParameters = parameters;
00238 }
00239
00240 JackLoadableInternalClient::~JackLoadableInternalClient()
00241 {
00242 if (fFinish)
00243 fFinish(fProcessArg);
00244 UnloadJackModule(fHandle);
00245 }
00246
00247 int JackLoadableInternalClient1::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00248 {
00249 int res = -1;
00250
00251 if (JackInternalClient::Open(server_name, name, options, status) == 0) {
00252 if (fInitialize((jack_client_t*)this, fObjectData) == 0) {
00253 res = 0;
00254 } else {
00255 JackInternalClient::Close();
00256 fFinish = NULL;
00257 }
00258 }
00259
00260 return res;
00261 }
00262
00263 int JackLoadableInternalClient2::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00264 {
00265 int res = -1;
00266
00267 if (JackInternalClient::Open(server_name, name, options, status) == 0) {
00268 if (fInitialize((jack_client_t*)this, fParameters) == 0) {
00269 res = 0;
00270 } else {
00271 JackInternalClient::Close();
00272 fFinish = NULL;
00273 }
00274 }
00275
00276 return res;
00277 }
00278
00279 }
00280