Jack2 1.9.6

JackLibAPI.cpp

00001 /*
00002 Copyright (C) 2001-2003 Paul Davis
00003 Copyright (C) 2004-2008 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU Lesser General Public License as published by
00007 the Free Software Foundation; either version 2.1 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public License
00016 along with this program; if not, write to the Free Software 
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 
00019 */
00020 
00021 #include "JackDebugClient.h"
00022 #include "JackLibClient.h"
00023 #include "JackChannel.h"
00024 #include "JackLibGlobals.h"
00025 #include "JackGlobals.h"
00026 #include "JackCompilerDeps.h"
00027 #include "JackTools.h"
00028 #include "JackSystemDeps.h"
00029 #include "JackServerLaunch.h"
00030 #include <assert.h>
00031 
00032 using namespace Jack;
00033 
00034 #ifdef __cplusplus
00035 extern "C"
00036 {
00037 #endif
00038 
00039     jack_client_t * jack_client_new_aux (const char *client_name,
00040             jack_options_t options,
00041             jack_status_t *status);
00042     jack_client_t * jack_client_open_aux (const char *client_name,
00043             jack_options_t options,
00044             jack_status_t *status, va_list ap);
00045     EXPORT jack_client_t * jack_client_open (const char *client_name,
00046             jack_options_t options,
00047             jack_status_t *status, ...);
00048     EXPORT int jack_client_close (jack_client_t *client);
00049     EXPORT int jack_get_client_pid (const char *name);
00050 
00051 #ifdef __cplusplus
00052 }
00053 #endif
00054 
00055 JackLibGlobals* JackLibGlobals::fGlobals = NULL;
00056 int JackLibGlobals::fClientCount = 0;
00057 
00058 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
00059 {
00060     jack_varargs_t va;          /* variable arguments */
00061     jack_status_t my_status;
00062     JackClient* client;
00063  
00064     if (client_name == NULL) {
00065         jack_error("jack_client_new called with a NULL client_name");
00066         return NULL;
00067     }
00068 
00069     jack_log("jack_client_new %s", client_name);
00070    
00071     if (status == NULL)                 /* no status from caller? */
00072         status = &my_status;    /* use local status word */
00073     *status = (jack_status_t)0;
00074 
00075     /* validate parameters */
00076     if ((options & ~JackOpenOptions)) {
00077         int my_status1 = *status | (JackFailure | JackInvalidOption);
00078         *status = (jack_status_t)my_status1;
00079         return NULL;
00080     }
00081 
00082     /* parse variable arguments */
00083     jack_varargs_init(&va);
00084         
00085     JackLibGlobals::Init(); // jack library initialisation
00086 
00087     if (try_start_server(&va, options, status)) {
00088         jack_error("jack server is not running or cannot be started");
00089         JackLibGlobals::Destroy(); // jack library destruction
00090         return 0;
00091     }
00092 
00093     if (JACK_DEBUG) {
00094         client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
00095     } else {
00096         client = new JackLibClient(GetSynchroTable());
00097     }
00098 
00099     int res = client->Open(va.server_name, client_name, options, status);
00100     if (res < 0) {
00101         delete client;
00102         JackLibGlobals::Destroy(); // jack library destruction
00103         int my_status1 = (JackFailure | JackServerError);
00104         *status = (jack_status_t)my_status1;
00105         return NULL;
00106     } else {
00107         return (jack_client_t*)client;
00108     }
00109 }
00110 
00111 jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
00112 {
00113     jack_varargs_t va;          /* variable arguments */
00114     jack_status_t my_status;
00115     JackClient* client;
00116  
00117     if (client_name == NULL) {
00118         jack_error("jack_client_open called with a NULL client_name");
00119         return NULL;
00120     }
00121 
00122     jack_log("jack_client_open %s", client_name);
00123    
00124     if (status == NULL)                 /* no status from caller? */
00125         status = &my_status;    /* use local status word */
00126     *status = (jack_status_t)0;
00127 
00128     /* validate parameters */
00129     if ((options & ~JackOpenOptions)) {
00130         int my_status1 = *status | (JackFailure | JackInvalidOption);
00131         *status = (jack_status_t)my_status1;
00132         return NULL;
00133     }
00134 
00135     /* parse variable arguments */
00136     jack_varargs_parse(options, ap, &va);
00137         
00138     JackLibGlobals::Init(); // jack library initialisation
00139 
00140     if (try_start_server(&va, options, status)) {
00141         jack_error("jack server is not running or cannot be started");
00142         JackLibGlobals::Destroy(); // jack library destruction
00143         return 0;
00144     }
00145 
00146     if (JACK_DEBUG) {
00147         client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
00148     } else {
00149         client = new JackLibClient(GetSynchroTable());
00150     }
00151 
00152     int res = client->Open(va.server_name, client_name, options, status);
00153     if (res < 0) {
00154         delete client;
00155         JackLibGlobals::Destroy(); // jack library destruction
00156         int my_status1 = (JackFailure | JackServerError);
00157         *status = (jack_status_t)my_status1;
00158         return NULL;
00159     } else {
00160         return (jack_client_t*)client;
00161     }
00162 }
00163 
00164 EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
00165 {
00166 #ifdef __CLIENTDEBUG__
00167         JackGlobals::CheckContext("jack_client_open");
00168 #endif
00169     try {
00170         assert(JackGlobals::fOpenMutex);
00171         JackGlobals::fOpenMutex->Lock();
00172         va_list ap;
00173         va_start(ap, status);
00174         jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
00175         va_end(ap);
00176         JackGlobals::fOpenMutex->Unlock();
00177         return res;
00178     } catch(std::bad_alloc& e) {
00179         jack_error("Memory allocation error...");
00180         return NULL;
00181     } catch (...) {
00182         jack_error("Unknown error...");
00183         return NULL;
00184     }
00185 }
00186 
00187 EXPORT int jack_client_close(jack_client_t* ext_client)
00188 {
00189 #ifdef __CLIENTDEBUG__
00190     JackGlobals::CheckContext("jack_client_close");
00191 #endif
00192     assert(JackGlobals::fOpenMutex);
00193     JackGlobals::fOpenMutex->Lock();
00194     int res = -1;
00195     jack_log("jack_client_close");
00196     JackClient* client = (JackClient*)ext_client;
00197     if (client == NULL) {
00198         jack_error("jack_client_close called with a NULL client");
00199     } else {
00200         res = client->Close();
00201         delete client;
00202         JackLibGlobals::Destroy(); // jack library destruction
00203         jack_log("jack_client_close res = %d", res);
00204     }
00205     JackGlobals::fOpenMutex->Unlock();
00206     return res;
00207 }
00208 
00209 EXPORT int jack_get_client_pid(const char *name)
00210 {
00211     jack_error("jack_get_client_pid : not implemented on library side");
00212     return 0;
00213 }
00214