Jack2  1.9.8
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 
00043     LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
00044             jack_options_t options,
00045             jack_status_t *status, ...);
00046     LIB_EXPORT int jack_client_close (jack_client_t *client);
00047     LIB_EXPORT int jack_get_client_pid (const char *name);
00048 
00049 
00050 #ifdef __cplusplus
00051 }
00052 #endif
00053 
00054 static jack_client_t * jack_client_open_aux (const char *client_name,
00055             jack_options_t options,
00056             jack_status_t *status, va_list ap);
00057 
00058 JackLibGlobals* JackLibGlobals::fGlobals = NULL;
00059 int JackLibGlobals::fClientCount = 0;
00060 
00061 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
00062 {
00063     jack_varargs_t va;          /* variable arguments */
00064     jack_status_t my_status;
00065     JackClient* client;
00066 
00067     if (client_name == NULL) {
00068         jack_error("jack_client_new called with a NULL client_name");
00069         return NULL;
00070     }
00071 
00072     jack_log("jack_client_new %s", client_name);
00073 
00074     if (status == NULL)         /* no status from caller? */
00075         status = &my_status;    /* use local status word */
00076     *status = (jack_status_t)0;
00077 
00078     /* validate parameters */
00079     if ((options & ~JackOpenOptions)) {
00080         int my_status1 = *status | (JackFailure | JackInvalidOption);
00081         *status = (jack_status_t)my_status1;
00082         return NULL;
00083     }
00084 
00085     /* parse variable arguments */
00086     jack_varargs_init(&va);
00087 
00088     JackLibGlobals::Init(); // jack library initialisation
00089 
00090     if (try_start_server(&va, options, status)) {
00091         jack_error("jack server is not running or cannot be started");
00092         JackLibGlobals::Destroy(); // jack library destruction
00093         return 0;
00094     }
00095 
00096     if (JACK_DEBUG) {
00097         client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
00098     } else {
00099         client = new JackLibClient(GetSynchroTable());
00100     }
00101 
00102     int res = client->Open(va.server_name, client_name, va.session_id, options, status);
00103     if (res < 0) {
00104         delete client;
00105         JackLibGlobals::Destroy(); // jack library destruction
00106         int my_status1 = (JackFailure | JackServerError);
00107         *status = (jack_status_t)my_status1;
00108         return NULL;
00109     } else {
00110         return (jack_client_t*)client;
00111     }
00112 }
00113 
00114 static jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
00115 {
00116     jack_varargs_t va;          /* variable arguments */
00117     jack_status_t my_status;
00118     JackClient* client;
00119 
00120     if (client_name == NULL) {
00121         jack_error("jack_client_open called with a NULL client_name");
00122         return NULL;
00123     }
00124 
00125     jack_log("jack_client_open %s", client_name);
00126 
00127     if (status == NULL)                 /* no status from caller? */
00128         status = &my_status;    /* use local status word */
00129     *status = (jack_status_t)0;
00130 
00131     /* validate parameters */
00132     if ((options & ~JackOpenOptions)) {
00133         int my_status1 = *status | (JackFailure | JackInvalidOption);
00134         *status = (jack_status_t)my_status1;
00135         return NULL;
00136     }
00137 
00138     /* parse variable arguments */
00139     jack_varargs_parse(options, ap, &va);
00140 
00141     JackLibGlobals::Init(); // jack library initialisation
00142 
00143     if (try_start_server(&va, options, status)) {
00144         jack_error("jack server is not running or cannot be started");
00145         JackLibGlobals::Destroy(); // jack library destruction
00146         return 0;
00147     }
00148 
00149     if (JACK_DEBUG) {
00150         client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
00151     } else {
00152         client = new JackLibClient(GetSynchroTable());
00153     }
00154 
00155     int res = client->Open(va.server_name, client_name, va.session_id, options, status);
00156     if (res < 0) {
00157         delete client;
00158         JackLibGlobals::Destroy(); // jack library destruction
00159         int my_status1 = (JackFailure | JackServerError);
00160         *status = (jack_status_t)my_status1;
00161         return NULL;
00162     } else {
00163         return (jack_client_t*)client;
00164     }
00165 }
00166 
00167 LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
00168 {
00169 #ifdef __CLIENTDEBUG__
00170         JackGlobals::CheckContext("jack_client_open");
00171 #endif
00172     try {
00173         assert(JackGlobals::fOpenMutex);
00174         JackGlobals::fOpenMutex->Lock();
00175         va_list ap;
00176         va_start(ap, status);
00177         jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
00178         va_end(ap);
00179         JackGlobals::fOpenMutex->Unlock();
00180         return res;
00181     } catch(std::bad_alloc& e) {
00182         jack_error("Memory allocation error...");
00183         return NULL;
00184     } catch (...) {
00185         jack_error("Unknown error...");
00186         return NULL;
00187     }
00188 }
00189 
00190 LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
00191 {
00192 #ifdef __CLIENTDEBUG__
00193     JackGlobals::CheckContext("jack_client_close");
00194 #endif
00195     assert(JackGlobals::fOpenMutex);
00196     JackGlobals::fOpenMutex->Lock();
00197     int res = -1;
00198     jack_log("jack_client_close");
00199     JackClient* client = (JackClient*)ext_client;
00200     if (client == NULL) {
00201         jack_error("jack_client_close called with a NULL client");
00202     } else {
00203         res = client->Close();
00204         delete client;
00205         JackLibGlobals::Destroy(); // jack library destruction
00206         jack_log("jack_client_close res = %d", res);
00207     }
00208     JackGlobals::fOpenMutex->Unlock();
00209     return res;
00210 }
00211 
00212 LIB_EXPORT int jack_get_client_pid(const char *name)
00213 {
00214     jack_error("jack_get_client_pid : not implemented on library side");
00215     return 0;
00216 }
00217