Merge branch 'master' into newer-midi-with-winmme-driver
[jack2.git] / common / JackServerAPI.cpp
blob49cc4a581bfea60db2673775d5e8a256748ace3c
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "JackSystemDeps.h"
22 #include "JackGraphManager.h"
23 #include "JackInternalClient.h"
24 #include "JackServer.h"
25 #include "JackDebugClient.h"
26 #include "JackServerGlobals.h"
27 #include "JackTools.h"
28 #include "JackCompilerDeps.h"
29 #include "JackLockedEngine.h"
31 #ifdef __cplusplus
32 extern "C"
34 #endif
36 jack_client_t * jack_client_new_aux (const char *client_name,
37 jack_options_t options,
38 jack_status_t *status);
39 jack_client_t * jack_client_open_aux (const char *client_name,
40 jack_options_t options,
41 jack_status_t *status, va_list ap);
42 EXPORT jack_client_t * jack_client_open (const char *client_name,
43 jack_options_t options,
44 jack_status_t *status, ...);
45 EXPORT int jack_client_close (jack_client_t *client);
46 EXPORT int jack_get_client_pid (const char *name);
48 #ifdef __cplusplus
50 #endif
52 using namespace Jack;
54 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
56 jack_varargs_t va; /* variable arguments */
57 jack_status_t my_status;
58 JackClient* client;
60 if (client_name == NULL) {
61 jack_error("jack_client_new called with a NULL client_name");
62 return NULL;
65 jack_log("jack_client_new %s", client_name);
67 if (status == NULL) /* no status from caller? */
68 status = &my_status; /* use local status word */
69 *status = (jack_status_t)0;
71 /* validate parameters */
72 if ((options & ~JackOpenOptions)) {
73 int my_status1 = *status | (JackFailure | JackInvalidOption);
74 *status = (jack_status_t)my_status1;
75 return NULL;
78 /* parse variable arguments */
79 jack_varargs_init(&va);
81 if (!JackServerGlobals::Init()) { // jack server initialisation
82 int my_status1 = (JackFailure | JackServerError);
83 *status = (jack_status_t)my_status1;
84 return NULL;
87 if (JACK_DEBUG) {
88 client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
89 } else {
90 client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
93 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
94 if (res < 0) {
95 delete client;
96 JackServerGlobals::Destroy(); // jack server destruction
97 int my_status1 = (JackFailure | JackServerError);
98 *status = (jack_status_t)my_status1;
99 return NULL;
100 } else {
101 return (jack_client_t*)client;
105 jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
107 jack_varargs_t va; /* variable arguments */
108 jack_status_t my_status;
109 JackClient* client;
111 if (client_name == NULL) {
112 jack_error("jack_client_open called with a NULL client_name");
113 return NULL;
116 jack_log("jack_client_open %s", client_name);
118 if (status == NULL) /* no status from caller? */
119 status = &my_status; /* use local status word */
120 *status = (jack_status_t)0;
122 /* validate parameters */
123 if ((options & ~JackOpenOptions)) {
124 int my_status1 = *status | (JackFailure | JackInvalidOption);
125 *status = (jack_status_t)my_status1;
126 return NULL;
129 /* parse variable arguments */
130 jack_varargs_parse(options, ap, &va);
132 if (!JackServerGlobals::Init()) { // jack server initialisation
133 int my_status1 = (JackFailure | JackServerError);
134 *status = (jack_status_t)my_status1;
135 return NULL;
138 if (JACK_DEBUG) {
139 client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
140 } else {
141 client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
144 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
145 if (res < 0) {
146 delete client;
147 JackServerGlobals::Destroy(); // jack server destruction
148 int my_status1 = (JackFailure | JackServerError);
149 *status = (jack_status_t)my_status1;
150 return NULL;
151 } else {
152 return (jack_client_t*)client;
156 EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
158 #ifdef __CLIENTDEBUG__
159 JackGlobals::CheckContext("jack_client_open");
160 #endif
161 try {
162 assert(JackGlobals::fOpenMutex);
163 JackGlobals::fOpenMutex->Lock();
164 va_list ap;
165 va_start(ap, status);
166 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
167 va_end(ap);
168 JackGlobals::fOpenMutex->Unlock();
169 return res;
170 } catch(std::bad_alloc& e) {
171 jack_error("Memory allocation error...");
172 return NULL;
173 } catch (...) {
174 jack_error("Unknown error...");
175 return NULL;
179 EXPORT int jack_client_close(jack_client_t* ext_client)
181 #ifdef __CLIENTDEBUG__
182 JackGlobals::CheckContext("jack_client_close");
183 #endif
184 assert(JackGlobals::fOpenMutex);
185 JackGlobals::fOpenMutex->Lock();
186 int res = -1;
187 jack_log("jack_client_close");
188 JackClient* client = (JackClient*)ext_client;
189 if (client == NULL) {
190 jack_error("jack_client_close called with a NULL client");
191 } else {
192 res = client->Close();
193 delete client;
194 JackServerGlobals::Destroy(); // jack server destruction
195 jack_log("jack_client_close res = %d", res);
197 JackGlobals::fOpenMutex->Unlock();
198 return res;
201 EXPORT int jack_get_client_pid(const char *name)
203 return (JackServerGlobals::fInstance != NULL)
204 ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)
205 : 0;