Jack2 1.9.6

JackLibClient.cpp

00001 /*
00002 Copyright (C) 2004-2008 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 "JackLibClient.h"
00021 #include "JackTime.h"
00022 #include "JackLibGlobals.h"
00023 #include "JackGlobals.h"
00024 #include "JackPlatformPlug.h"
00025 #include "JackTools.h"
00026 
00027 namespace Jack
00028 {
00029 
00030 // Used for external C API (JackAPI.cpp)
00031 JackGraphManager* GetGraphManager()
00032 {
00033     if (JackLibGlobals::fGlobals) {
00034         return JackLibGlobals::fGlobals->fGraphManager;
00035     } else {
00036         return NULL;
00037     }
00038 }
00039 
00040 JackEngineControl* GetEngineControl()
00041 {
00042     if (JackLibGlobals::fGlobals) {
00043         return JackLibGlobals::fGlobals->fEngineControl;
00044     } else {
00045         return NULL;
00046     }
00047 }
00048 
00049 JackSynchro* GetSynchroTable()
00050 {
00051     return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0);
00052 }
00053 
00054 //-------------------
00055 // Client management
00056 //-------------------
00057 
00058 JackLibClient::JackLibClient(JackSynchro* table): JackClient(table)
00059 {
00060     jack_log("JackLibClient::JackLibClient table = %x", table);
00061     fChannel = new JackClientChannel();
00062 }
00063 
00064 JackLibClient::~JackLibClient()
00065 {
00066     jack_log("JackLibClient::~JackLibClient");
00067     delete fChannel;
00068 }
00069 
00070 int JackLibClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00071 {
00072     int shared_engine, shared_client, shared_graph, result;
00073     jack_log("JackLibClient::Open name = %s", name);
00074 
00075     strncpy(fServerName, server_name, sizeof(fServerName));
00076 
00077     // Open server/client channel
00078     char name_res[JACK_CLIENT_NAME_SIZE + 1];
00079     if (fChannel->Open(server_name, name, name_res, this, options, status) < 0) {
00080         jack_error("Cannot connect to the server");
00081         goto error;
00082     }
00083 
00084     // Start receiving notifications
00085     if (fChannel->Start() < 0) {
00086         jack_error("Cannot start channel");
00087         goto error;
00088     }
00089 
00090     // Require new client
00091     fChannel->ClientOpen(name_res, JackTools::GetPID(), &shared_engine, &shared_client, &shared_graph, &result);
00092     if (result < 0) {
00093         jack_error("Cannot open %s client", name_res);
00094         goto error;
00095     }
00096 
00097     try {
00098         // Map shared memory segments
00099         JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName);
00100         JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
00101         fClientControl.SetShmIndex(shared_client, fServerName);
00102         JackGlobals::fVerbose = GetEngineControl()->fVerbose;
00103     } catch (int n) {
00104         jack_error("Map shared memory segments exception %d", n);
00105         goto error;
00106     } catch (...) {
00107         jack_error("Unknown error...");
00108         goto error;
00109     }
00110 
00111     SetupDriverSync(false);
00112  
00113     // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
00114     if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) {
00115         jack_error("Cannot ConnectSemaphore %s client", name_res);
00116         goto error;
00117     }
00118   
00119     JackGlobals::fClientTable[GetClientControl()->fRefNum] = this;
00120     JackGlobals::fServerRunning = true;
00121     SetClockSource(GetEngineControl()->fClockSource);
00122     jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum);
00123     return 0;
00124 
00125 error:
00126     fChannel->Stop();
00127     fChannel->Close();
00128     return -1;
00129 }
00130 
00131 // Notifications received from the server
00132 // TODO this should be done once for all clients in the process, when a shared notification channel
00133 // will be shared by all clients...
00134 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
00135 {
00136     int res = 0;
00137 
00138     // Done all time
00139     switch (notify) {
00140 
00141         case kAddClient:
00142             jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum);
00143             // the synchro must be usable in I/O mode when several clients live in the same process
00144             res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1;
00145             break;
00146 
00147         case kRemoveClient:
00148             jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum);
00149             if (strcmp(GetClientControl()->fName, name) != 0)
00150                 res = fSynchroTable[refnum].Disconnect() ? 0 : -1;
00151             break;
00152     }
00153 
00154     return res;
00155 }
00156 
00157 JackGraphManager* JackLibClient::GetGraphManager() const
00158 {
00159     assert(JackLibGlobals::fGlobals->fGraphManager);
00160     return JackLibGlobals::fGlobals->fGraphManager;
00161 }
00162 
00163 JackEngineControl* JackLibClient::GetEngineControl() const
00164 {
00165     assert(JackLibGlobals::fGlobals->fEngineControl);
00166     return JackLibGlobals::fGlobals->fEngineControl;
00167 }
00168 
00169 JackClientControl* JackLibClient::GetClientControl() const
00170 {
00171     return fClientControl;
00172 }
00173 
00174 } // end of namespace
00175 
00176 
00177