Jack2  1.9.12
JackAPI.cpp
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4 
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.
9 
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.
14 
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.
18 
19 */
20 
21 #include "JackClient.h"
22 #include "JackError.h"
23 #include "JackGraphManager.h"
24 #include "JackEngineControl.h"
25 #include "JackClientControl.h"
26 #include "JackGlobals.h"
27 #include "JackTime.h"
28 #include "JackPortType.h"
29 #include "JackMetadata.h"
30 #include <math.h>
31 
32 using namespace Jack;
33 
34 #ifdef __cplusplus
35 extern "C"
36 {
37 #endif
38 
39  typedef void (*print_function)(const char*);
40  typedef void *(*thread_routine)(void*);
41 
42  LIB_EXPORT const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name";
43  LIB_EXPORT const char* JACK_METADATA_HARDWARE = "http://jackaudio.org/metadata/hardware";
44  LIB_EXPORT const char* JACK_METADATA_CONNECTED = "http://jackaudio.org/metadata/connected";
45  LIB_EXPORT const char* JACK_METADATA_PORT_GROUP = "http://jackaudio.org/metadata/port-group";
46  LIB_EXPORT const char* JACK_METADATA_ICON_SMALL = "http://jackaudio.org/metadata/icon-small";
47  LIB_EXPORT const char* JACK_METADATA_ICON_LARGE = "http://jackaudio.org/metadata/icon-large";
48 
49  LIB_EXPORT
50  void
51  jack_get_version(
52  int *major_ptr,
53  int *minor_ptr,
54  int *micro_ptr,
55  int *proto_ptr);
56 
57  LIB_EXPORT
58  const char*
59  jack_get_version_string();
60 
61  jack_client_t * jack_client_new_aux(const char* client_name,
62  jack_options_t options,
63  jack_status_t *status);
64 
65  LIB_EXPORT jack_client_t * jack_client_open(const char* client_name,
66  jack_options_t options,
67  jack_status_t *status, ...);
68  LIB_EXPORT jack_client_t * jack_client_new(const char* client_name);
69  LIB_EXPORT int jack_client_name_size(void);
70  LIB_EXPORT char* jack_get_client_name(jack_client_t *client);
71  LIB_EXPORT int jack_internal_client_new(const char* client_name,
72  const char* load_name,
73  const char* load_init);
74  LIB_EXPORT void jack_internal_client_close(const char* client_name);
75  LIB_EXPORT int jack_is_realtime(jack_client_t *client);
76  LIB_EXPORT void jack_on_shutdown(jack_client_t *client,
77  JackShutdownCallback shutdown_callback, void *arg);
78  LIB_EXPORT void jack_on_info_shutdown(jack_client_t *client,
79  JackInfoShutdownCallback shutdown_callback, void *arg);
80  LIB_EXPORT int jack_set_process_callback(jack_client_t *client,
81  JackProcessCallback process_callback,
82  void *arg);
83  LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
84 
85  // new
86  LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*);
87  LIB_EXPORT void jack_cycle_signal(jack_client_t*, int status);
88  LIB_EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);
89 
90  LIB_EXPORT int jack_set_thread_init_callback(jack_client_t *client,
91  JackThreadInitCallback thread_init_callback,
92  void *arg);
93  LIB_EXPORT int jack_set_freewheel_callback(jack_client_t *client,
94  JackFreewheelCallback freewheel_callback,
95  void *arg);
96  LIB_EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
97  LIB_EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes);
98  LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client,
99  JackBufferSizeCallback bufsize_callback,
100  void *arg);
101  LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client,
102  JackSampleRateCallback srate_callback,
103  void *arg);
104  LIB_EXPORT int jack_set_client_registration_callback(jack_client_t *,
105  JackClientRegistrationCallback
106  registration_callback, void *arg);
107  LIB_EXPORT int jack_set_port_registration_callback(jack_client_t *,
108  JackPortRegistrationCallback
109  registration_callback, void *arg);
110  LIB_EXPORT int jack_set_port_connect_callback(jack_client_t *,
111  JackPortConnectCallback
112  connect_callback, void *arg);
113  LIB_EXPORT int jack_set_port_rename_callback(jack_client_t *,
114  JackPortRenameCallback
115  rename_callback, void *arg);
116  LIB_EXPORT int jack_set_graph_order_callback(jack_client_t *,
117  JackGraphOrderCallback graph_callback,
118  void *);
119  LIB_EXPORT int jack_set_xrun_callback(jack_client_t *,
120  JackXRunCallback xrun_callback, void *arg);
121  LIB_EXPORT int jack_set_latency_callback(jack_client_t *client,
122  JackLatencyCallback latency_callback, void *arg);
123 
124  LIB_EXPORT int jack_activate(jack_client_t *client);
125  LIB_EXPORT int jack_deactivate(jack_client_t *client);
126  LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client,
127  const char* port_name,
128  const char* port_type,
129  unsigned long flags,
130  unsigned long buffer_size);
131  LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *);
132  LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t);
133  LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*);
134  LIB_EXPORT const char* jack_port_name(const jack_port_t *port);
135  LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port);
136  LIB_EXPORT int jack_port_flags(const jack_port_t *port);
137  LIB_EXPORT const char* jack_port_type(const jack_port_t *port);
138  LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port);
139  LIB_EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port);
140  LIB_EXPORT int jack_port_connected(const jack_port_t *port);
141  LIB_EXPORT int jack_port_connected_to(const jack_port_t *port,
142  const char* port_name);
143  LIB_EXPORT const char* * jack_port_get_connections(const jack_port_t *port);
144  LIB_EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client,
145  const jack_port_t *port);
146  LIB_EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst);
147  LIB_EXPORT int jack_port_untie(jack_port_t *port);
148 
149  // Old latency API
150  LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port);
151  LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *,
152  jack_port_t *port);
153  LIB_EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t);
154  LIB_EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port);
155 
156  // New latency API
157  LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
158  LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
159  LIB_EXPORT int jack_recompute_total_latencies(jack_client_t*);
160 
161  LIB_EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name);
162  LIB_EXPORT int jack_port_rename(jack_client_t *client, jack_port_t *port, const char* port_name);
163  LIB_EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias);
164  LIB_EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias);
165  LIB_EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]);
166  LIB_EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff);
167  LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t *client,
168  const char* port_name, int onoff);
169  LIB_EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff);
170  LIB_EXPORT int jack_port_monitoring_input(jack_port_t *port);
171  LIB_EXPORT int jack_connect(jack_client_t *,
172  const char* source_port,
173  const char* destination_port);
174  LIB_EXPORT int jack_disconnect(jack_client_t *,
175  const char* source_port,
176  const char* destination_port);
177  LIB_EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *);
178  LIB_EXPORT int jack_port_name_size(void);
179  LIB_EXPORT int jack_port_type_size(void);
180  LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type);
181  LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *);
182  LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *);
183  LIB_EXPORT const char* * jack_get_ports(jack_client_t *,
184  const char* port_name_pattern,
185  const char* type_name_pattern,
186  unsigned long flags);
187  LIB_EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name);
188  LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client,
189  jack_port_id_t port_id);
190  LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t *);
191  LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *);
192  LIB_EXPORT jack_time_t jack_get_time();
193  LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t usecs);
194  LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
195  LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t *);
196  LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client);
197  LIB_EXPORT int jack_get_cycle_times(const jack_client_t *client,
198  jack_nframes_t *current_frames,
199  jack_time_t *current_usecs,
200  jack_time_t *next_usecs,
201  float *period_usecs);
202  LIB_EXPORT float jack_cpu_load(jack_client_t *client);
203  LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *);
204  LIB_EXPORT void jack_set_error_function(print_function);
205  LIB_EXPORT void jack_set_info_function(print_function);
206 
207  LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t *client);
208  LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client);
209  LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client);
210 
211  LIB_EXPORT int jack_release_timebase(jack_client_t *client);
212  LIB_EXPORT int jack_set_sync_callback(jack_client_t *client,
213  JackSyncCallback sync_callback,
214  void *arg);
215  LIB_EXPORT int jack_set_sync_timeout(jack_client_t *client,
216  jack_time_t timeout);
217  LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client,
218  int conditional,
219  JackTimebaseCallback timebase_callback,
220  void *arg);
221  LIB_EXPORT int jack_transport_locate(jack_client_t *client,
222  jack_nframes_t frame);
223  LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client,
224  jack_position_t *pos);
225  LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client);
226  LIB_EXPORT int jack_transport_reposition(jack_client_t *client,
227  const jack_position_t *pos);
228  LIB_EXPORT void jack_transport_start(jack_client_t *client);
229  LIB_EXPORT void jack_transport_stop(jack_client_t *client);
230  LIB_EXPORT void jack_get_transport_info(jack_client_t *client,
231  jack_transport_info_t *tinfo);
232  LIB_EXPORT void jack_set_transport_info(jack_client_t *client,
233  jack_transport_info_t *tinfo);
234 
235  LIB_EXPORT int jack_client_real_time_priority(jack_client_t*);
236  LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t*);
237  LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority);
238  LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
239  jack_native_thread_t *thread,
240  int priority,
241  int realtime, // boolean
242  thread_routine routine,
243  void *arg);
244  LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread);
245 
246  LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread);
247  LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread);
248 #ifndef WIN32
249  LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc);
250 #endif
251  LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client,
252  jack_intclient_t intclient);
253  LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client,
254  const char* client_name,
255  jack_status_t *status);
256  LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client,
257  const char* client_name,
258  jack_options_t options,
259  jack_status_t *status, ...);
260 
261  LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client,
262  jack_intclient_t intclient);
263  LIB_EXPORT void jack_free(void* ptr);
264 
265  LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg);
266  LIB_EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path);
267  LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event);
268  LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev);
269  LIB_EXPORT char* jack_client_get_uuid (jack_client_t *client);
270  LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name);
271  LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid);
272  LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid);
273  LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds);
274  LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name);
275 
276  LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type);
277  LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type);
278  LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_description_itself);
279  LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc);
280  LIB_EXPORT int jack_get_all_properties(jack_description_t** descs);
281  LIB_EXPORT int jack_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key);
282  LIB_EXPORT int jack_remove_properties(jack_client_t* client, jack_uuid_t subject);
283  LIB_EXPORT int jack_remove_all_properties(jack_client_t* client);
284  LIB_EXPORT int jack_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg);
285 
286  LIB_EXPORT jack_uuid_t jack_client_uuid_generate();
287  LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t port_id);
288  LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t);
289  LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t);
290  LIB_EXPORT void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src);
291  LIB_EXPORT void jack_uuid_clear(jack_uuid_t*);
292  LIB_EXPORT int jack_uuid_parse(const char* buf, jack_uuid_t*);
293  LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]);
294  LIB_EXPORT int jack_uuid_empty(jack_uuid_t);
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 static inline bool CheckPort(jack_port_id_t port_index)
301 {
302  return (port_index > 0 && port_index < PORT_NUM_MAX);
303 }
304 
305 static inline bool CheckBufferSize(jack_nframes_t buffer_size)
306 {
307  return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX);
308 }
309 
310 static inline void WaitGraphChange()
311 {
312  /*
313  TLS key that is set only in RT thread, so never waits for pending
314  graph change in RT context (just read the current graph state).
315  */
316 
317  if (jack_tls_get(JackGlobals::fRealTimeThread) == NULL) {
318  JackGraphManager* manager = GetGraphManager();
319  JackEngineControl* control = GetEngineControl();
320  assert(manager);
321  assert(control);
322  if (manager->IsPendingChange()) {
323  jack_log("WaitGraphChange...");
324  JackSleep(int(control->fPeriodUsecs * 1.1f));
325  }
326  }
327 }
328 
329 LIB_EXPORT void jack_set_error_function(print_function func)
330 {
331  jack_error_callback = (func == NULL) ? &default_jack_error_callback : func;
332 }
333 
334 LIB_EXPORT void jack_set_info_function(print_function func)
335 {
336  jack_info_callback = (func == NULL) ? &default_jack_info_callback : func;
337 }
338 
339 LIB_EXPORT jack_client_t* jack_client_new(const char* client_name)
340 {
341  JackGlobals::CheckContext("jack_client_new");
342 
343  try {
344  assert(JackGlobals::fOpenMutex);
345  JackGlobals::fOpenMutex->Lock();
346  jack_error("jack_client_new: deprecated");
347  int options = JackUseExactName;
348  if (getenv("JACK_START_SERVER") == NULL) {
349  options |= JackNoStartServer;
350  }
351  jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL);
352  JackGlobals::fOpenMutex->Unlock();
353  return res;
354  } catch (std::bad_alloc& e) {
355  jack_error("Memory allocation error...");
356  return NULL;
357  } catch (...) {
358  jack_error("Unknown error...");
359  return NULL;
360  }
361 }
362 
363 LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
364 {
365  JackGlobals::CheckContext("jack_port_get_buffer");
366 
367  uintptr_t port_aux = (uintptr_t)port;
368  jack_port_id_t myport = (jack_port_id_t)port_aux;
369  if (!CheckPort(myport)) {
370  jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
371  return NULL;
372  } else {
373  JackGraphManager* manager = GetGraphManager();
374  return (manager ? manager->GetBuffer(myport, frames) : NULL);
375  }
376 }
377 
378 LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*)
379 {
380  return 0;
381 }
382 
383 LIB_EXPORT const char* jack_port_name(const jack_port_t* port)
384 {
385  JackGlobals::CheckContext("jack_port_name");
386 
387  uintptr_t port_aux = (uintptr_t)port;
388  jack_port_id_t myport = (jack_port_id_t)port_aux;
389  if (!CheckPort(myport)) {
390  jack_error("jack_port_name called with an incorrect port %ld", myport);
391  return NULL;
392  } else {
393  JackGraphManager* manager = GetGraphManager();
394  return (manager ? manager->GetPort(myport)->GetName() : NULL);
395  }
396 }
397 
398 LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port)
399 {
400  JackGlobals::CheckContext("jack_port_short_name");
401 
402  uintptr_t port_aux = (uintptr_t)port;
403  jack_port_id_t myport = (jack_port_id_t)port_aux;
404  if (!CheckPort(myport)) {
405  jack_error("jack_port_short_name called with an incorrect port %ld", myport);
406  return NULL;
407  } else {
408  JackGraphManager* manager = GetGraphManager();
409  return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
410  }
411 }
412 
413 LIB_EXPORT int jack_port_flags(const jack_port_t* port)
414 {
415  JackGlobals::CheckContext("jack_port_flags");
416 
417  uintptr_t port_aux = (uintptr_t)port;
418  jack_port_id_t myport = (jack_port_id_t)port_aux;
419  if (!CheckPort(myport)) {
420  jack_error("jack_port_flags called with an incorrect port %ld", myport);
421  return -1;
422  } else {
423  JackGraphManager* manager = GetGraphManager();
424  return (manager ? manager->GetPort(myport)->GetFlags() : -1);
425  }
426 }
427 
428 LIB_EXPORT const char* jack_port_type(const jack_port_t* port)
429 {
430  JackGlobals::CheckContext("jack_port_type");
431 
432  uintptr_t port_aux = (uintptr_t)port;
433  jack_port_id_t myport = (jack_port_id_t)port_aux;
434  if (!CheckPort(myport)) {
435  jack_error("jack_port_flags called an incorrect port %ld", myport);
436  return NULL;
437  } else {
438  JackGraphManager* manager = GetGraphManager();
439  return (manager ? manager->GetPort(myport)->GetType() : NULL);
440  }
441 }
442 
443 LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port)
444 {
445  JackGlobals::CheckContext("jack_port_type_id");
446 
447  uintptr_t port_aux = (uintptr_t)port;
448  jack_port_id_t myport = (jack_port_id_t)port_aux;
449  if (!CheckPort(myport)) {
450  jack_error("jack_port_type_id called an incorrect port %ld", myport);
451  return 0;
452  } else {
453  JackGraphManager* manager = GetGraphManager();
454  return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
455  }
456 }
457 
458 LIB_EXPORT int jack_port_connected(const jack_port_t* port)
459 {
460  JackGlobals::CheckContext("jack_port_connected");
461 
462  uintptr_t port_aux = (uintptr_t)port;
463  jack_port_id_t myport = (jack_port_id_t)port_aux;
464  if (!CheckPort(myport)) {
465  jack_error("jack_port_connected called with an incorrect port %ld", myport);
466  return -1;
467  } else {
468  WaitGraphChange();
469  JackGraphManager* manager = GetGraphManager();
470  return (manager ? manager->GetConnectionsNum(myport) : -1);
471  }
472 }
473 
474 LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
475 {
476  JackGlobals::CheckContext("jack_port_connected_to");
477 
478  uintptr_t port_aux = (uintptr_t)port;
479  jack_port_id_t src = (jack_port_id_t)port_aux;
480  if (!CheckPort(src)) {
481  jack_error("jack_port_connected_to called with an incorrect port %ld", src);
482  return -1;
483  } else if (port_name == NULL) {
484  jack_error("jack_port_connected_to called with a NULL port name");
485  return -1;
486  } else {
487  WaitGraphChange();
488  JackGraphManager* manager = GetGraphManager();
489  jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
490  if (dst == NO_PORT) {
491  jack_error("Unknown destination port port_name = %s", port_name);
492  return 0;
493  } else {
494  return manager->IsConnected(src, dst);
495  }
496  }
497 }
498 
499 LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
500 {
501  JackGlobals::CheckContext("jack_port_tie");
502 
503  uintptr_t src_aux = (uintptr_t)src;
504  jack_port_id_t mysrc = (jack_port_id_t)src_aux;
505  if (!CheckPort(mysrc)) {
506  jack_error("jack_port_tie called with a NULL src port");
507  return -1;
508  }
509  uintptr_t dst_aux = (uintptr_t)dst;
510  jack_port_id_t mydst = (jack_port_id_t)dst_aux;
511  if (!CheckPort(mydst)) {
512  jack_error("jack_port_tie called with a NULL dst port");
513  return -1;
514  }
515  JackGraphManager* manager = GetGraphManager();
516  if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
517  jack_error("jack_port_tie called with ports not belonging to the same client");
518  return -1;
519  } else {
520  return manager->GetPort(mydst)->Tie(mysrc);
521  }
522 }
523 
524 LIB_EXPORT int jack_port_untie(jack_port_t* port)
525 {
526  JackGlobals::CheckContext("jack_port_untie");
527 
528  uintptr_t port_aux = (uintptr_t)port;
529  jack_port_id_t myport = (jack_port_id_t)port_aux;
530  if (!CheckPort(myport)) {
531  jack_error("jack_port_untie called with an incorrect port %ld", myport);
532  return -1;
533  } else {
534  JackGraphManager* manager = GetGraphManager();
535  return (manager ? manager->GetPort(myport)->UnTie() : -1);
536  }
537 }
538 
539 LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
540 {
541  JackGlobals::CheckContext("jack_port_get_latency");
542 
543  uintptr_t port_aux = (uintptr_t)port;
544  jack_port_id_t myport = (jack_port_id_t)port_aux;
545  if (!CheckPort(myport)) {
546  jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
547  return 0;
548  } else {
549  WaitGraphChange();
550  JackGraphManager* manager = GetGraphManager();
551  return (manager ? manager->GetPort(myport)->GetLatency() : 0);
552  }
553 }
554 
555 LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
556 {
557  JackGlobals::CheckContext("jack_port_set_latency");
558 
559  uintptr_t port_aux = (uintptr_t)port;
560  jack_port_id_t myport = (jack_port_id_t)port_aux;
561  if (!CheckPort(myport)) {
562  jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
563  } else {
564  JackGraphManager* manager = GetGraphManager();
565  if (manager)
566  manager->GetPort(myport)->SetLatency(frames);
567  }
568 }
569 
570 LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
571 {
572  JackGlobals::CheckContext("jack_port_get_latency_range");
573 
574  uintptr_t port_aux = (uintptr_t)port;
575  jack_port_id_t myport = (jack_port_id_t)port_aux;
576  if (!CheckPort(myport)) {
577  jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport);
578  } else {
579  WaitGraphChange();
580  JackGraphManager* manager = GetGraphManager();
581  if (manager)
582  manager->GetPort(myport)->GetLatencyRange(mode, range);
583  }
584 }
585 
586 LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
587 {
588  JackGlobals::CheckContext("jack_port_set_latency_range");
589 
590  uintptr_t port_aux = (uintptr_t)port;
591  jack_port_id_t myport = (jack_port_id_t)port_aux;
592  if (!CheckPort(myport)) {
593  jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport);
594  } else {
595  WaitGraphChange();
596  JackGraphManager* manager = GetGraphManager();
597  if (manager)
598  manager->GetPort(myport)->SetLatencyRange(mode, range);
599  }
600 }
601 
602 LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
603 {
604  JackGlobals::CheckContext("jack_recompute_total_latency");
605 
606 
607  JackClient* client = (JackClient*)ext_client;
608  uintptr_t port_aux = (uintptr_t)port;
609  jack_port_id_t myport = (jack_port_id_t)port_aux;
610  if (client == NULL) {
611  jack_error("jack_recompute_total_latency called with a NULL client");
612  return -1;
613  } else if (!CheckPort(myport)) {
614  jack_error("jack_recompute_total_latency called with a NULL port");
615  return -1;
616  } else {
617  WaitGraphChange();
618  JackGraphManager* manager = GetGraphManager();
619  return (manager ? manager->ComputeTotalLatency(myport) : -1);
620  }
621 }
622 
623 LIB_EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
624 {
625  JackGlobals::CheckContext("jack_recompute_total_latencies");
626 
627  JackClient* client = (JackClient*)ext_client;
628  if (client == NULL) {
629  jack_error("jack_recompute_total_latencies called with a NULL client");
630  return -1;
631  } else {
632  return client->ComputeTotalLatencies();
633  }
634 }
635 
636 LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
637 {
638  JackGlobals::CheckContext("jack_port_set_name");
639  jack_error("jack_port_set_name: deprecated");
640 
641  // Find a valid client
642  jack_client_t* client = NULL;
643  for (int i = 0; i < CLIENT_NUM; i++) {
644  if ((client = (jack_client_t*)JackGlobals::fClientTable[i])) {
645  break;
646  }
647  }
648 
649  return (client) ? jack_port_rename(client, port, name) : -1;
650 }
651 
652 LIB_EXPORT int jack_port_rename(jack_client_t* ext_client, jack_port_t* port, const char* name)
653 {
654  JackGlobals::CheckContext("jack_port_rename");
655 
656  JackClient* client = (JackClient*)ext_client;
657  uintptr_t port_aux = (uintptr_t)port;
658  jack_port_id_t myport = (jack_port_id_t)port_aux;
659  if (client == NULL) {
660  jack_error("jack_port_rename called with a NULL client");
661  return -1;
662  } else if (!CheckPort(myport)) {
663  jack_error("jack_port_rename called with an incorrect port %ld", myport);
664  return -1;
665  } else if (name == NULL) {
666  jack_error("jack_port_rename called with a NULL port name");
667  return -1;
668  } else {
669  return client->PortRename(myport, name);
670  }
671 }
672 
673 LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
674 {
675  JackGlobals::CheckContext("jack_port_set_alias");
676 
677  uintptr_t port_aux = (uintptr_t)port;
678  jack_port_id_t myport = (jack_port_id_t)port_aux;
679  if (!CheckPort(myport)) {
680  jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
681  return -1;
682  } else if (name == NULL) {
683  jack_error("jack_port_set_alias called with a NULL port name");
684  return -1;
685  } else {
686  JackGraphManager* manager = GetGraphManager();
687  return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
688  }
689 }
690 
691 LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
692 {
693  JackGlobals::CheckContext("jack_port_unset_alias");
694 
695  uintptr_t port_aux = (uintptr_t)port;
696  jack_port_id_t myport = (jack_port_id_t)port_aux;
697  if (!CheckPort(myport)) {
698  jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
699  return -1;
700  } else if (name == NULL) {
701  jack_error("jack_port_unset_alias called with a NULL port name");
702  return -1;
703  } else {
704  JackGraphManager* manager = GetGraphManager();
705  return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
706  }
707 }
708 
709 LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
710 {
711  JackGlobals::CheckContext("jack_port_get_aliases");
712 
713  uintptr_t port_aux = (uintptr_t)port;
714  jack_port_id_t myport = (jack_port_id_t)port_aux;
715  if (!CheckPort(myport)) {
716  jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
717  return -1;
718  } else {
719  JackGraphManager* manager = GetGraphManager();
720  return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
721  }
722 }
723 
724 LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
725 {
726  JackGlobals::CheckContext("jack_port_request_monitor");
727 
728  uintptr_t port_aux = (uintptr_t)port;
729  jack_port_id_t myport = (jack_port_id_t)port_aux;
730  if (!CheckPort(myport)) {
731  jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
732  return -1;
733  } else {
734  JackGraphManager* manager = GetGraphManager();
735  return (manager ? manager->RequestMonitor(myport, onoff) : -1);
736  }
737 }
738 
739 LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
740 {
741  JackGlobals::CheckContext("jack_port_request_monitor_by_name");
742 
743  JackClient* client = (JackClient*)ext_client;
744  if (client == NULL) {
745  jack_error("jack_port_request_monitor_by_name called with a NULL client");
746  return -1;
747  } else {
748  JackGraphManager* manager = GetGraphManager();
749  if (!manager)
750  return -1;
751  jack_port_id_t myport = manager->GetPort(port_name);
752  if (!CheckPort(myport)) {
753  jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
754  return -1;
755  } else {
756  return manager->RequestMonitor(myport, onoff);
757  }
758  }
759 }
760 
761 LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
762 {
763  JackGlobals::CheckContext("jack_port_ensure_monitor");
764 
765  uintptr_t port_aux = (uintptr_t)port;
766  jack_port_id_t myport = (jack_port_id_t)port_aux;
767  if (!CheckPort(myport)) {
768  jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
769  return -1;
770  } else {
771  JackGraphManager* manager = GetGraphManager();
772  return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
773  }
774 }
775 
776 LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port)
777 {
778  JackGlobals::CheckContext("jack_port_monitoring_input");
779 
780  uintptr_t port_aux = (uintptr_t)port;
781  jack_port_id_t myport = (jack_port_id_t)port_aux;
782  if (!CheckPort(myport)) {
783  jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
784  return -1;
785  } else {
786  JackGraphManager* manager = GetGraphManager();
787  return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
788  }
789 }
790 
791 LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client)
792 {
793  JackGlobals::CheckContext("jack_is_realtime");
794 
795  JackClient* client = (JackClient*)ext_client;
796  if (client == NULL) {
797  jack_error("jack_is_realtime called with a NULL client");
798  return -1;
799  } else {
800  JackEngineControl* control = GetEngineControl();
801  return (control ? control->fRealTime : -1);
802  }
803 }
804 
805 LIB_EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg)
806 {
807  JackGlobals::CheckContext("jack_on_shutdown");
808 
809  JackClient* client = (JackClient*)ext_client;
810  if (client == NULL) {
811  jack_error("jack_on_shutdown called with a NULL client");
812  } else {
813  client->OnShutdown(callback, arg);
814  }
815 }
816 
817 LIB_EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg)
818 {
819  JackGlobals::CheckContext("jack_on_info_shutdown");
820 
821  JackClient* client = (JackClient*)ext_client;
822  if (client == NULL) {
823  jack_error("jack_on_info_shutdown called with a NULL client");
824  } else {
825  client->OnInfoShutdown(callback, arg);
826  }
827 }
828 
829 LIB_EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
830 {
831  JackGlobals::CheckContext("jack_set_process_callback");
832 
833  JackClient* client = (JackClient*)ext_client;
834  if (client == NULL) {
835  jack_error("jack_set_process_callback called with a NULL client");
836  return -1;
837  } else {
838  return client->SetProcessCallback(callback, arg);
839  }
840 }
841 
842 LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
843 {
844  JackGlobals::CheckContext("jack_thread_wait");
845 
846  JackClient* client = (JackClient*)ext_client;
847  if (client == NULL) {
848  jack_error("jack_thread_wait called with a NULL client");
849  return 0;
850  } else {
851  jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal");
852  return 0;
853  }
854 }
855 
856 LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
857 {
858  JackGlobals::CheckContext("jack_cycle_wait");
859 
860  JackClient* client = (JackClient*)ext_client;
861  if (client == NULL) {
862  jack_error("jack_cycle_wait called with a NULL client");
863  return 0;
864  } else {
865  return client->CycleWait();
866  }
867 }
868 
869 LIB_EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
870 {
871  JackGlobals::CheckContext("jack_cycle_signal");
872 
873  JackClient* client = (JackClient*)ext_client;
874  if (client == NULL) {
875  jack_error("jack_cycle_signal called with a NULL client");
876  } else {
877  client->CycleSignal(status);
878  }
879 }
880 
881 LIB_EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
882 {
883  JackGlobals::CheckContext("jack_set_process_thread");
884 
885  JackClient* client = (JackClient*)ext_client;
886  if (client == NULL) {
887  jack_error("jack_set_process_thread called with a NULL client");
888  return -1;
889  } else {
890  return client->SetProcessThread(fun, arg);
891  }
892 }
893 
894 LIB_EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
895 {
896  JackGlobals::CheckContext("jack_set_freewheel_callback");
897 
898  JackClient* client = (JackClient*)ext_client;
899  if (client == NULL) {
900  jack_error("jack_set_freewheel_callback called with a NULL client");
901  return -1;
902  } else {
903  return client->SetFreewheelCallback(freewheel_callback, arg);
904  }
905 }
906 
907 LIB_EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
908 {
909  JackGlobals::CheckContext("jack_set_freewheel");
910 
911  JackClient* client = (JackClient*)ext_client;
912  if (client == NULL) {
913  jack_error("jack_set_freewheel called with a NULL client");
914  return -1;
915  } else {
916  return client->SetFreeWheel(onoff);
917  }
918 }
919 
920 LIB_EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
921 {
922  JackGlobals::CheckContext("jack_set_buffer_size");
923 
924  JackClient* client = (JackClient*)ext_client;
925  if (client == NULL) {
926  jack_error("jack_set_buffer_size called with a NULL client");
927  return -1;
928  } else if (!CheckBufferSize(buffer_size)) {
929  return -1;
930  } else {
931  return client->SetBufferSize(buffer_size);
932  }
933 }
934 
935 LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
936 {
937  JackGlobals::CheckContext("jack_set_buffer_size_callback");
938 
939  JackClient* client = (JackClient*)ext_client;
940  if (client == NULL) {
941  jack_error("jack_set_buffer_size_callback called with a NULL client");
942  return -1;
943  } else {
944  return client->SetBufferSizeCallback(bufsize_callback, arg);
945  }
946 }
947 
948 LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
949 {
950  JackGlobals::CheckContext("jack_set_sample_rate_callback");
951 
952  JackClient* client = (JackClient*)ext_client;
953  if (client == NULL) {
954  jack_error("jack_set_sample_rate_callback called with a NULL client");
955  return -1;
956  } else {
957  return client->SetSampleRateCallback(srate_callback, arg);
958  }
959 }
960 
961 LIB_EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
962 {
963  JackGlobals::CheckContext("jack_set_client_registration_callback");
964 
965  JackClient* client = (JackClient*)ext_client;
966  if (client == NULL) {
967  jack_error("jack_set_client_registration_callback called with a NULL client");
968  return -1;
969  } else {
970  return client->SetClientRegistrationCallback(registration_callback, arg);
971  }
972 }
973 
974 LIB_EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
975 {
976  JackGlobals::CheckContext("jack_set_port_registration_callback");
977 
978  JackClient* client = (JackClient*)ext_client;
979  if (client == NULL) {
980  jack_error("jack_set_port_registration_callback called with a NULL client");
981  return -1;
982  } else {
983  return client->SetPortRegistrationCallback(registration_callback, arg);
984  }
985 }
986 
987 LIB_EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
988 {
989  JackGlobals::CheckContext("jack_set_port_connect_callback");
990 
991  JackClient* client = (JackClient*)ext_client;
992  if (client == NULL) {
993  jack_error("jack_set_port_connect_callback called with a NULL client");
994  return -1;
995  } else {
996  return client->SetPortConnectCallback(portconnect_callback, arg);
997  }
998 }
999 
1000 LIB_EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg)
1001 {
1002  JackGlobals::CheckContext("jack_set_port_rename_callback");
1003 
1004  JackClient* client = (JackClient*)ext_client;
1005  if (client == NULL) {
1006  jack_error("jack_set_port_rename_callback called with a NULL client");
1007  return -1;
1008  } else {
1009  return client->SetPortRenameCallback(rename_callback, arg);
1010  }
1011 }
1012 
1013 LIB_EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
1014 {
1015  JackGlobals::CheckContext("jack_set_graph_order_callback");
1016 
1017  JackClient* client = (JackClient*)ext_client;
1018  jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client);
1019  if (client == NULL) {
1020  jack_error("jack_set_graph_order_callback called with a NULL client");
1021  return -1;
1022  } else {
1023  return client->SetGraphOrderCallback(graph_callback, arg);
1024  }
1025 }
1026 
1027 LIB_EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
1028 {
1029  JackGlobals::CheckContext("jack_set_xrun_callback");
1030 
1031  JackClient* client = (JackClient*)ext_client;
1032  if (client == NULL) {
1033  jack_error("jack_set_xrun_callback called with a NULL client");
1034  return -1;
1035  } else {
1036  return client->SetXRunCallback(xrun_callback, arg);
1037  }
1038 }
1039 
1040 LIB_EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg)
1041 {
1042  JackGlobals::CheckContext("jack_set_latency_callback");
1043 
1044  JackClient* client = (JackClient*)ext_client;
1045  if (client == NULL) {
1046  jack_error("jack_set_latency_callback called with a NULL client");
1047  return -1;
1048  } else {
1049  return client->SetLatencyCallback(latency_callback, arg);
1050  }
1051 }
1052 
1053 LIB_EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
1054 {
1055  JackGlobals::CheckContext("jack_set_thread_init_callback");
1056 
1057  JackClient* client = (JackClient*)ext_client;
1058  jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client);
1059  if (client == NULL) {
1060  jack_error("jack_set_thread_init_callback called with a NULL client");
1061  return -1;
1062  } else {
1063  return client->SetInitCallback(init_callback, arg);
1064  }
1065 }
1066 
1067 LIB_EXPORT int jack_activate(jack_client_t* ext_client)
1068 {
1069  JackGlobals::CheckContext("jack_activate");
1070 
1071  JackClient* client = (JackClient*)ext_client;
1072  if (client == NULL) {
1073  jack_error("jack_activate called with a NULL client");
1074  return -1;
1075  } else {
1076  return client->Activate();
1077  }
1078 }
1079 
1080 LIB_EXPORT int jack_deactivate(jack_client_t* ext_client)
1081 {
1082  JackGlobals::CheckContext("jack_deactivate");
1083 
1084  JackClient* client = (JackClient*)ext_client;
1085  if (client == NULL) {
1086  jack_error("jack_deactivate called with a NULL client");
1087  return -1;
1088  } else {
1089  return client->Deactivate();
1090  }
1091 }
1092 
1093 LIB_EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
1094 {
1095  JackGlobals::CheckContext("jack_port_register");
1096 
1097  JackClient* client = (JackClient*)ext_client;
1098  if (client == NULL) {
1099  jack_error("jack_port_register called with a NULL client");
1100  return NULL;
1101  } else if ((port_name == NULL) || (port_type == NULL)) {
1102  jack_error("jack_port_register called with a NULL port name or a NULL port_type");
1103  return NULL;
1104  } else {
1105  return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size));
1106  }
1107 }
1108 
1109 LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
1110 {
1111  JackGlobals::CheckContext("jack_port_unregister");
1112 
1113  JackClient* client = (JackClient*)ext_client;
1114  if (client == NULL) {
1115  jack_error("jack_port_unregister called with a NULL client");
1116  return -1;
1117  }
1118  uintptr_t port_aux = (uintptr_t)port;
1119  jack_port_id_t myport = (jack_port_id_t)port_aux;
1120  if (!CheckPort(myport)) {
1121  jack_error("jack_port_unregister called with an incorrect port %ld", myport);
1122  return -1;
1123  }
1124  return client->PortUnRegister(myport);
1125 }
1126 
1127 LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
1128 {
1129  JackGlobals::CheckContext("jack_port_is_mine");
1130 
1131  JackClient* client = (JackClient*)ext_client;
1132  if (client == NULL) {
1133  jack_error("jack_port_is_mine called with a NULL client");
1134  return -1;
1135  }
1136  uintptr_t port_aux = (uintptr_t)port;
1137  jack_port_id_t myport = (jack_port_id_t)port_aux;
1138  if (!CheckPort(myport)) {
1139  jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
1140  return -1;
1141  }
1142  return client->PortIsMine(myport);
1143 }
1144 
1145 LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port)
1146 {
1147  JackGlobals::CheckContext("jack_port_get_connections");
1148 
1149  uintptr_t port_aux = (uintptr_t)port;
1150  jack_port_id_t myport = (jack_port_id_t)port_aux;
1151  if (!CheckPort(myport)) {
1152  jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
1153  return NULL;
1154  } else {
1155  WaitGraphChange();
1156  JackGraphManager* manager = GetGraphManager();
1157  return (manager ? manager->GetConnections(myport) : NULL);
1158  }
1159 }
1160 
1161 // Calling client does not need to "own" the port
1162 LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
1163 {
1164  JackGlobals::CheckContext("jack_port_get_all_connections");
1165 
1166  JackClient* client = (JackClient*)ext_client;
1167  if (client == NULL) {
1168  jack_error("jack_port_get_all_connections called with a NULL client");
1169  return NULL;
1170  }
1171 
1172  uintptr_t port_aux = (uintptr_t)port;
1173  jack_port_id_t myport = (jack_port_id_t)port_aux;
1174  if (!CheckPort(myport)) {
1175  jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
1176  return NULL;
1177  } else {
1178  WaitGraphChange();
1179  JackGraphManager* manager = GetGraphManager();
1180  return (manager ? manager->GetConnections(myport) : NULL);
1181  }
1182 }
1183 
1184 LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
1185 {
1186  JackGlobals::CheckContext("jack_port_get_total_latency");
1187 
1188  JackClient* client = (JackClient*)ext_client;
1189  if (client == NULL) {
1190  jack_error("jack_port_get_total_latency called with a NULL client");
1191  return 0;
1192  }
1193 
1194  uintptr_t port_aux = (uintptr_t)port;
1195  jack_port_id_t myport = (jack_port_id_t)port_aux;
1196  if (!CheckPort(myport)) {
1197  jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
1198  return 0;
1199  } else {
1200  WaitGraphChange();
1201  JackGraphManager* manager = GetGraphManager();
1202  if (manager) {
1203  manager->ComputeTotalLatency(myport);
1204  return manager->GetPort(myport)->GetTotalLatency();
1205  } else {
1206  return 0;
1207  }
1208  }
1209 }
1210 
1211 LIB_EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
1212 {
1213  JackGlobals::CheckContext("jack_connect");
1214 
1215  JackClient* client = (JackClient*)ext_client;
1216  if (client == NULL) {
1217  jack_error("jack_connect called with a NULL client");
1218  return -1;
1219  } else if ((src == NULL) || (dst == NULL)) {
1220  jack_error("jack_connect called with a NULL port name");
1221  return -1;
1222  } else {
1223  return client->PortConnect(src, dst);
1224  }
1225 }
1226 
1227 LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
1228 {
1229  JackGlobals::CheckContext("jack_disconnect");
1230 
1231  JackClient* client = (JackClient*)ext_client;
1232  if (client == NULL) {
1233  jack_error("jack_disconnect called with a NULL client");
1234  return -1;
1235  } else if ((src == NULL) || (dst == NULL)) {
1236  jack_error("jack_disconnect called with a NULL port name");
1237  return -1;
1238  } else {
1239  return client->PortDisconnect(src, dst);
1240  }
1241 }
1242 
1243 LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
1244 {
1245  JackGlobals::CheckContext("jack_port_disconnect");
1246 
1247  JackClient* client = (JackClient*)ext_client;
1248  if (client == NULL) {
1249  jack_error("jack_port_disconnect called with a NULL client");
1250  return -1;
1251  }
1252  uintptr_t port_aux = (uintptr_t)src;
1253  jack_port_id_t myport = (jack_port_id_t)port_aux;
1254  if (!CheckPort(myport)) {
1255  jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
1256  return -1;
1257  }
1258  return client->PortDisconnect(myport);
1259 }
1260 
1261 LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
1262 {
1263  JackGlobals::CheckContext("jack_get_sample_rate");
1264 
1265  JackClient* client = (JackClient*)ext_client;
1266  if (client == NULL) {
1267  jack_error("jack_get_sample_rate called with a NULL client");
1268  return 0;
1269  } else {
1270  JackEngineControl* control = GetEngineControl();
1271  return (control ? control->fSampleRate : 0);
1272  }
1273 }
1274 
1275 LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
1276 {
1277  JackGlobals::CheckContext("jack_get_buffer_size");
1278 
1279  JackClient* client = (JackClient*)ext_client;
1280  if (client == NULL) {
1281  jack_error("jack_get_buffer_size called with a NULL client");
1282  return 0;
1283  } else {
1284  JackEngineControl* control = GetEngineControl();
1285  return (control ? control->fBufferSize : 0);
1286  }
1287 }
1288 
1289 LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
1290 {
1291  JackGlobals::CheckContext("jack_get_ports");
1292 
1293  JackClient* client = (JackClient*)ext_client;
1294  if (client == NULL) {
1295  jack_error("jack_get_ports called with a NULL client");
1296  return NULL;
1297  }
1298  JackGraphManager* manager = GetGraphManager();
1299  return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL);
1300 }
1301 
1302 LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
1303 {
1304  JackGlobals::CheckContext("jack_port_by_name");
1305 
1306  JackClient* client = (JackClient*)ext_client;
1307  if (client == NULL) {
1308  jack_error("jack_port_by_name called with a NULL client");
1309  return NULL;
1310  }
1311 
1312  if (portname == NULL) {
1313  jack_error("jack_port_by_name called with a NULL port name");
1314  return NULL;
1315  }
1316 
1317  JackGraphManager* manager = GetGraphManager();
1318  if (manager) {
1319  int res = manager->GetPort(portname); // returns a port index at least > 1
1320  return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res);
1321  } else {
1322  return NULL;
1323  }
1324 }
1325 
1326 LIB_EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
1327 {
1328  JackGlobals::CheckContext("jack_port_by_id");
1329 
1330  /* jack_port_t* type is actually the port index */
1331  return (jack_port_t*)((uintptr_t)id);
1332 }
1333 
1334 LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
1335 {
1336  JackGlobals::CheckContext("jack_engine_takeover_timebase");
1337 
1338  JackClient* client = (JackClient*)ext_client;
1339  if (client == NULL) {
1340  jack_error("jack_engine_takeover_timebase called with a NULL client");
1341  return -1;
1342  } else {
1343  jack_error("jack_engine_takeover_timebase: deprecated\n");
1344  return 0;
1345  }
1346 }
1347 
1348 LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
1349 {
1350  JackGlobals::CheckContext("jack_frames_since_cycle_start");
1351 
1352  JackTimer timer;
1353  JackEngineControl* control = GetEngineControl();
1354  if (control) {
1355  control->ReadFrameTime(&timer);
1356  return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate);
1357  } else {
1358  return 0;
1359  }
1360 }
1361 
1362 LIB_EXPORT jack_time_t jack_get_time()
1363 {
1364  JackGlobals::CheckContext("jack_get_time");
1365 
1366  return GetMicroSeconds();
1367 }
1368 
1369 LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
1370 {
1371  JackGlobals::CheckContext("jack_frames_to_time");
1372 
1373  JackClient* client = (JackClient*)ext_client;
1374  if (client == NULL) {
1375  jack_error("jack_frames_to_time called with a NULL client");
1376  return 0;
1377  } else {
1378  JackTimer timer;
1379  JackEngineControl* control = GetEngineControl();
1380  if (control) {
1381  control->ReadFrameTime(&timer);
1382  return timer.Frames2Time(frames, control->fBufferSize);
1383  } else {
1384  return 0;
1385  }
1386  }
1387 }
1388 
1389 LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t usecs)
1390 {
1391  JackGlobals::CheckContext("jack_time_to_frames");
1392 
1393  JackClient* client = (JackClient*)ext_client;
1394  if (client == NULL) {
1395  jack_error("jack_time_to_frames called with a NULL client");
1396  return 0;
1397  } else {
1398  JackTimer timer;
1399  JackEngineControl* control = GetEngineControl();
1400  if (control) {
1401  control->ReadFrameTime(&timer);
1402  return timer.Time2Frames(usecs, control->fBufferSize);
1403  } else {
1404  return 0;
1405  }
1406  }
1407 }
1408 
1409 LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
1410 {
1411  JackGlobals::CheckContext("jack_frame_time");
1412 
1413  return jack_time_to_frames(ext_client, GetMicroSeconds());
1414 }
1415 
1416 LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
1417 {
1418  JackGlobals::CheckContext("jack_last_frame_time");
1419 
1420  JackEngineControl* control = GetEngineControl();
1421  return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0;
1422 }
1423 
1424 LIB_EXPORT int jack_get_cycle_times(const jack_client_t *client,
1425  jack_nframes_t *current_frames,
1426  jack_time_t *current_usecs,
1427  jack_time_t *next_usecs,
1428  float *period_usecs)
1429 {
1430  JackGlobals::CheckContext("jack_get_cycle_times");
1431 
1432  JackEngineControl* control = GetEngineControl();
1433  if (control) {
1434  JackTimer timer;
1435  control->ReadFrameTime(&timer);
1436  return timer.GetCycleTimes(current_frames, current_usecs, next_usecs, period_usecs);
1437  } else {
1438  return -1;
1439  }
1440 }
1441 
1442 LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client)
1443 {
1444  JackGlobals::CheckContext("jack_cpu_load");
1445 
1446  JackClient* client = (JackClient*)ext_client;
1447  if (client == NULL) {
1448  jack_error("jack_cpu_load called with a NULL client");
1449  return 0.0f;
1450  } else {
1451  JackEngineControl* control = GetEngineControl();
1452  return (control ? control->fCPULoad : 0.0f);
1453  }
1454 }
1455 
1456 LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client)
1457 {
1458  JackGlobals::CheckContext("jack_client_thread_id");
1459 
1460  JackClient* client = (JackClient*)ext_client;
1461  if (client == NULL) {
1462  jack_error("jack_client_thread_id called with a NULL client");
1463  return (jack_native_thread_t)NULL;
1464  } else {
1465  return client->GetThreadID();
1466  }
1467 }
1468 
1469 LIB_EXPORT char* jack_get_client_name(jack_client_t* ext_client)
1470 {
1471  JackGlobals::CheckContext("jack_get_client_name");
1472 
1473  JackClient* client = (JackClient*)ext_client;
1474  if (client == NULL) {
1475  jack_error("jack_get_client_name called with a NULL client");
1476  return NULL;
1477  } else {
1478  return client->GetClientControl()->fName;
1479  }
1480 }
1481 
1482 LIB_EXPORT int jack_client_name_size(void)
1483 {
1484  return JACK_CLIENT_NAME_SIZE+1;
1485 }
1486 
1487 LIB_EXPORT int jack_port_name_size(void)
1488 {
1489  return REAL_JACK_PORT_NAME_SIZE+1;
1490 }
1491 
1492 LIB_EXPORT int jack_port_type_size(void)
1493 {
1494  return JACK_PORT_TYPE_SIZE;
1495 }
1496 
1497 LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type)
1498 {
1499  JackGlobals::CheckContext("jack_port_type_get_buffer_size");
1500 
1501  JackClient* client = (JackClient*)ext_client;
1502  if (client == NULL) {
1503  jack_error("jack_port_type_get_buffer_size called with a NULL client");
1504  return 0;
1505  } else {
1506  jack_port_type_id_t port_id = GetPortTypeId(port_type);
1507  if (port_id == PORT_TYPES_MAX) {
1508  jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type);
1509  return 0;
1510  } else {
1511  return GetPortType(port_id)->size();
1512  }
1513  }
1514 }
1515 
1516 // transport.h
1517 LIB_EXPORT int jack_release_timebase(jack_client_t* ext_client)
1518 {
1519  JackGlobals::CheckContext("jack_release_timebase");
1520 
1521  JackClient* client = (JackClient*)ext_client;
1522  if (client == NULL) {
1523  jack_error("jack_release_timebase called with a NULL client");
1524  return -1;
1525  } else {
1526  return client->ReleaseTimebase();
1527  }
1528 }
1529 
1530 LIB_EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
1531 {
1532  JackGlobals::CheckContext("jack_set_sync_callback");
1533 
1534  JackClient* client = (JackClient*)ext_client;
1535  if (client == NULL) {
1536  jack_error("jack_set_sync_callback called with a NULL client");
1537  return -1;
1538  } else {
1539  return client->SetSyncCallback(sync_callback, arg);
1540  }
1541 }
1542 
1543 LIB_EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
1544 {
1545  JackGlobals::CheckContext("jack_set_sync_timeout");
1546 
1547  JackClient* client = (JackClient*)ext_client;
1548  if (client == NULL) {
1549  jack_error("jack_set_sync_timeout called with a NULL client");
1550  return -1;
1551  } else {
1552  return client->SetSyncTimeout(timeout);
1553  }
1554 }
1555 
1556 LIB_EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
1557 {
1558  JackGlobals::CheckContext("jack_set_timebase_callback");
1559 
1560  JackClient* client = (JackClient*)ext_client;
1561  if (client == NULL) {
1562  jack_error("jack_set_timebase_callback called with a NULL client");
1563  return -1;
1564  } else {
1565  return client->SetTimebaseCallback(conditional, timebase_callback, arg);
1566  }
1567 }
1568 
1569 LIB_EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
1570 {
1571  JackGlobals::CheckContext("jack_transport_locate");
1572 
1573  JackClient* client = (JackClient*)ext_client;
1574  if (client == NULL) {
1575  jack_error("jack_transport_locate called with a NULL client");
1576  return -1;
1577  } else {
1578  client->TransportLocate(frame);
1579  return 0;
1580  }
1581 }
1582 
1583 LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
1584 {
1585  JackGlobals::CheckContext("jack_transport_query");
1586 
1587  JackClient* client = (JackClient*)ext_client;
1588  if (client == NULL) {
1589  jack_error("jack_transport_query called with a NULL client");
1590  return JackTransportStopped;
1591  } else {
1592  return client->TransportQuery(pos);
1593  }
1594 }
1595 
1596 LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
1597 {
1598  JackGlobals::CheckContext("jack_get_current_transport_frame");
1599 
1600  JackClient* client = (JackClient*)ext_client;
1601  if (client == NULL) {
1602  jack_error("jack_get_current_transport_frame called with a NULL client");
1603  return 0;
1604  } else {
1605  return client->GetCurrentTransportFrame();
1606  }
1607 }
1608 
1609 LIB_EXPORT int jack_transport_reposition(jack_client_t* ext_client, const jack_position_t* pos)
1610 {
1611  JackGlobals::CheckContext("jack_transport_reposition");
1612 
1613  JackClient* client = (JackClient*)ext_client;
1614  if (client == NULL) {
1615  jack_error("jack_transport_reposition called with a NULL client");
1616  return -1;
1617  } else {
1618  client->TransportReposition(pos);
1619  return 0;
1620  }
1621 }
1622 
1623 LIB_EXPORT void jack_transport_start(jack_client_t* ext_client)
1624 {
1625  JackGlobals::CheckContext("jack_transport_start");
1626 
1627  JackClient* client = (JackClient*)ext_client;
1628  if (client == NULL) {
1629  jack_error("jack_transport_start called with a NULL client");
1630  } else {
1631  client->TransportStart();
1632  }
1633 }
1634 
1635 LIB_EXPORT void jack_transport_stop(jack_client_t* ext_client)
1636 {
1637  JackGlobals::CheckContext("jack_transport_stop");
1638 
1639  JackClient* client = (JackClient*)ext_client;
1640  if (client == NULL) {
1641  jack_error("jack_transport_stop called with a NULL client");
1642  } else {
1643  client->TransportStop();
1644  }
1645 }
1646 
1647 // deprecated
1648 LIB_EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1649 {
1650  JackGlobals::CheckContext("jack_get_transport_info");
1651 
1652  jack_error("jack_get_transport_info: deprecated");
1653  if (tinfo)
1654  memset(tinfo, 0, sizeof(jack_transport_info_t));
1655 }
1656 
1657 LIB_EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1658 {
1659  JackGlobals::CheckContext("jack_set_transport_info");
1660 
1661  jack_error("jack_set_transport_info: deprecated");
1662  if (tinfo)
1663  memset(tinfo, 0, sizeof(jack_transport_info_t));
1664 }
1665 
1666 // statistics.h
1667 LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
1668 {
1669  JackGlobals::CheckContext("jack_get_max_delayed_usecs");
1670 
1671  JackClient* client = (JackClient*)ext_client;
1672  if (client == NULL) {
1673  jack_error("jack_get_max_delayed_usecs called with a NULL client");
1674  return 0.f;
1675  } else {
1676  JackEngineControl* control = GetEngineControl();
1677  return (control ? control->fMaxDelayedUsecs : 0.f);
1678  }
1679  }
1680 
1681 LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
1682 {
1683  JackGlobals::CheckContext("jack_get_xrun_delayed_usecs");
1684 
1685  JackClient* client = (JackClient*)ext_client;
1686  if (client == NULL) {
1687  jack_error("jack_get_xrun_delayed_usecs called with a NULL client");
1688  return 0.f;
1689  } else {
1690  JackEngineControl* control = GetEngineControl();
1691  return (control ? control->fXrunDelayedUsecs : 0.f);
1692  }
1693 }
1694 
1695 LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
1696 {
1697  JackGlobals::CheckContext("jack_reset_max_delayed_usecs");
1698 
1699  JackClient* client = (JackClient*)ext_client;
1700  if (client == NULL) {
1701  jack_error("jack_reset_max_delayed_usecs called with a NULL client");
1702  } else {
1703  JackEngineControl* control = GetEngineControl();
1704  control->ResetXRun();
1705  }
1706 }
1707 
1708 // thread.h
1709 LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client)
1710 {
1711  JackGlobals::CheckContext("jack_client_real_time_priority");
1712 
1713  JackClient* client = (JackClient*)ext_client;
1714  if (client == NULL) {
1715  jack_error("jack_client_real_time_priority called with a NULL client");
1716  return -1;
1717  } else {
1718  JackEngineControl* control = GetEngineControl();
1719  return (control->fRealTime) ? control->fClientPriority : -1;
1720  }
1721 }
1722 
1723 LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client)
1724 {
1725  JackGlobals::CheckContext("jack_client_max_real_time_priority");
1726 
1727  JackClient* client = (JackClient*)ext_client;
1728  if (client == NULL) {
1729  jack_error("jack_client_max_real_time_priority called with a NULL client");
1730  return -1;
1731  } else {
1732  JackEngineControl* control = GetEngineControl();
1733  return (control->fRealTime) ? control->fMaxClientPriority : -1;
1734  }
1735 }
1736 
1737 LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority)
1738 {
1739  JackEngineControl* control = GetEngineControl();
1740  return (control
1741  ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint)
1742  : -1);
1743 }
1744 
1745 LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
1746  jack_native_thread_t *thread,
1747  int priority,
1748  int realtime, /* boolean */
1749  thread_routine routine,
1750  void *arg)
1751 {
1752  JackGlobals::CheckContext("jack_client_create_thread");
1753 
1754  JackEngineControl* control = GetEngineControl();
1755  int res = JackThread::StartImp(thread, priority, realtime, routine, arg);
1756  return (res == 0)
1757  ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : res))
1758  : res;
1759 }
1760 
1761 LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread)
1762 {
1763  return JackThread::DropRealTimeImp(thread);
1764 }
1765 
1766 LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread)
1767 {
1768  JackGlobals::CheckContext("jack_client_stop_thread");
1769  return JackThread::StopImp(thread);
1770 }
1771 
1772 LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread)
1773 {
1774  JackGlobals::CheckContext("jack_client_kill_thread");
1775  return JackThread::KillImp(thread);
1776 }
1777 
1778 #ifndef WIN32
1779 LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc)
1780 {
1781  if (jtc == NULL) {
1782  JackGlobals::fJackThreadCreator = pthread_create;
1783  } else {
1784  JackGlobals::fJackThreadCreator = jtc;
1785  }
1786 }
1787 #endif
1788 
1789 // intclient.h
1790 LIB_EXPORT int jack_internal_client_new (const char* client_name,
1791  const char* load_name,
1792  const char* load_init)
1793 {
1794  JackGlobals::CheckContext("jack_internal_client_new");
1795  jack_error("jack_internal_client_new: deprecated");
1796  return -1;
1797 }
1798 
1799 LIB_EXPORT void jack_internal_client_close (const char* client_name)
1800 {
1801  JackGlobals::CheckContext("jack_internal_client_close");
1802  jack_error("jack_internal_client_close: deprecated");
1803 }
1804 
1805 LIB_EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
1806 {
1807  JackGlobals::CheckContext("jack_get_internal_client_name");
1808 
1809  JackClient* client = (JackClient*)ext_client;
1810  if (client == NULL) {
1811  jack_error("jack_get_internal_client_name called with a NULL client");
1812  return NULL;
1813  } else if (intclient >= CLIENT_NUM) {
1814  jack_error("jack_get_internal_client_name: incorrect client");
1815  return NULL;
1816  } else {
1817  return client->GetInternalClientName(intclient);
1818  }
1819 }
1820 
1821 LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
1822 {
1823  JackGlobals::CheckContext("jack_internal_client_handle");
1824 
1825  JackClient* client = (JackClient*)ext_client;
1826  if (client == NULL) {
1827  jack_error("jack_internal_client_handle called with a NULL client");
1828  return 0;
1829  } else {
1830  jack_status_t my_status;
1831  if (status == NULL) /* no status from caller? */
1832  status = &my_status; /* use local status word */
1833  *status = (jack_status_t)0;
1834  return client->InternalClientHandle(client_name, status);
1835  }
1836 }
1837 
1838 static jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
1839 {
1840  JackGlobals::CheckContext("jack_internal_client_load_aux");
1841 
1842  JackClient* client = (JackClient*)ext_client;
1843  if (client == NULL) {
1844  jack_error("jack_internal_client_load called with a NULL client");
1845  return 0;
1846  } else {
1847  jack_varargs_t va;
1848  jack_status_t my_status;
1849 
1850  if (status == NULL) /* no status from caller? */
1851  status = &my_status; /* use local status word */
1852  *status = (jack_status_t)0;
1853 
1854  /* validate parameters */
1855  if ((options & ~JackLoadOptions)) {
1856  int my_status1 = *status | (JackFailure | JackInvalidOption);
1857  *status = (jack_status_t)my_status1;
1858  return 0;
1859  }
1860 
1861  /* parse variable arguments */
1862  jack_varargs_parse(options, ap, &va);
1863  return client->InternalClientLoad(client_name, options, status, &va);
1864  }
1865 }
1866 
1867 LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...)
1868 {
1869  JackGlobals::CheckContext("jack_internal_client_load");
1870 
1871  va_list ap;
1872  va_start(ap, status);
1873  jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap);
1874  va_end(ap);
1875  return res;
1876 }
1877 
1878 LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
1879 {
1880  JackGlobals::CheckContext("jack_internal_client_load");
1881 
1882  JackClient* client = (JackClient*)ext_client;
1883  if (client == NULL) {
1884  jack_error("jack_internal_client_unload called with a NULL client");
1885  return (jack_status_t)(JackNoSuchClient | JackFailure);
1886  } else if (intclient >= CLIENT_NUM) {
1887  jack_error("jack_internal_client_unload: incorrect client");
1888  return (jack_status_t)(JackNoSuchClient | JackFailure);
1889  } else {
1890  jack_status_t my_status;
1891  client->InternalClientUnload(intclient, &my_status);
1892  return my_status;
1893  }
1894 }
1895 
1896 LIB_EXPORT void jack_get_version(int *major_ptr,
1897  int *minor_ptr,
1898  int *micro_ptr,
1899  int *proto_ptr)
1900 {
1901  JackGlobals::CheckContext("jack_get_version");
1902 
1903  // FIXME: We need these comming from build system
1904  *major_ptr = 0;
1905  *minor_ptr = 0;
1906  *micro_ptr = 0;
1907  *proto_ptr = 0;
1908 }
1909 
1910 LIB_EXPORT const char* jack_get_version_string()
1911 {
1912  JackGlobals::CheckContext("jack_get_version_string");
1913  return VERSION;
1914 }
1915 
1916 LIB_EXPORT void jack_free(void* ptr)
1917 {
1918  JackGlobals::CheckContext("jack_free");
1919 
1920  if (ptr) {
1921  free(ptr);
1922  }
1923 }
1924 
1925 // session.h
1926 LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg)
1927 {
1928  JackGlobals::CheckContext("jack_set_session_callback");
1929 
1930  JackClient* client = (JackClient*)ext_client;
1931  jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client);
1932  if (client == NULL) {
1933  jack_error("jack_set_session_callback called with a NULL client");
1934  return -1;
1935  } else {
1936  return client->SetSessionCallback(session_callback, arg);
1937  }
1938 }
1939 
1940 LIB_EXPORT jack_session_command_t* jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path)
1941 {
1942  JackGlobals::CheckContext("jack_session_notify");
1943 
1944  JackClient* client = (JackClient*)ext_client;
1945  jack_log("jack_session_notify ext_client %x client %x ", ext_client, client);
1946  if (client == NULL) {
1947  jack_error("jack_session_notify called with a NULL client");
1948  return NULL;
1949  } else {
1950  return client->SessionNotify(target, ev_type, path);
1951  }
1952 }
1953 
1954 LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event)
1955 {
1956  JackGlobals::CheckContext("jack_session_reply");
1957 
1958  JackClient* client = (JackClient*)ext_client;
1959  jack_log("jack_session_reply ext_client %x client %x ", ext_client, client);
1960  if (client == NULL) {
1961  jack_error("jack_session_reply called with a NULL client");
1962  return -1;
1963  } else {
1964  return client->SessionReply(event);
1965  }
1966 }
1967 
1969 {
1970  JackGlobals::CheckContext("jack_session_event_free");
1971 
1972  if (ev) {
1973  if (ev->session_dir)
1974  free((void *)ev->session_dir);
1975  if (ev->client_uuid)
1976  free((void *)ev->client_uuid);
1977  if (ev->command_line)
1978  free(ev->command_line);
1979  free(ev);
1980  }
1981 }
1982 
1983 LIB_EXPORT char *jack_client_get_uuid(jack_client_t* ext_client)
1984 {
1985  JackGlobals::CheckContext("jack_client_get_uuid");
1986 
1987  JackClient* client = (JackClient*)ext_client;
1988  if (client == NULL) {
1989  jack_error("jack_client_get_uuid called with a NULL client");
1990  return NULL;
1991  } else {
1992  char retval[16];
1993  snprintf(retval, sizeof(retval), "%d", client->GetClientControl()->fSessionID);
1994  return strdup(retval);
1995  }
1996 }
1997 
1998 LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name)
1999 {
2000  JackGlobals::CheckContext("jack_get_uuid_for_client_name");
2001 
2002  JackClient* client = (JackClient*)ext_client;
2003  jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
2004  if (client == NULL) {
2005  jack_error("jack_get_uuid_for_client_name called with a NULL client");
2006  return NULL;
2007  } else {
2008  return client->GetUUIDForClientName(client_name);
2009  }
2010 }
2011 
2012 LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid)
2013 {
2014  JackGlobals::CheckContext("jack_get_client_name_by_uuid");
2015 
2016  JackClient* client = (JackClient*)ext_client;
2017  jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
2018  if (client == NULL) {
2019  jack_error("jack_get_client_name_by_uuid called with a NULL client");
2020  return NULL;
2021  } else {
2022  return client->GetClientNameByUUID(client_uuid);
2023  }
2024 }
2025 
2026 LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid)
2027 {
2028  JackGlobals::CheckContext("jack_reserve_client_name");
2029 
2030  JackClient* client = (JackClient*)ext_client;
2031  jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client);
2032  if (client == NULL) {
2033  jack_error("jack_reserve_client_name called with a NULL client");
2034  return -1;
2035  } else {
2036  return client->ReserveClientName(client_name, uuid);
2037  }
2038 }
2039 
2041 {
2042  JackGlobals::CheckContext("jack_session_commands_free");
2043 
2044 
2045  if (!cmds) {
2046  return;
2047  }
2048 
2049  int i = 0;
2050  while (1) {
2051  if (cmds[i].client_name) {
2052  free ((char *)cmds[i].client_name);
2053  }
2054  if (cmds[i].command) {
2055  free ((char *)cmds[i].command);
2056  }
2057  if (cmds[i].uuid) {
2058  free ((char *)cmds[i].uuid);
2059  } else {
2060  break;
2061  }
2062 
2063  i += 1;
2064  }
2065 
2066  free(cmds);
2067 }
2068 
2069 LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name)
2070 {
2071  JackGlobals::CheckContext("jack_client_has_session_callback");
2072 
2073  JackClient* client = (JackClient*)ext_client;
2074  jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client);
2075  if (client == NULL) {
2076  jack_error("jack_client_has_session_callback called with a NULL client");
2077  return -1;
2078  } else {
2079  return client->ClientHasSessionCallback(client_name);
2080  }
2081 }
2082 
2083 LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t, const char*, const char*, const char*)
2084 {
2085  return -1;
2086 }
2087 
2088 LIB_EXPORT int jack_get_property(jack_uuid_t, const char*, char**, char**)
2089 {
2090  return -1;
2091 }
2092 
2094 {
2095 }
2096 
2097 LIB_EXPORT int jack_get_properties(jack_uuid_t, jack_description_t*)
2098 {
2099  return -1;
2100 }
2101 
2103 {
2104  return -1;
2105 }
2106 
2107 LIB_EXPORT int jack_remove_property(jack_client_t*, jack_uuid_t, const char*)
2108 {
2109  return -1;
2110 }
2111 
2112 LIB_EXPORT int jack_remove_properties(jack_client_t*, jack_uuid_t)
2113 {
2114  return -1;
2115 }
2116 
2117 LIB_EXPORT int jack_remove_all_properties(jack_client_t*)
2118 {
2119  return -1;
2120 }
2121 
2122 LIB_EXPORT int jack_set_property_change_callback(jack_client_t*, JackPropertyChangeCallback, void*)
2123 {
2124  return -1;
2125 }
2126 
2127 LIB_EXPORT jack_uuid_t jack_client_uuid_generate()
2128 {
2129  return 0;
2130 }
2131 
2132 LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t)
2133 {
2134  return 0;
2135 }
2136 
2137 LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t)
2138 {
2139  return 0;
2140 }
2141 
2142 LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t)
2143 {
2144  return 0;
2145 }
2146 
2147 LIB_EXPORT void jack_uuid_copy(jack_uuid_t*, jack_uuid_t)
2148 {
2149 }
2150 
2151 LIB_EXPORT void jack_uuid_clear(jack_uuid_t*)
2152 {
2153 }
2154 
2155 LIB_EXPORT int jack_uuid_parse(const char*, jack_uuid_t*)
2156 {
2157  return 0;
2158 }
2159 
2160 LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE])
2161 {
2162 }
2163 
2164 LIB_EXPORT int jack_uuid_empty(jack_uuid_t)
2165 {
2166  return 0;
2167 }