Add jack_position_t::tick_double, and flags around it (#770)
[jack2.git] / common / JackLibAPI.cpp
blobe439f4735320384bb0d554e448c01d7c59d5e960
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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackDebugClient.h"
22 #include "JackLibClient.h"
23 #include "JackChannel.h"
24 #include "JackLibGlobals.h"
25 #include "JackGlobals.h"
26 #include "JackCompilerDeps.h"
27 #include "JackTools.h"
28 #include "JackSystemDeps.h"
29 #include "JackServerLaunch.h"
30 #include "JackMetadata.h"
31 #include <assert.h>
33 using namespace Jack;
35 #ifdef __cplusplus
36 extern "C"
38 #endif
40 jack_client_t * jack_client_new_aux (const char *client_name,
41 jack_options_t options,
42 jack_status_t *status);
44 LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
45 jack_options_t options,
46 jack_status_t *status, ...);
47 LIB_EXPORT int jack_client_close (jack_client_t *client);
48 LIB_EXPORT int jack_get_client_pid (const char *name);
50 LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type);
51 LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type);
52 LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_description_itself);
53 LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc);
54 LIB_EXPORT int jack_get_all_properties(jack_description_t** descs);
55 LIB_EXPORT int jack_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key);
56 LIB_EXPORT int jack_remove_properties(jack_client_t* client, jack_uuid_t subject);
57 LIB_EXPORT int jack_remove_all_properties(jack_client_t* client);
58 LIB_EXPORT int jack_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg);
60 #ifdef __cplusplus
62 #endif
64 static jack_client_t * jack_client_open_aux (const char *client_name,
65 jack_options_t options,
66 jack_status_t *status, va_list ap);
68 JackLibGlobals* JackLibGlobals::fGlobals = NULL;
69 int JackLibGlobals::fClientCount = 0;
71 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
73 jack_varargs_t va; /* variable arguments */
74 jack_status_t my_status;
75 JackClient* client;
77 if (client_name == NULL) {
78 jack_error("jack_client_new called with a NULL client_name");
79 return NULL;
82 jack_log("jack_client_new %s", client_name);
84 if (status == NULL) /* no status from caller? */
85 status = &my_status; /* use local status word */
86 *status = (jack_status_t)0;
88 /* validate parameters */
89 if ((options & ~JackOpenOptions)) {
90 int my_status1 = *status | (JackFailure | JackInvalidOption);
91 *status = (jack_status_t)my_status1;
92 return NULL;
95 /* parse variable arguments */
96 jack_varargs_init(&va);
98 JackLibGlobals::Init(); // jack library initialisation
100 if (try_start_server(&va, options, status)) {
101 jack_error("jack server is not running or cannot be started");
102 JackLibGlobals::Destroy(); // jack library destruction
103 return 0;
106 if (JACK_DEBUG) {
107 client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
108 } else {
109 client = new JackLibClient(GetSynchroTable());
112 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
113 if (res < 0) {
114 delete client;
115 JackLibGlobals::Destroy(); // jack library destruction
116 int my_status1 = (JackFailure | JackServerError);
117 *status = (jack_status_t)my_status1;
118 return NULL;
119 } else {
120 return (jack_client_t*)client;
124 static jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
126 jack_varargs_t va; /* variable arguments */
127 jack_status_t my_status;
128 JackClient* client;
130 if (client_name == NULL) {
131 jack_error("jack_client_open called with a NULL client_name");
132 return NULL;
135 jack_log("jack_client_open %s", client_name);
137 if (status == NULL) /* no status from caller? */
138 status = &my_status; /* use local status word */
139 *status = (jack_status_t)0;
141 /* validate parameters */
142 if ((options & ~JackOpenOptions)) {
143 int my_status1 = *status | (JackFailure | JackInvalidOption);
144 *status = (jack_status_t)my_status1;
145 return NULL;
148 /* parse variable arguments */
149 jack_varargs_parse(options, ap, &va);
151 JackLibGlobals::Init(); // jack library initialisation
153 if (try_start_server(&va, options, status)) {
154 jack_error("jack server is not running or cannot be started");
155 JackLibGlobals::Destroy(); // jack library destruction
156 return 0;
159 if (JACK_DEBUG) {
160 client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
161 } else {
162 client = new JackLibClient(GetSynchroTable());
165 int res = client->Open(va.server_name, client_name, va.session_id, options, status);
166 if (res < 0) {
167 delete client;
168 JackLibGlobals::Destroy(); // jack library destruction
169 int my_status1 = (JackFailure | JackServerError);
170 *status = (jack_status_t)my_status1;
171 return NULL;
172 } else {
173 return (jack_client_t*)client;
177 LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
179 JackGlobals::CheckContext("jack_client_open");
181 try {
182 assert(JackGlobals::fOpenMutex);
183 JackGlobals::fOpenMutex->Lock();
184 va_list ap;
185 va_start(ap, status);
186 jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
187 va_end(ap);
188 JackGlobals::fOpenMutex->Unlock();
189 return res;
190 } catch (std::bad_alloc& e) {
191 jack_error("Memory allocation error...");
192 return NULL;
193 } catch (...) {
194 jack_error("Unknown error...");
195 return NULL;
199 LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
201 JackGlobals::CheckContext("jack_client_close");
203 assert(JackGlobals::fOpenMutex);
204 JackGlobals::fOpenMutex->Lock();
205 int res = -1;
206 jack_log("jack_client_close");
207 JackClient* client = (JackClient*)ext_client;
208 if (client == NULL) {
209 jack_error("jack_client_close called with a NULL client");
210 } else {
211 res = client->Close();
212 delete client;
213 JackLibGlobals::Destroy(); // jack library destruction
214 jack_log("jack_client_close res = %d", res);
216 JackGlobals::fOpenMutex->Unlock();
217 return res;
220 LIB_EXPORT int jack_get_client_pid(const char *name)
222 jack_error("jack_get_client_pid : not implemented on library side");
223 return 0;
226 // Metadata API
228 LIB_EXPORT int jack_set_property(jack_client_t* ext_client, jack_uuid_t subject, const char* key, const char* value, const char* type)
230 JackGlobals::CheckContext("jack_set_property");
232 JackClient* client = (JackClient*)ext_client;
233 jack_log("jack_set_property ext_client %x client %x ", ext_client, client);
234 if (client == NULL) {
235 jack_error("jack_set_property called with a NULL client");
236 return -1;
237 } else {
238 JackMetadata* metadata = GetMetadata();
239 return (metadata ? metadata->SetProperty(client, subject, key, value, type) : -1);
243 LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type)
245 JackGlobals::CheckContext("jack_get_property");
247 JackMetadata* metadata = GetMetadata();
248 return (metadata ? metadata->GetProperty(subject, key, value, type) : -1);
251 LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_actual_description_too)
253 JackGlobals::CheckContext("jack_free_description");
255 JackMetadata* metadata = GetMetadata();
256 if (metadata)
257 metadata->FreeDescription(desc, free_actual_description_too);
260 LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc)
262 JackGlobals::CheckContext("jack_get_properties");
264 JackMetadata* metadata = GetMetadata();
265 return (metadata ? metadata->GetProperties(subject, desc) : -1);
268 LIB_EXPORT int jack_get_all_properties(jack_description_t** descriptions)
270 JackGlobals::CheckContext("jack_get_all_properties");
272 JackMetadata* metadata = GetMetadata();
273 return (metadata ? metadata->GetAllProperties(descriptions) : -1);
276 LIB_EXPORT int jack_remove_property(jack_client_t* ext_client, jack_uuid_t subject, const char* key)
278 JackGlobals::CheckContext("jack_remove_property");
280 JackClient* client = (JackClient*)ext_client;
281 jack_log("jack_remove_property ext_client %x client %x ", ext_client, client);
282 if (client == NULL) {
283 jack_error("jack_remove_property called with a NULL client");
284 return -1;
285 } else {
286 JackMetadata* metadata = GetMetadata();
287 return (metadata ? metadata->RemoveProperty(client, subject, key) : -1);
291 LIB_EXPORT int jack_remove_properties(jack_client_t* ext_client, jack_uuid_t subject)
293 JackGlobals::CheckContext("jack_remove_properties");
295 JackClient* client = (JackClient*)ext_client;
296 jack_log("jack_remove_properties ext_client %x client %x ", ext_client, client);
297 if (client == NULL) {
298 jack_error("jack_remove_properties called with a NULL client");
299 return -1;
300 } else {
301 JackMetadata* metadata = GetMetadata();
302 return (metadata ? metadata->RemoveProperties(client, subject) : -1);
306 LIB_EXPORT int jack_remove_all_properties(jack_client_t* ext_client)
308 JackGlobals::CheckContext("jack_remove_all_properties");
310 JackClient* client = (JackClient*)ext_client;
311 jack_log("jack_remove_all_properties ext_client %x client %x ", ext_client, client);
312 if (client == NULL) {
313 jack_error("jack_remove_all_properties called with a NULL client");
314 return -1;
315 } else {
316 JackMetadata* metadata = GetMetadata();
317 return (metadata ? metadata->RemoveAllProperties(client) : -1);
321 LIB_EXPORT int jack_set_property_change_callback(jack_client_t* ext_client, JackPropertyChangeCallback callback, void* arg)
323 JackGlobals::CheckContext("jack_set_property_change_callback");
325 JackClient* client = (JackClient*)ext_client;
326 jack_log("jack_set_property_change_callback ext_client %x client %x ", ext_client, client);
327 if (client == NULL) {
328 jack_error("jack_set_property_change_callback called with a NULL client");
329 return -1;
330 } else {
331 return client->SetPropertyChangeCallback(callback, arg);