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"
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
);
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
;
77 if (client_name
== NULL
) {
78 jack_error("jack_client_new called with a NULL client_name");
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
;
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
107 client
= new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
109 client
= new JackLibClient(GetSynchroTable());
112 int res
= client
->Open(va
.server_name
, client_name
, va
.session_id
, options
, status
);
115 JackLibGlobals::Destroy(); // jack library destruction
116 int my_status1
= (JackFailure
| JackServerError
);
117 *status
= (jack_status_t
)my_status1
;
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
;
130 if (client_name
== NULL
) {
131 jack_error("jack_client_open called with a NULL client_name");
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
;
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
160 client
= new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode
162 client
= new JackLibClient(GetSynchroTable());
165 int res
= client
->Open(va
.server_name
, client_name
, va
.session_id
, options
, status
);
168 JackLibGlobals::Destroy(); // jack library destruction
169 int my_status1
= (JackFailure
| JackServerError
);
170 *status
= (jack_status_t
)my_status1
;
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");
182 assert(JackGlobals::fOpenMutex
);
183 JackGlobals::fOpenMutex
->Lock();
185 va_start(ap
, status
);
186 jack_client_t
* res
= jack_client_open_aux(ext_client_name
, options
, status
, ap
);
188 JackGlobals::fOpenMutex
->Unlock();
190 } catch (std::bad_alloc
& e
) {
191 jack_error("Memory allocation error...");
194 jack_error("Unknown error...");
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();
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");
211 res
= client
->Close();
213 JackLibGlobals::Destroy(); // jack library destruction
214 jack_log("jack_client_close res = %d", res
);
216 JackGlobals::fOpenMutex
->Unlock();
220 LIB_EXPORT
int jack_get_client_pid(const char *name
)
222 jack_error("jack_get_client_pid : not implemented on library side");
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");
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();
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");
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");
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");
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");
331 return client
->SetPropertyChangeCallback(callback
, arg
);