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