00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackWinNamedPipeClientChannel.h"
00022 #include "JackRequest.h"
00023 #include "JackClient.h"
00024 #include "JackGlobals.h"
00025 #include "JackError.h"
00026
00027 namespace Jack
00028 {
00029
00030 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel():fThread(this)
00031 {
00032 fClient = NULL;
00033 }
00034
00035 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel()
00036 {}
00037
00038 int JackWinNamedPipeClientChannel::ServerCheck(const char* server_name)
00039 {
00040 jack_log("JackWinNamedPipeClientChannel::ServerCheck = %s", server_name);
00041
00042
00043 if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) {
00044 jack_error("Cannot connect to server pipe");
00045 return -1;
00046 } else {
00047 return 0;
00048 }
00049 }
00050
00051 int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
00052 {
00053 int result = 0;
00054 jack_log("JackWinNamedPipeClientChannel::Open name = %s", name);
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) {
00065 jack_error("Cannot connect to server pipe");
00066 goto error;
00067 }
00068
00069
00070 ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00071 if (result < 0) {
00072 jack_error("Client name = %s conflits with another running client", name);
00073 goto error;
00074 }
00075
00076 if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
00077 jack_error("Cannot bind pipe");
00078 goto error;
00079 }
00080
00081 fClient = obj;
00082 return 0;
00083
00084 error:
00085 fRequestPipe.Close();
00086 fNotificationListenPipe.Close();
00087 return -1;
00088 }
00089
00090 void JackWinNamedPipeClientChannel::Close()
00091 {
00092 fRequestPipe.Close();
00093 fNotificationListenPipe.Close();
00094
00095 fThread.Stop();
00096 }
00097
00098 int JackWinNamedPipeClientChannel::Start()
00099 {
00100 jack_log("JackWinNamedPipeClientChannel::Start");
00101
00102
00103
00104 if (fThread.StartSync() != 0) {
00105 jack_error("Cannot start Jack client listener");
00106 return -1;
00107 } else {
00108 return 0;
00109 }
00110 }
00111
00112 void JackWinNamedPipeClientChannel::Stop()
00113 {
00114 jack_log("JackWinNamedPipeClientChannel::Stop");
00115 fThread.Kill();
00116 }
00117
00118 void JackWinNamedPipeClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result)
00119 {
00120 if (req->Write(&fRequestPipe) < 0) {
00121 jack_error("Could not write request type = %ld", req->fType);
00122 *result = -1;
00123 return ;
00124 }
00125
00126 if (res->Read(&fRequestPipe) < 0) {
00127 jack_error("Could not read result type = %ld", req->fType);
00128 *result = -1;
00129 return ;
00130 }
00131
00132 *result = res->fResult;
00133 }
00134
00135 void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result)
00136 {
00137 if (req->Write(&fRequestPipe) < 0) {
00138 jack_error("Could not write request type = %ld", req->fType);
00139 *result = -1;
00140 } else {
00141 *result = 0;
00142 }
00143 }
00144
00145 void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
00146 {
00147 JackClientCheckRequest req(name, protocol, options, uuid);
00148 JackClientCheckResult res;
00149 ServerSyncCall(&req, &res, result);
00150 *status = res.fStatus;
00151 strcpy(name_res, res.fName);
00152 }
00153
00154 void JackWinNamedPipeClientChannel::ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00155 {
00156 JackClientOpenRequest req(name, pid, uuid);
00157 JackClientOpenResult res;
00158 ServerSyncCall(&req, &res, result);
00159 *shared_engine = res.fSharedEngine;
00160 *shared_client = res.fSharedClient;
00161 *shared_graph = res.fSharedGraph;
00162 }
00163
00164 void JackWinNamedPipeClientChannel::ClientClose(int refnum, int* result)
00165 {
00166 JackClientCloseRequest req(refnum);
00167 JackResult res;
00168 ServerSyncCall(&req, &res, result);
00169 }
00170
00171 void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int is_real_time, int* result)
00172 {
00173 JackActivateRequest req(refnum, is_real_time);
00174 JackResult res;
00175 ServerSyncCall(&req, &res, result);
00176 }
00177
00178 void JackWinNamedPipeClientChannel::ClientDeactivate(int refnum, int* result)
00179 {
00180 JackDeactivateRequest req(refnum);
00181 JackResult res;
00182 ServerSyncCall(&req, &res, result);
00183 }
00184
00185 void JackWinNamedPipeClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
00186 {
00187 JackPortRegisterRequest req(refnum, name, type, flags, buffer_size);
00188 JackPortRegisterResult res;
00189 ServerSyncCall(&req, &res, result);
00190 *port_index = res.fPortIndex;
00191 }
00192
00193 void JackWinNamedPipeClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
00194 {
00195 JackPortUnRegisterRequest req(refnum, port_index);
00196 JackResult res;
00197 ServerSyncCall(&req, &res, result);
00198 }
00199
00200 void JackWinNamedPipeClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
00201 {
00202 JackPortConnectNameRequest req(refnum, src, dst);
00203 JackResult res;
00204 ServerSyncCall(&req, &res, result);
00205 }
00206
00207 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
00208 {
00209 JackPortDisconnectNameRequest req(refnum, src, dst);
00210 JackResult res;
00211 ServerSyncCall(&req, &res, result);
00212 }
00213
00214 void JackWinNamedPipeClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00215 {
00216 JackPortConnectRequest req(refnum, src, dst);
00217 JackResult res;
00218 ServerSyncCall(&req, &res, result);
00219 }
00220
00221 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00222 {
00223 JackPortDisconnectRequest req(refnum, src, dst);
00224 JackResult res;
00225 ServerSyncCall(&req, &res, result);
00226 }
00227
00228 void JackWinNamedPipeClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result)
00229 {
00230 JackPortRenameRequest req(refnum, port, name);
00231 JackResult res;
00232 ServerSyncCall(&req, &res, result);
00233 }
00234
00235 void JackWinNamedPipeClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
00236 {
00237 JackSetBufferSizeRequest req(buffer_size);
00238 JackResult res;
00239 ServerSyncCall(&req, &res, result);
00240 }
00241
00242 void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result)
00243 {
00244 JackSetFreeWheelRequest req(onoff);
00245 JackResult res;
00246 ServerSyncCall(&req, &res, result);
00247 }
00248
00249 void JackWinNamedPipeClientChannel::ComputeTotalLatencies(int* result)
00250 {
00251 JackComputeTotalLatenciesRequest req;
00252 JackResult res;
00253 ServerSyncCall(&req, &res, result);
00254 }
00255
00256 void JackWinNamedPipeClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result)
00257 {
00258 JackSessionNotifyRequest req(refnum, path, type, target);
00259 JackSessionNotifyResult res;
00260 int intresult;
00261 ServerSyncCall(&req, &res, &intresult);
00262
00263 jack_session_command_t* session_command = (jack_session_command_t *)malloc(sizeof(jack_session_command_t) * (res.fCommandList.size() + 1));
00264 int i = 0;
00265
00266 for (std::list<JackSessionCommand>::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) {
00267 session_command[i].uuid = strdup( ci->fUUID );
00268 session_command[i].client_name = strdup( ci->fClientName );
00269 session_command[i].command = strdup( ci->fCommand );
00270 session_command[i].flags = ci->fFlags;
00271 i += 1;
00272 }
00273
00274 session_command[i].uuid = NULL;
00275 session_command[i].client_name = NULL;
00276 session_command[i].command = NULL;
00277 session_command[i].flags = (jack_session_flags_t)0;
00278
00279 *result = session_command;
00280 }
00281
00282 void JackWinNamedPipeClientChannel::SessionReply(int refnum, int* result)
00283 {
00284 JackSessionReplyRequest req(refnum);
00285 JackResult res;
00286 ServerSyncCall(&req, &res, result);
00287 }
00288
00289 void JackWinNamedPipeClientChannel::GetUUIDForClientName(int refnum, const char* client_name, char* uuid_res, int* result)
00290 {
00291 JackGetUUIDRequest req(client_name);
00292 JackUUIDResult res;
00293 ServerSyncCall(&req, &res, result);
00294 strncpy(uuid_res, res.fUUID, JACK_UUID_SIZE);
00295 }
00296
00297 void JackWinNamedPipeClientChannel::GetClientNameForUUID(int refnum, const char* uuid, char* name_res, int* result)
00298 {
00299 JackGetClientNameRequest req(uuid);
00300 JackClientNameResult res;
00301 ServerSyncCall(&req, &res, result);
00302 strncpy(name_res, res.fName, JACK_CLIENT_NAME_SIZE);
00303 }
00304
00305 void JackWinNamedPipeClientChannel::ClientHasSessionCallback(const char* client_name, int* result)
00306 {
00307 JackClientHasSessionCallbackRequest req(client_name);
00308 JackResult res;
00309 ServerSyncCall(&req, &res, result);
00310 }
00311
00312 void JackWinNamedPipeClientChannel::ReserveClientName(int refnum, const char* client_name, const char* uuid, int* result)
00313 {
00314 JackReserveNameRequest req(refnum, client_name, uuid);
00315 JackResult res;
00316 ServerSyncCall(&req, &res, result);
00317 }
00318
00319 void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result)
00320 {
00321 JackReleaseTimebaseRequest req(refnum);
00322 JackResult res;
00323 ServerSyncCall(&req, &res, result);
00324 }
00325
00326 void JackWinNamedPipeClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00327 {
00328 JackSetTimebaseCallbackRequest req(refnum, conditional);
00329 JackResult res;
00330 ServerSyncCall(&req, &res, result);
00331 }
00332
00333 void JackWinNamedPipeClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
00334 {
00335 JackGetInternalClientNameRequest req(refnum, int_ref);
00336 JackGetInternalClientNameResult res;
00337 ServerSyncCall(&req, &res, result);
00338 strcpy(name_res, res.fName);
00339 }
00340
00341 void JackWinNamedPipeClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
00342 {
00343 JackInternalClientHandleRequest req(refnum, client_name);
00344 JackInternalClientHandleResult res;
00345 ServerSyncCall(&req, &res, result);
00346 *int_ref = res.fIntRefNum;
00347 *status = res.fStatus;
00348 }
00349
00350 void JackWinNamedPipeClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result)
00351 {
00352 JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options, uuid);
00353 JackInternalClientLoadResult res;
00354 ServerSyncCall(&req, &res, result);
00355 *int_ref = res.fIntRefNum;
00356 *status = res.fStatus;
00357 }
00358
00359 void JackWinNamedPipeClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
00360 {
00361 JackInternalClientUnloadRequest req(refnum, int_ref);
00362 JackInternalClientUnloadResult res;
00363 ServerSyncCall(&req, &res, result);
00364 *status = res.fStatus;
00365 }
00366
00367 bool JackWinNamedPipeClientChannel::Init()
00368 {
00369 jack_log("JackWinNamedPipeClientChannel::Init");
00370
00371 if (!fNotificationListenPipe.Accept()) {
00372 jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");
00373 return false;
00374 } else {
00375 return true;
00376 }
00377 }
00378
00379 bool JackWinNamedPipeClientChannel::Execute()
00380 {
00381 JackClientNotification event;
00382 JackResult res;
00383
00384 if (event.Read(&fNotificationListenPipe) < 0) {
00385 jack_error("JackWinNamedPipeClientChannel read fail");
00386 goto error;
00387 }
00388
00389 res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
00390
00391 if (event.fSync) {
00392 if (res.Write(&fNotificationListenPipe) < 0) {
00393 jack_error("JackWinNamedPipeClientChannel write fail");
00394 goto error;
00395 }
00396 }
00397 return true;
00398
00399 error:
00400
00401 fNotificationListenPipe.Close();
00402 fRequestPipe.Close();
00403 fClient->ShutDown();
00404 return false;
00405 }
00406
00407 }
00408
00409