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