JackWinNamedPipeClientChannel.cpp

00001 /*
00002 Copyright (C) 2004-2006 Grame  
00003   
00004   This program is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU Lesser General Public License as published by
00006   the Free Software Foundation; either version 2.1 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU Lesser General Public License for more details.
00013   
00014   You should have received a copy of the GNU Lesser General Public License
00015   along with this program; if not, write to the Free Software 
00016   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 
00018 */
00019 
00020 #include "JackWinNamedPipeClientChannel.h"
00021 #include "JackRequest.h"
00022 #include "JackClient.h"
00023 #include "JackGlobals.h"
00024 
00025 namespace Jack
00026 {
00027 
00028 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel()
00029 {
00030     fThread = JackGlobals::MakeThread(this);
00031     fClient = NULL;
00032 }
00033 
00034 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel()
00035 {
00036     delete fThread;
00037 }
00038 
00039 int JackWinNamedPipeClientChannel::Open(const char* name, JackClient* obj)
00040 {
00041     JackLog("JackWinNamedPipeClientChannel::Open name = %s\n", name);
00042 
00043     if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
00044         jack_error("Cannot bind pipe");
00045         goto error;
00046     }
00047 
00048     if (fRequestPipe.Connect(jack_server_dir, 0) < 0) {
00049         jack_error("Cannot connect to server pipe");
00050         goto error;
00051     }
00052 
00053     fClient = obj;
00054     return 0;
00055 
00056 error:
00057     fRequestPipe.Close();
00058     fNotificationListenPipe.Close();
00059     return -1;
00060 }
00061 
00062 void JackWinNamedPipeClientChannel::Close()
00063 {
00064     fRequestPipe.Close();
00065     fNotificationListenPipe.Close();
00066         // Here the thread will correctly stop when the pipe are closed
00067         fThread->Stop();
00068 }
00069 
00070 int JackWinNamedPipeClientChannel::Start()
00071 {
00072     JackLog("JackWinNamedPipeClientChannel::Start\n");
00073         
00074     if (fThread->Start() != 0) {
00075         jack_error("Cannot start Jack client listener");
00076         return -1;
00077     } else {
00078         return 0;
00079     }   
00080 }
00081 
00082 void JackWinNamedPipeClientChannel::Stop()
00083 {
00084     JackLog("JackWinNamedPipeClientChannel::Stop\n");
00085     fThread->Kill();  // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue
00086 }
00087 
00088 void JackWinNamedPipeClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result)
00089 {
00090     if (req->Write(&fRequestPipe) < 0) {
00091         jack_error("Could not write request type = %ld", req->fType);
00092         *result = -1;
00093         return ;
00094     }
00095 
00096     if (res->Read(&fRequestPipe) < 0) {
00097         jack_error("Could not read result type = %ld", req->fType);
00098         *result = -1;
00099         return ;
00100     }
00101 
00102     *result = res->fResult;
00103 }
00104 
00105 void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result)
00106 {
00107     if (req->Write(&fRequestPipe) < 0) {
00108         jack_error("Could not write request type = %ld", req->fType);
00109         *result = -1;
00110     } else {
00111         *result = 0;
00112     }
00113 }
00114 
00115 void JackWinNamedPipeClientChannel::ClientNew(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00116 {
00117     JackClientNewRequest req(name);
00118     JackClientNewResult res;
00119     ServerSyncCall(&req, &res, result);
00120     *shared_engine = res.fSharedEngine;
00121     *shared_client = res.fSharedClient;
00122     *shared_graph = res.fSharedGraph;
00123 }
00124 
00125 void JackWinNamedPipeClientChannel::ClientClose(int refnum, int* result)
00126 {
00127     JackClientCloseRequest req(refnum);
00128     JackResult res;
00129     ServerAsyncCall(&req, &res, result);
00130 }
00131 
00132 void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int* result)
00133 {
00134     JackActivateRequest req(refnum);
00135     JackResult res;
00136     ServerSyncCall(&req, &res, result);
00137 }
00138 
00139 void JackWinNamedPipeClientChannel::ClientDeactivate(int refnum, int* result)
00140 {
00141     JackDeactivateRequest req(refnum);
00142     JackResult res;
00143     ServerSyncCall(&req, &res, result);
00144 }
00145 
00146 void JackWinNamedPipeClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
00147 {
00148     JackPortRegisterRequest req(refnum, name, "audio", flags, buffer_size);
00149     JackPortRegisterResult res;
00150     ServerSyncCall(&req, &res, result);
00151     *port_index = res.fPortIndex;
00152 }
00153 
00154 void JackWinNamedPipeClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
00155 {
00156     JackPortUnRegisterRequest req(refnum, port_index);
00157     JackResult res;
00158     ServerSyncCall(&req, &res, result);
00159 }
00160 
00161 void JackWinNamedPipeClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
00162 {
00163     JackPortConnectNameRequest req(refnum, src, dst);
00164     JackResult res;
00165     ServerSyncCall(&req, &res, result);
00166 }
00167 
00168 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
00169 {
00170     JackPortDisconnectNameRequest req(refnum, src, dst);
00171     JackResult res;
00172     ServerSyncCall(&req, &res, result);
00173 }
00174 
00175 void JackWinNamedPipeClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00176 {
00177     JackPortConnectRequest req(refnum, src, dst);
00178     JackResult res;
00179     ServerSyncCall(&req, &res, result);
00180 }
00181 
00182 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
00183 {
00184     JackPortDisconnectRequest req(refnum, src, dst);
00185     JackResult res;
00186     ServerSyncCall(&req, &res, result);
00187 }
00188 
00189 void JackWinNamedPipeClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
00190 {
00191     JackSetBufferSizeRequest req(buffer_size);
00192     JackResult res;
00193     ServerSyncCall(&req, &res, result);
00194 }
00195 
00196 void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result)
00197 {
00198     JackSetFreeWheelRequest req(onoff);
00199     JackResult res;
00200     ServerSyncCall(&req, &res, result);
00201 }
00202 
00203 void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result)
00204 {
00205     JackReleaseTimebaseRequest req(refnum);
00206     JackResult res;
00207     ServerSyncCall(&req, &res, result);
00208 }
00209 
00210 void JackWinNamedPipeClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00211 {
00212     JackSetTimebaseCallbackRequest req(refnum, conditional);
00213     JackResult res;
00214     ServerSyncCall(&req, &res, result);
00215 }
00216 
00217 bool JackWinNamedPipeClientChannel::Init()
00218 {
00219     JackLog("JackWinNamedPipeClientChannel::Init \n");
00220 
00221     if (!fNotificationListenPipe.Accept()) {
00222         jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");
00223         return false;
00224     } else {
00225                 return true;
00226     }
00227 }
00228 
00229 bool JackWinNamedPipeClientChannel::Execute()
00230 {
00231     JackClientNotification event;
00232     JackResult res;
00233 
00234     if (event.Read(&fNotificationListenPipe) < 0) {
00235         fNotificationListenPipe.Close();
00236         jack_error("JackWinNamedPipeClientChannel read fail");
00237         goto error;
00238     }
00239 
00240     res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue);
00241 
00242     if (event.fSync) {
00243         if (res.Write(&fNotificationListenPipe) < 0) {
00244             fNotificationListenPipe.Close();
00245             jack_error("JackWinNamedPipeClientChannel write fail");
00246             goto error;
00247         }
00248     }
00249     return true;
00250 
00251 error:
00252 
00253     //fClient->ShutDown(); needed ??
00254     return false;
00255 }
00256 
00257 } // end of namespace
00258 
00259 

Generated on Wed Jan 10 11:42:47 2007 for Jackdmp by  doxygen 1.4.5