Jack2: JackControlAPI.cpp Source File

Jack2 1.9.12

JackControlAPI.cpp
1 // u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */
2 /*
3 JACK control API implementation
4
5 Copyright (C) 2008 Nedko Arnaudov
6 Copyright (C) 2008 Grame
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23 #ifndef WIN32
24 #include <stdint.h>
25 #include <dirent.h>
26 #include <pthread.h>
27 #endif
28
29 #include "types.h"
30 #include <string.h>
31 #include <errno.h>
32 #include <stdio.h>
33 #include <assert.h>
34 #include <signal.h>
35
36 #include "jslist.h"
37 #include "driver_interface.h"
38 #include "JackError.h"
39 #include "JackServer.h"
40 #include "shm.h"
41 #include "JackTools.h"
42 #include "JackControlAPI.h"
43 #include "JackLockedEngine.h"
44 #include "JackConstants.h"
45 #include "JackDriverLoader.h"
46 #include "JackServerGlobals.h"
47
48 using namespace Jack;
49
50 /* JackEngine::CheckPortsConnect() has some assumptions about char values */
51 static struct jack_constraint_enum_char_descriptor self_connect_mode_constraint_descr_array[] =
52 {
53 { ' ', "Don't restrict self connect requests" },
54 { 'E', "Fail self connect requests to external ports only" },
55 { 'e', "Ignore self connect requests to external ports only" },
56 { 'A', "Fail all self connect requests" },
57 { 'a', "Ignore all self connect requests" },
58 { 0 }
59 };
60
61 struct jackctl_server
62 {
63 JSList * drivers;
64 JSList * internals;
65 JSList * parameters;
66
67 class JackServer * engine;
68
69 /* string, server name */
70 union jackctl_parameter_value name;
71 union jackctl_parameter_value default_name;
72
73 /* bool, whether to be "realtime" */
74 union jackctl_parameter_value realtime;
75 union jackctl_parameter_value default_realtime;
76
77 /* int32_t */
78 union jackctl_parameter_value realtime_priority;
79 union jackctl_parameter_value default_realtime_priority;
80
81 /* bool, whether to exit once all clients have closed their connections */
82 union jackctl_parameter_value temporary;
83 union jackctl_parameter_value default_temporary;
84
85 /* bool, whether to be verbose */
86 union jackctl_parameter_value verbose;
87 union jackctl_parameter_value default_verbose;
88
89 /* int32_t, msecs; if zero, use period size. */
90 union jackctl_parameter_value client_timeout;
91 union jackctl_parameter_value default_client_timeout;
92
93 /* uint32_t, clock source type */
94 union jackctl_parameter_value clock_source;
95 union jackctl_parameter_value default_clock_source;
96
97 /* uint32_t, max port number */
98 union jackctl_parameter_value port_max;
99 union jackctl_parameter_value default_port_max;
100
101 /* bool */
102 union jackctl_parameter_value replace_registry;
103 union jackctl_parameter_value default_replace_registry;
104
105 /* bool, synchronous or asynchronous engine mode */
106 union jackctl_parameter_value sync;
107 union jackctl_parameter_value default_sync;
108
109 /* char enum, self connect mode mode */
110 union jackctl_parameter_value self_connect_mode;
111 union jackctl_parameter_value default_self_connect_mode;
112 };
113
114 struct jackctl_driver
115 {
116 jack_driver_desc_t * desc_ptr;
117 JSList * parameters;
118 JSList * infos;
119 };
120
121 struct jackctl_internal
122 {
123 jack_driver_desc_t * desc_ptr;
124 JSList * parameters;
125 int refnum;
126 };
127
128 struct jackctl_parameter
129 {
130 const char * name;
131 const char * short_description;
132 const char * long_description;
133 jackctl_param_type_t type;
134 bool is_set;
135 union jackctl_parameter_value * value_ptr;
136 union jackctl_parameter_value * default_value_ptr;
137
138 union jackctl_parameter_value value;
139 union jackctl_parameter_value default_value;
140 struct jackctl_driver * driver_ptr;
141 char id;
142 jack_driver_param_constraint_desc_t * constraint_ptr;
143 };
144
145 const char * jack_get_self_connect_mode_description(char mode)
146 {
147 struct jack_constraint_enum_char_descriptor * descr_ptr;
148
149 for (descr_ptr = self_connect_mode_constraint_descr_array;
150 descr_ptr->value;
151 descr_ptr++)
152 if (descr_ptr->value == mode) return descr_ptr->short_desc;
153
154 return NULL;
155 }
156
157 static
158 struct jackctl_parameter *
159 jackctl_add_parameter(
160 JSList ** parameters_list_ptr_ptr,
161 const char * name,
162 const char * short_description,
163 const char * long_description,
164 jackctl_param_type_t type,
165 union jackctl_parameter_value * value_ptr,
166 union jackctl_parameter_value * default_value_ptr,
167 union jackctl_parameter_value value,
168 jack_driver_param_constraint_desc_t * constraint_ptr = NULL)
169 {
170 struct jackctl_parameter * parameter_ptr;
171
172 parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter));
173 if (parameter_ptr == NULL)
174 {
175 jack_error("Cannot allocate memory for jackctl_parameter structure.");
176 goto fail;
177 }
178
179 parameter_ptr->name = name;
180 parameter_ptr->short_description = short_description;
181 parameter_ptr->long_description = long_description;
182 parameter_ptr->type = type;
183 parameter_ptr->is_set = false;
184
185 if (value_ptr == NULL)
186 {
187 value_ptr = &parameter_ptr->value;
188 }
189
190 if (default_value_ptr == NULL)
191 {
192 default_value_ptr = &parameter_ptr->default_value;
193 }
194
195 parameter_ptr->value_ptr = value_ptr;
196 parameter_ptr->default_value_ptr = default_value_ptr;
197
198 *value_ptr = *default_value_ptr = value;
199
200 parameter_ptr->driver_ptr = NULL;
201 parameter_ptr->id = 0;
202 parameter_ptr->constraint_ptr = constraint_ptr;
203
204 *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr);
205
206 return parameter_ptr;
207
208 fail:
209 return NULL;
210 }
211
212 static
213 void
214 jackctl_free_driver_parameters(
215 struct jackctl_driver * driver_ptr)
216 {
217 JSList * next_node_ptr;
218
219 while (driver_ptr->parameters)
220 {
221 next_node_ptr = driver_ptr->parameters->next;
222 free(driver_ptr->parameters->data);
223 free(driver_ptr->parameters);
224 driver_ptr->parameters = next_node_ptr;
225 }
226 }
227
228 static
229 bool
230 jackctl_add_driver_parameters(
231 struct jackctl_driver * driver_ptr)
232 {
233 unsigned int i;
234
235 union jackctl_parameter_value jackctl_value;
236 jackctl_param_type_t jackctl_type;
237 struct jackctl_parameter * parameter_ptr;
238 jack_driver_param_desc_t * descriptor_ptr;
239
240 for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++)
241 {
242 descriptor_ptr = driver_ptr->desc_ptr->params + i;
243
244 switch (descriptor_ptr->type)
245 {
246 case JackDriverParamInt:
247 jackctl_type = JackParamInt;
248 jackctl_value.i = descriptor_ptr->value.i;
249 break;
250 case JackDriverParamUInt:
251 jackctl_type = JackParamUInt;
252 jackctl_value.ui = descriptor_ptr->value.ui;
253 break;
254 case JackDriverParamChar:
255 jackctl_type = JackParamChar;
256 jackctl_value.c = descriptor_ptr->value.c;
257 break;
258 case JackDriverParamString:
259 jackctl_type = JackParamString;
260 strcpy(jackctl_value.str, descriptor_ptr->value.str);
261 break;
262 case JackDriverParamBool:
263 jackctl_type = JackParamBool;
264 jackctl_value.b = descriptor_ptr->value.i;
265 break;
266 default:
267 jack_error("Unknown driver parameter type %i", (int)descriptor_ptr->type);
268 assert(0);
269 goto fail;
270 }
271
272 parameter_ptr = jackctl_add_parameter(
273 &driver_ptr->parameters,
274 descriptor_ptr->name,
275 descriptor_ptr->short_desc,
276 descriptor_ptr->long_desc,
277 jackctl_type,
278 NULL,
279 NULL,
280 jackctl_value,
281 descriptor_ptr->constraint);
282
283 if (parameter_ptr == NULL)
284 {
285 goto fail;
286 }
287
288 parameter_ptr->driver_ptr = driver_ptr;
289 parameter_ptr->id = descriptor_ptr->character;
290 }
291
292 return true;
293
294 fail:
295 jackctl_free_driver_parameters(driver_ptr);
296
297 return false;
298 }
299
300 /* destroy jack_driver_param_desc_t list created by jackctl_create_param_list() */
301 static void
302 jackctl_destroy_param_list(
303 JSList * params)
304 {
305 JSList * next;
306
307 while (params)
308 {
309 next = params->next;
310 free(params->data);
311 free(params);
312 params = next;
313 }
314 }
315
316 /* for drivers and internals are configured through jack_driver_param_t JSList */
317 /* this function creates such list from a jackctl_parameter list */
318 static
319 bool
320 jackctl_create_param_list(
321 const JSList * paramlist,
322 JSList ** retparamlist)
323 {
324 jackctl_parameter * param_ptr;
325 jack_driver_param_t * retparam_ptr;
326
327 *retparamlist = NULL;
328 while (paramlist != NULL)
329 {
330 param_ptr = (jackctl_parameter *)paramlist->data;
331 if (param_ptr->is_set)
332 {
333 /* jack_info("setting driver parameter %p ...", parameter_ptr); */
334 retparam_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
335 if (retparam_ptr == NULL)
336 {
337 jack_error ("Allocation of jack_driver_param_t structure failed");
338 goto destroy;
339 }
340
341 retparam_ptr->character = param_ptr->id;
342
343 switch (param_ptr->type)
344 {
345 case JackParamInt:
346 retparam_ptr->value.i = param_ptr->value_ptr->i;
347 break;
348 case JackParamUInt:
349 retparam_ptr->value.ui = param_ptr->value_ptr->ui;
350 break;
351 case JackParamChar:
352 retparam_ptr->value.c = param_ptr->value_ptr->c;
353 break;
354 case JackParamString:
355 strcpy(retparam_ptr->value.str, param_ptr->value_ptr->str);
356 break;
357 case JackParamBool:
358 retparam_ptr->value.i = param_ptr->value_ptr->b;
359 break;
360 default:
361 jack_error("Unknown parameter type %i", (int)param_ptr->type);
362 assert(0);
363 goto free;
364 }
365
366 *retparamlist = jack_slist_append(*retparamlist, retparam_ptr);
367 }
368
369 paramlist = paramlist->next;
370 }
371
372 return true;
373
374 free:
375 free(retparam_ptr);
376 destroy:
377 jackctl_destroy_param_list(*retparamlist);
378 return false;
379 }
380
381 static int
382 jackctl_drivers_load(
383 struct jackctl_server * server_ptr)
384 {
385 struct jackctl_driver * driver_ptr;
386 JSList *node_ptr;
387 JSList *descriptor_node_ptr;
388
389 descriptor_node_ptr = jack_drivers_load(NULL);
390 if (descriptor_node_ptr == NULL)
391 {
392 jack_error("Could not find any drivers in driver directory!");
393 return false;
394 }
395
396 while (descriptor_node_ptr != NULL)
397 {
398 driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver));
399 if (driver_ptr == NULL)
400 {
401 jack_error("Memory allocation of jackctl_driver structure failed.");
402 goto next;
403 }
404
405 driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
406 driver_ptr->parameters = NULL;
407 driver_ptr->infos = NULL;
408
409 if (!jackctl_add_driver_parameters(driver_ptr))
410 {
411 assert(driver_ptr->parameters == NULL);
412 free(driver_ptr);
413 goto next;
414 }
415
416 server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr);
417
418 next:
419 node_ptr = descriptor_node_ptr;
420 descriptor_node_ptr = descriptor_node_ptr->next;
421 free(node_ptr);
422 }
423
424 return true;
425 }
426
427 static
428 void
429 jackctl_server_free_drivers(
430 struct jackctl_server * server_ptr)
431 {
432 JSList * next_node_ptr;
433 struct jackctl_driver * driver_ptr;
434
435 while (server_ptr->drivers)
436 {
437 next_node_ptr = server_ptr->drivers->next;
438 driver_ptr = (struct jackctl_driver *)server_ptr->drivers->data;
439
440 jackctl_free_driver_parameters(driver_ptr);
441 free(driver_ptr->desc_ptr->params);
442 free(driver_ptr->desc_ptr);
443 free(driver_ptr);
444
445 free(server_ptr->drivers);
446 server_ptr->drivers = next_node_ptr;
447 }
448 }
449
450 static int
451 jackctl_internals_load(
452 struct jackctl_server * server_ptr)
453 {
454 struct jackctl_internal * internal_ptr;
455 JSList *node_ptr;
456 JSList *descriptor_node_ptr;
457
458 descriptor_node_ptr = jack_internals_load(NULL);
459 if (descriptor_node_ptr == NULL)
460 {
461 jack_error("Could not find any internals in driver directory!");
462 return false;
463 }
464
465 while (descriptor_node_ptr != NULL)
466 {
467 internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal));
468 if (internal_ptr == NULL)
469 {
470 jack_error("Memory allocation of jackctl_driver structure failed.");
471 goto next;
472 }
473
474 internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data;
475 internal_ptr->parameters = NULL;
476 internal_ptr->refnum = -1;
477
478 if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr))
479 {
480 assert(internal_ptr->parameters == NULL);
481 free(internal_ptr);
482 goto next;
483 }
484
485 server_ptr->internals = jack_slist_append(server_ptr->internals, internal_ptr);
486
487 next:
488 node_ptr = descriptor_node_ptr;
489 descriptor_node_ptr = descriptor_node_ptr->next;
490 free(node_ptr);
491 }
492
493 return true;
494 }
495
496 static
497 void
498 jackctl_server_free_internals(
499 struct jackctl_server * server_ptr)
500 {
501 JSList * next_node_ptr;
502 struct jackctl_internal * internal_ptr;
503
504 while (server_ptr->internals)
505 {
506 next_node_ptr = server_ptr->internals->next;
507 internal_ptr = (struct jackctl_internal *)server_ptr->internals->data;
508
509 jackctl_free_driver_parameters((struct jackctl_driver *)internal_ptr);
510 free(internal_ptr->desc_ptr->params);
511 free(internal_ptr->desc_ptr);
512 free(internal_ptr);
513
514 free(server_ptr->internals);
515 server_ptr->internals = next_node_ptr;
516 }
517 }
518
519 static
520 void
521 jackctl_server_free_parameters(
522 struct jackctl_server * server_ptr)
523 {
524 JSList * next_node_ptr;
525
526 while (server_ptr->parameters)
527 {
528 next_node_ptr = server_ptr->parameters->next;
529 free(server_ptr->parameters->data);
530 free(server_ptr->parameters);
531 server_ptr->parameters = next_node_ptr;
532 }
533 }
534
535 #ifdef WIN32
536
537 struct jackctl_sigmask
538 {
539 HANDLE wait_event;
540 };
541
542 static jackctl_sigmask sigmask;
543
544 static void signal_handler(int signum)
545 {
546 printf("Jack main caught signal %d\n", signum);
547 (void) signal(SIGINT, SIG_DFL);
548 SetEvent(sigmask.wait_event);
549 }
550
551 jackctl_sigmask_t *
552 jackctl_setup_signals(
553 unsigned int flags)
554 {
555 if ((sigmask.wait_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
556 jack_error("CreateEvent fails err = %ld", GetLastError());
557 return 0;
558 }
559
560 (void) signal(SIGINT, signal_handler);
561 (void) signal(SIGABRT, signal_handler);
562 (void) signal(SIGTERM, signal_handler);
563
564 return &sigmask;
565 }
566
567 void jackctl_wait_signals(jackctl_sigmask_t * signals)
568 {
569 if (WaitForSingleObject(signals->wait_event, INFINITE) != WAIT_OBJECT_0) {
570 jack_error("WaitForSingleObject fails err = %ld", GetLastError());
571 }
572 }
573
574 #else
575
576 struct jackctl_sigmask
577 {
578 sigset_t signals;
579 };
580
581 static jackctl_sigmask sigmask;
582
583 static
584 void
585 signal_handler(int sig)
586 {
587 /* this is used by the child (active) process, but it never
588 gets called unless we are already shutting down after
589 another signal.
590 */
591 char buf[64];
592 snprintf(buf, sizeof(buf), "Received signal %d during shutdown (ignored)\n", sig);
593 }
594
595 SERVER_EXPORT jackctl_sigmask_t *
596 jackctl_setup_signals(
597 unsigned int flags)
598 {
599 sigset_t allsignals;
600 struct sigaction action;
601 int i;
602
603 /* ensure that we are in our own process group so that
604 kill (SIG, -pgrp) does the right thing.
605 */
606
607 setsid();
608
609 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
610
611 /* what's this for?
612
613 POSIX says that signals are delivered like this:
614
615 * if a thread has blocked that signal, it is not
616 a candidate to receive the signal.
617 * of all threads not blocking the signal, pick
618 one at random, and deliver the signal.
619
620 this means that a simple-minded multi-threaded program can
621 expect to get POSIX signals delivered randomly to any one
622 of its threads,
623
624 here, we block all signals that we think we might receive
625 and want to catch. all "child" threads will inherit this
626 setting. if we create a thread that calls sigwait() on the
627 same set of signals, implicitly unblocking all those
628 signals. any of those signals that are delivered to the
629 process will be delivered to that thread, and that thread
630 alone. this makes cleanup for a signal-driven exit much
631 easier, since we know which thread is doing it and more
632 importantly, we are free to call async-unsafe functions,
633 because the code is executing in normal thread context
634 after a return from sigwait().
635 */
636
637 sigemptyset(&sigmask.signals);
638 sigaddset(&sigmask.signals, SIGHUP);
639 sigaddset(&sigmask.signals, SIGINT);
640 sigaddset(&sigmask.signals, SIGQUIT);
641 sigaddset(&sigmask.signals, SIGPIPE);
642 sigaddset(&sigmask.signals, SIGTERM);
643 #ifndef __ANDROID__
644 /* android's bionic c doesn't provide pthread_cancel() and related functions.
645 * to solve this issue, use pthread_kill() & SIGUSR1 instead.
646 */
647 sigaddset(&sigmask.signals, SIGUSR1);
648 #endif
649 sigaddset(&sigmask.signals, SIGUSR2);
650
651 /* all child threads will inherit this mask unless they
652 * explicitly reset it
653 */
654
655 pthread_sigmask(SIG_BLOCK, &sigmask.signals, 0);
656
657 /* install a do-nothing handler because otherwise pthreads
658 behaviour is undefined when we enter sigwait.
659 */
660
661 sigfillset(&allsignals);
662 action.sa_handler = signal_handler;
663 action.sa_mask = allsignals;
664 action.sa_flags = SA_RESTART|SA_RESETHAND;
665
666 for (i = 1; i < NSIG; i++)
667 {
668 if (sigismember (&sigmask.signals, i))
669 {
670 sigaction(i, &action, 0);
671 }
672 }
673
674 return &sigmask;
675 }
676
677 SERVER_EXPORT void
678 jackctl_wait_signals(jackctl_sigmask_t * sigmask)
679 {
680 int sig;
681 bool waiting = true;
682
683 while (waiting) {
684 #if defined(sun) && !defined(__sun__) // SUN compiler only, to check
685 sigwait(&sigmask->signals);
686 #else
687 sigwait(&sigmask->signals, &sig);
688 #endif
689 fprintf(stderr, "Jack main caught signal %d\n", sig);
690
691 switch (sig) {
692 case SIGUSR1:
693 //jack_dump_configuration(engine, 1);
694 break;
695 case SIGUSR2:
696 // driver exit
697 waiting = false;
698 break;
699 case SIGTTOU:
700 break;
701 default:
702 waiting = false;
703 break;
704 }
705 }
706
707 if (sig != SIGSEGV) {
708 // unblock signals so we can see them during shutdown.
709 // this will help prod developers not to lose sight of
710 // bugs that cause segfaults etc. during shutdown.
711 sigprocmask(SIG_UNBLOCK, &sigmask->signals, 0);
712 }
713 }
714 #endif
715
716 static
717 jack_driver_param_constraint_desc_t *
718 get_realtime_priority_constraint()
719 {
720 jack_driver_param_constraint_desc_t * constraint_ptr;
721 int min, max;
722
723 if (!jack_get_thread_realtime_priority_range(&min, &max))
724 {
725 return NULL;
726 }
727
728 //jack_info("realtime priority range is (%d,%d)", min, max);
729
730 constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_constraint_desc_t));
731 if (constraint_ptr == NULL)
732 {
733 jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure.");
734 return NULL;
735 }
736 constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE;
737
738 constraint_ptr->constraint.range.min.i = min;
739 constraint_ptr->constraint.range.max.i = max;
740
741 return constraint_ptr;
742 }
743
744 SERVER_EXPORT jackctl_server_t * jackctl_server_create(
745 bool (* on_device_acquire)(const char * device_name),
746 void (* on_device_release)(const char * device_name))
747 {
748 struct jackctl_server * server_ptr;
749 union jackctl_parameter_value value;
750
751 server_ptr = (struct jackctl_server *)malloc(sizeof(struct jackctl_server));
752 if (server_ptr == NULL)
753 {
754 jack_error("Cannot allocate memory for jackctl_server structure.");
755 goto fail;
756 }
757
758 server_ptr->drivers = NULL;
759 server_ptr->internals = NULL;
760 server_ptr->parameters = NULL;
761 server_ptr->engine = NULL;
762
763 strcpy(value.str, JackTools::DefaultServerName());
764 if (jackctl_add_parameter(
765 &server_ptr->parameters,
766 "name",
767 "Server name to use.",
768 "",
769 JackParamString,
770 &server_ptr->name,
771 &server_ptr->default_name,
772 value) == NULL)
773 {
774 goto fail_free_parameters;
775 }
776
777 value.b = true;
778 if (jackctl_add_parameter(
779 &server_ptr->parameters,
780 "realtime",
781 "Whether to use realtime mode.",
782 "Use realtime scheduling. This is needed for reliable low-latency performance. On most systems, it requires JACK to run with special scheduler and memory allocation privileges, which may be obtained in several ways. On Linux you should use PAM.",
783 JackParamBool,
784 &server_ptr->realtime,
785 &server_ptr->default_realtime,
786 value) == NULL)
787 {
788 goto fail_free_parameters;
789 }
790
791 value.i = 10;
792 if (jackctl_add_parameter(
793 &server_ptr->parameters,
794 "realtime-priority",
795 "Scheduler priority when running in realtime mode.",
796 "",
797 JackParamInt,
798 &server_ptr->realtime_priority,
799 &server_ptr->default_realtime_priority,
800 value,
801 get_realtime_priority_constraint()) == NULL)
802 {
803 goto fail_free_parameters;
804 }
805
806 value.b = false;
807 if (jackctl_add_parameter(
808 &server_ptr->parameters,
809 "temporary",
810 "Exit once all clients have closed their connections.",
811 "",
812 JackParamBool,
813 &server_ptr->temporary,
814 &server_ptr->default_temporary,
815 value) == NULL)
816 {
817 goto fail_free_parameters;
818 }
819
820 value.b = false;
821 if (jackctl_add_parameter(
822 &server_ptr->parameters,
823 "verbose",
824 "Verbose mode.",
825 "",
826 JackParamBool,
827 &server_ptr->verbose,
828 &server_ptr->default_verbose,
829 value) == NULL)
830 {
831 goto fail_free_parameters;
832 }
833
834 value.i = 0;
835 if (jackctl_add_parameter(
836 &server_ptr->parameters,
837 "client-timeout",
838 "Client timeout limit in milliseconds.",
839 "",
840 JackParamInt,
841 &server_ptr->client_timeout,
842 &server_ptr->default_client_timeout,
843 value) == NULL)
844 {
845 goto fail_free_parameters;
846 }
847
848 value.ui = 0;
849 if (jackctl_add_parameter(
850 &server_ptr->parameters,
851 "clock-source",
852 "Clocksource type : c(ycle) | h(pet) | s(ystem).",
853 "",
854 JackParamUInt,
855 &server_ptr->clock_source,
856 &server_ptr->default_clock_source,
857 value) == NULL)
858 {
859 goto fail_free_parameters;
860 }
861
862 value.ui = PORT_NUM;
863 if (jackctl_add_parameter(
864 &server_ptr->parameters,
865 "port-max",
866 "Maximum number of ports.",
867 "",
868 JackParamUInt,
869 &server_ptr->port_max,
870 &server_ptr->default_port_max,
871 value) == NULL)
872 {
873 goto fail_free_parameters;
874 }
875
876 value.b = false;
877 if (jackctl_add_parameter(
878 &server_ptr->parameters,
879 "replace-registry",
880 "Replace shared memory registry.",
881 "",
882 JackParamBool,
883 &server_ptr->replace_registry,
884 &server_ptr->default_replace_registry,
885 value) == NULL)
886 {
887 goto fail_free_parameters;
888 }
889
890 value.b = false;
891 if (jackctl_add_parameter(
892 &server_ptr->parameters,
893 "sync",
894 "Use server synchronous mode.",
895 "",
896 JackParamBool,
897 &server_ptr->sync,
898 &server_ptr->default_sync,
899 value) == NULL)
900 {
901 goto fail_free_parameters;
902 }
903
904 value.c = JACK_DEFAULT_SELF_CONNECT_MODE;
905 if (jackctl_add_parameter(
906 &server_ptr->parameters,
907 "self-connect-mode",
908 "Self connect mode.",
909 "Whether JACK clients are allowed to connect their own ports",
910 JackParamChar,
911 &server_ptr->self_connect_mode,
912 &server_ptr->default_self_connect_mode,
913 value,
914 jack_constraint_compose_enum_char(
915 JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE,
916 self_connect_mode_constraint_descr_array)) == NULL)
917 {
918 goto fail_free_parameters;
919 }
920
921 JackServerGlobals::on_device_acquire = on_device_acquire;
922 JackServerGlobals::on_device_release = on_device_release;
923
924 if (!jackctl_drivers_load(server_ptr))
925 {
926 goto fail_free_parameters;
927 }
928
929 /* Allowed to fail */
930 jackctl_internals_load(server_ptr);
931
932 return server_ptr;
933
934 fail_free_parameters:
935 jackctl_server_free_parameters(server_ptr);
936
937 free(server_ptr);
938
939 fail:
940 return NULL;
941 }
942
943 SERVER_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
944 {
945 if (server_ptr) {
946 jackctl_server_free_drivers(server_ptr);
947 jackctl_server_free_internals(server_ptr);
948 jackctl_server_free_parameters(server_ptr);
949 free(server_ptr);
950 }
951 }
952
953 SERVER_EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr)
954 {
955 return (server_ptr) ? server_ptr->drivers : NULL;
956 }
957
958 SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
959 {
960 if (server_ptr) {
961 server_ptr->engine->Stop();
962 return true;
963 } else {
964 return false;
965 }
966 }
967
968 SERVER_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
969 {
970 if (server_ptr) {
971 server_ptr->engine->Close();
972 delete server_ptr->engine;
973
974 /* clean up shared memory and files from this server instance */
975 jack_log("Cleaning up shared memory");
976
977 jack_cleanup_shm();
978
979 jack_log("Cleaning up files");
980
981 JackTools::CleanupFiles(server_ptr->name.str);
982
983 jack_log("Unregistering server `%s'", server_ptr->name.str);
984
985 jack_unregister_server(server_ptr->name.str);
986
987 server_ptr->engine = NULL;
988
989 return true;
990 } else {
991 return false;
992 }
993 }
994
995 SERVER_EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr)
996 {
997 return (server_ptr) ? server_ptr->parameters : NULL;
998 }
999
1000 SERVER_EXPORT bool
1001 jackctl_server_open(
1002 jackctl_server *server_ptr,
1003 jackctl_driver *driver_ptr)
1004 {
1005 JSList * paramlist = NULL;
1006
1007 try {
1008
1009 if (!server_ptr || !driver_ptr) {
1010 return false;
1011 }
1012
1013 int rc = jack_register_server(server_ptr->name.str, server_ptr->replace_registry.b);
1014 switch (rc)
1015 {
1016 case EEXIST:
1017 jack_error("`%s' server already active", server_ptr->name.str);
1018 goto fail;
1019 case ENOSPC:
1020 jack_error("Too many servers already active");
1021 goto fail;
1022 case ENOMEM:
1023 jack_error("No access to shm registry");
1024 goto fail;
1025 }
1026
1027 jack_log("Server `%s' registered", server_ptr->name.str);
1028
1029 /* clean up shared memory and files from any previous
1030 * instance of this server name */
1031 jack_cleanup_shm();
1032 JackTools::CleanupFiles(server_ptr->name.str);
1033
1034 if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) {
1035 server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */
1036 }
1037
1038 /* check port max value before allocating server */
1039 if (server_ptr->port_max.ui > PORT_NUM_MAX) {
1040 jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX);
1041 goto fail;
1042 }
1043
1044 /* get the engine/driver started */
1045 server_ptr->engine = new JackServer(
1046 server_ptr->sync.b,
1047 server_ptr->temporary.b,
1048 server_ptr->client_timeout.i,
1049 server_ptr->realtime.b,
1050 server_ptr->realtime_priority.i,
1051 server_ptr->port_max.ui,
1052 server_ptr->verbose.b,
1053 (jack_timer_type_t)server_ptr->clock_source.ui,
1054 server_ptr->self_connect_mode.c,
1055 server_ptr->name.str);
1056 if (server_ptr->engine == NULL)
1057 {
1058 jack_error("Failed to create new JackServer object");
1059 goto fail_unregister;
1060 }
1061
1062 if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) goto fail_delete;
1063 rc = server_ptr->engine->Open(driver_ptr->desc_ptr, paramlist);
1064 jackctl_destroy_param_list(paramlist);
1065 if (rc < 0)
1066 {
1067 jack_error("JackServer::Open failed with %d", rc);
1068 goto fail_delete;
1069 }
1070
1071 return true;
1072
1073 } catch (std::exception e) {
1074 jack_error("jackctl_server_open error...");
1075 jackctl_destroy_param_list(paramlist);
1076 }
1077
1078 fail_delete:
1079 delete server_ptr->engine;
1080 server_ptr->engine = NULL;
1081
1082 fail_unregister:
1083 jack_log("Cleaning up shared memory");
1084
1085 jack_cleanup_shm();
1086
1087 jack_log("Cleaning up files");
1088
1089 JackTools::CleanupFiles(server_ptr->name.str);
1090
1091 jack_log("Unregistering server `%s'", server_ptr->name.str);
1092
1093 jack_unregister_server(server_ptr->name.str);
1094
1095 fail:
1096 return false;
1097 }
1098
1099 SERVER_EXPORT bool
1100 jackctl_server_start(
1101 jackctl_server *server_ptr)
1102 {
1103 if (!server_ptr) {
1104 return false;
1105 } else {
1106 int rc = server_ptr->engine->Start();
1107 bool result = rc >= 0;
1108 if (! result)
1109 {
1110 jack_error("JackServer::Start() failed with %d", rc);
1111 }
1112 return result;
1113 }
1114 }
1115
1116 SERVER_EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr)
1117 {
1118 return (driver_ptr) ? driver_ptr->desc_ptr->name : NULL;
1119 }
1120
1121 SERVER_EXPORT jackctl_driver_type_t jackctl_driver_get_type(jackctl_driver *driver_ptr)
1122 {
1123 return (driver_ptr) ? (jackctl_driver_type_t)driver_ptr->desc_ptr->type : (jackctl_driver_type_t)0;
1124 }
1125
1126 SERVER_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
1127 {
1128 return (driver_ptr) ? driver_ptr->parameters : NULL;
1129 }
1130
1131 SERVER_EXPORT jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver *driver_ptr)
1132 {
1133 return (driver_ptr) ? driver_ptr->desc_ptr : NULL;
1134 }
1135
1136 SERVER_EXPORT const char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr)
1137 {
1138 return (parameter_ptr) ? parameter_ptr->name : NULL;
1139 }
1140
1141 SERVER_EXPORT const char * jackctl_parameter_get_short_description(jackctl_parameter *parameter_ptr)
1142 {
1143 return (parameter_ptr) ? parameter_ptr->short_description : NULL;
1144 }
1145
1146 SERVER_EXPORT const char * jackctl_parameter_get_long_description(jackctl_parameter *parameter_ptr)
1147 {
1148 return (parameter_ptr) ? parameter_ptr->long_description : NULL;
1149 }
1150
1151 SERVER_EXPORT bool jackctl_parameter_has_range_constraint(jackctl_parameter *parameter_ptr)
1152 {
1153 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0) : false;
1154 }
1155
1156 SERVER_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *parameter_ptr)
1157 {
1158 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0): false;
1159 }
1160
1161 SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
1162 {
1163 if (!parameter_ptr) {
1164 return 0;
1165 }
1166
1167 if (!jackctl_parameter_has_enum_constraint(parameter_ptr))
1168 {
1169 return 0;
1170 }
1171
1172 return parameter_ptr->constraint_ptr->constraint.enumeration.count;
1173 }
1174
1175 SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index)
1176 {
1177 jack_driver_param_value_t * value_ptr;
1178 union jackctl_parameter_value jackctl_value;
1179
1180 if (!parameter_ptr) {
1181 memset(&jackctl_value, 0, sizeof(jackctl_value));
1182 return jackctl_value;
1183 }
1184
1185 value_ptr = &parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].value;
1186
1187 switch (parameter_ptr->type)
1188 {
1189 case JackParamInt:
1190 jackctl_value.i = value_ptr->i;
1191 break;
1192 case JackParamUInt:
1193 jackctl_value.ui = value_ptr->ui;
1194 break;
1195 case JackParamChar:
1196 jackctl_value.c = value_ptr->c;
1197 break;
1198 case JackParamString:
1199 strcpy(jackctl_value.str, value_ptr->str);
1200 break;
1201 default:
1202 jack_error("Bad driver parameter type %i (enum constraint)", (int)parameter_ptr->type);
1203 assert(0);
1204 }
1205
1206 return jackctl_value;
1207 }
1208
1209 SERVER_EXPORT const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index)
1210 {
1211 return (parameter_ptr) ? parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc : NULL;
1212 }
1213
1214 SERVER_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr)
1215 {
1216 if (!parameter_ptr || !min_ptr || !max_ptr) {
1217 return;
1218 }
1219
1220 switch (parameter_ptr->type)
1221 {
1222 case JackParamInt:
1223 min_ptr->i = parameter_ptr->constraint_ptr->constraint.range.min.i;
1224 max_ptr->i = parameter_ptr->constraint_ptr->constraint.range.max.i;
1225 return;
1226 case JackParamUInt:
1227 min_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.min.ui;
1228 max_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.max.ui;
1229 return;
1230 default:
1231 jack_error("Bad driver parameter type %i (range constraint)", (int)parameter_ptr->type);
1232 assert(0);
1233 }
1234 }
1235
1236 SERVER_EXPORT bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr)
1237 {
1238 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0) : false;
1239 }
1240
1241 SERVER_EXPORT bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr)
1242 {
1243 return (parameter_ptr) ? (parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0) : false;
1244 }
1245
1246 SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr)
1247 {
1248 return (parameter_ptr) ? parameter_ptr->type : (jackctl_param_type_t)0;
1249 }
1250
1251 SERVER_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr)
1252 {
1253 return (parameter_ptr) ? parameter_ptr->id : 0;
1254 }
1255
1256 SERVER_EXPORT bool jackctl_parameter_is_set(jackctl_parameter *parameter_ptr)
1257 {
1258 return (parameter_ptr) ? parameter_ptr->is_set : false;
1259 }
1260
1261 SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter *parameter_ptr)
1262 {
1263 if (parameter_ptr) {
1264 return *parameter_ptr->value_ptr;
1265 } else {
1266 union jackctl_parameter_value jackctl_value;
1267 memset(&jackctl_value, 0, sizeof(jackctl_value));
1268 return jackctl_value;
1269 }
1270 }
1271
1272 SERVER_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
1273 {
1274 if (!parameter_ptr) {
1275 return NULL;
1276 }
1277
1278 if (!parameter_ptr->is_set)
1279 {
1280 return true;
1281 }
1282
1283 parameter_ptr->is_set = false;
1284
1285 *parameter_ptr->value_ptr = *parameter_ptr->default_value_ptr;
1286
1287 return true;
1288 }
1289
1290 SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value * value_ptr)
1291 {
1292 if (!parameter_ptr || !value_ptr) {
1293 return NULL;
1294 }
1295
1296 parameter_ptr->is_set = true;
1297 *parameter_ptr->value_ptr = *value_ptr;
1298
1299 return true;
1300 }
1301
1302 SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr)
1303 {
1304 if (parameter_ptr) {
1305 return *parameter_ptr->default_value_ptr;
1306 } else {
1307 union jackctl_parameter_value jackctl_value;
1308 memset(&jackctl_value, 0, sizeof(jackctl_value));
1309 return jackctl_value;
1310 }
1311 }
1312
1313 // Internals clients
1314
1315 SERVER_EXPORT const JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr)
1316 {
1317 return (server_ptr) ? server_ptr->internals : NULL;
1318 }
1319
1320 SERVER_EXPORT const char * jackctl_internal_get_name(jackctl_internal *internal_ptr)
1321 {
1322 return (internal_ptr) ? internal_ptr->desc_ptr->name : NULL;
1323 }
1324
1325 SERVER_EXPORT const JSList * jackctl_internal_get_parameters(jackctl_internal *internal_ptr)
1326 {
1327 return (internal_ptr) ? internal_ptr->parameters : NULL;
1328 }
1329
1330 SERVER_EXPORT bool jackctl_server_load_internal(
1331 jackctl_server * server_ptr,
1332 jackctl_internal * internal)
1333 {
1334 if (!server_ptr || !internal) {
1335 return false;
1336 }
1337
1338 int status;
1339 if (server_ptr->engine != NULL) {
1340 JSList * paramlist;
1341 if (!jackctl_create_param_list(internal->parameters, &paramlist)) return false;
1342 server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, paramlist, JackNullOption, &internal->refnum, -1, &status);
1343 jackctl_destroy_param_list(paramlist);
1344 return (internal->refnum > 0);
1345 } else {
1346 return false;
1347 }
1348 }
1349
1350 SERVER_EXPORT bool jackctl_server_unload_internal(
1351 jackctl_server * server_ptr,
1352 jackctl_internal * internal)
1353 {
1354 if (!server_ptr || !internal) {
1355 return false;
1356 }
1357
1358 int status;
1359 if (server_ptr->engine != NULL && internal->refnum > 0) {
1360 // Client object is internally kept in JackEngine, and will be deallocated in InternalClientUnload
1361 return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0);
1362 } else {
1363 return false;
1364 }
1365 }
1366
1367 SERVER_EXPORT bool jackctl_server_load_session_file(
1368 jackctl_server * server_ptr,
1369 const char * file)
1370 {
1371 if (!server_ptr || !file || !server_ptr->engine) {
1372 return false;
1373 }
1374
1375 return (server_ptr->engine->LoadInternalSessionFile(file) >= 0);
1376 }
1377
1378 SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
1379 {
1380 if (server_ptr && server_ptr->engine) {
1381 if (server_ptr->engine->IsRunning()) {
1382 jack_error("Cannot add a slave in a running server");
1383 return false;
1384 } else {
1385 JSList * paramlist;
1386 if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) return false;
1387 JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, paramlist);
1388 jackctl_destroy_param_list(paramlist);
1389 if (info) {
1390 driver_ptr->infos = jack_slist_append(driver_ptr->infos, info);
1391 return true;
1392 } else {
1393 return false;
1394 }
1395 }
1396 } else {
1397 return false;
1398 }
1399 }
1400
1401 SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
1402 {
1403 if (server_ptr && server_ptr->engine) {
1404 if (server_ptr->engine->IsRunning()) {
1405 jack_error("Cannot remove a slave from a running server");
1406 return false;
1407 } else {
1408 if (driver_ptr->infos) {
1409 JackDriverInfo* info = (JackDriverInfo*)driver_ptr->infos->data;
1410 assert(info);
1411 driver_ptr->infos = jack_slist_remove(driver_ptr->infos, info);
1412 server_ptr->engine->RemoveSlave(info);
1413 delete info;
1414 return true;
1415 } else {
1416 return false;
1417 }
1418 }
1419 } else {
1420 return false;
1421 }
1422 }
1423
1424 SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
1425 {
1426 if (server_ptr && server_ptr->engine) {
1427 JSList * paramlist;
1428 if (!jackctl_create_param_list(driver_ptr->parameters, &paramlist)) return false;
1429 bool ret = (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, paramlist) == 0);
1430 jackctl_destroy_param_list(paramlist);
1431 return ret;
1432 } else {
1433 return false;
1434 }
1435 }
1436
1437
jackctl_server_switch_master
SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1424
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
jackctl_server_unload_internal
SERVER_EXPORT bool jackctl_server_unload_internal(jackctl_server *server_ptr, jackctl_internal *internal)
Definition: JackControlAPI.cpp:1350
jackctl_driver
Definition: JackControlAPI.cpp:114
jackctl_parameter_get_long_description
const SERVER_EXPORT char * jackctl_parameter_get_long_description(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1146
jack_driver_param_desc_t::character
char character
Definition: driver_interface.h:115
jackctl_server
Definition: JackControlAPI.cpp:61
jackctl_parameter_constraint_is_strict
SERVER_EXPORT bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t *parameter_ptr)
Definition: JackControlAPI.cpp:1236
jack_driver_param_desc_t::value
jack_driver_param_value_t value
Definition: driver_interface.h:117
jackctl_driver_get_parameters
const SERVER_EXPORT JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1126
jackctl_server_close
SERVER_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:968
jackctl_parameter_get_enum_constraint_description
const SERVER_EXPORT char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index)
Definition: JackControlAPI.cpp:1209
jackctl_driver_get_type
SERVER_EXPORT jackctl_driver_type_t jackctl_driver_get_type(jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1121
JackParamString
value type is a string with max size of JACK_PARAM_STRING_MAX+1 chars
Definition: control.h:45
jackctl_parameter_constraint_is_fake_value
SERVER_EXPORT bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t *parameter_ptr)
Definition: JackControlAPI.cpp:1241
jackctl_server_add_slave
SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1378
jackctl_parameter_get_type
SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1246
jackctl_driver_get_name
const SERVER_EXPORT char * jackctl_driver_get_name(jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1116
jackctl_parameter_value::i
int32_t i
member used for JackParamInt
Definition: JackControlAPI.h:56
jackctl_server_get_drivers_list
const SERVER_EXPORT JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:953
JackDriverInfo
Definition: JackDriverInfo.h:30
jack_constraint_enum_char_descriptor
Definition: driver_interface.h:87
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jackctl_parameter_reset
SERVER_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1272
jackctl_server_get_internals_list
const SERVER_EXPORT JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:1315
jackctl_parameter_get_short_description
const SERVER_EXPORT char * jackctl_parameter_get_short_description(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1141
jackctl_parameter_set_value
SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value *value_ptr)
Definition: JackControlAPI.cpp:1290
JackParamInt
value type is a signed integer
Definition: control.h:42
jackctl_server_load_session_file
SERVER_EXPORT bool jackctl_server_load_session_file(jackctl_server *server_ptr, const char *file)
Definition: JackControlAPI.cpp:1367
jackctl_server_load_internal
SERVER_EXPORT bool jackctl_server_load_internal(jackctl_server *server_ptr, jackctl_internal *internal)
Definition: JackControlAPI.cpp:1330
JackParamChar
value type is a char
Definition: control.h:44
Jack::JackServer
The Jack server.
Definition: JackServer.h:46
jackctl_parameter_get_enum_constraint_value
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index)
Definition: JackControlAPI.cpp:1175
jackctl_server_start
SERVER_EXPORT bool jackctl_server_start(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:1100
jack_driver_param_constraint_desc_t::range
struct jack_driver_param_constraint_desc_t::@0::@1 range
jack_driver_desc_t::name
char name[JACK_DRIVER_NAME_MAX+1]
Definition: driver_interface.h:133
JackParamUInt
value type is an unsigned integer
Definition: control.h:43
jackctl_internal_get_parameters
const SERVER_EXPORT JSList * jackctl_internal_get_parameters(jackctl_internal *internal_ptr)
Definition: JackControlAPI.cpp:1325
jack_driver_desc_t::nparams
uint32_t nparams
Definition: driver_interface.h:137
jack_driver_desc_t::params
jack_driver_param_desc_t * params
Definition: driver_interface.h:138
jackctl_server_stop
SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:958
jackctl_server_destroy
SERVER_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:943
jack_driver_param_value_t
Definition: driver_interface.h:64
jackctl_internal
Definition: JackControlAPI.cpp:121
jackctl_server_get_parameters
const SERVER_EXPORT JSList * jackctl_server_get_parameters(jackctl_server *server_ptr)
Definition: JackControlAPI.cpp:995
jackctl_parameter_has_enum_constraint
SERVER_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1156
jackctl_setup_signals
SERVER_EXPORT jackctl_sigmask_t * jackctl_setup_signals(unsigned int flags)
Definition: JackControlAPI.cpp:596
jackctl_parameter_value::str
char str[JACK_PARAM_STRING_MAX+1]
member used for JackParamString
Definition: JackControlAPI.h:58
jackctl_parameter_value
Type for parameter value.
Definition: JackControlAPI.h:53
jack_driver_param_t
Definition: driver_interface.h:125
jack_driver_param_desc_t::constraint
jack_driver_param_constraint_desc_t * constraint
Definition: driver_interface.h:118
JackParamBool
value type is a boolean
Definition: control.h:46
jackctl_server_open
SERVER_EXPORT bool jackctl_server_open(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1001
jackctl_parameter_get_id
SERVER_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t *parameter_ptr)
Definition: JackControlAPI.cpp:1251
jackctl_parameter_value::b
bool b
member used for JackParamBool
Definition: JackControlAPI.h:59
jackctl_parameter_get_name
const SERVER_EXPORT char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1136
jack_driver_param_desc_t::name
char name[JACK_DRIVER_NAME_MAX+1]
Definition: driver_interface.h:114
jackctl_server_create
SERVER_EXPORT jackctl_server_t * jackctl_server_create(bool(*on_device_acquire)(const char *device_name), void(*on_device_release)(const char *device_name))
Definition: JackControlAPI.cpp:744
jackctl_server_remove_slave
SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
Definition: JackControlAPI.cpp:1401
jackctl_parameter_has_range_constraint
SERVER_EXPORT bool jackctl_parameter_has_range_constraint(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1151
jackctl_parameter_is_set
SERVER_EXPORT bool jackctl_parameter_is_set(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1256
jackctl_parameter_get_value
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1261
jack_driver_param_desc_t::short_desc
char short_desc[64]
Definition: driver_interface.h:119
jack_driver_param_constraint_desc_t
Definition: driver_interface.h:97
jackctl_wait_signals
SERVER_EXPORT void jackctl_wait_signals(jackctl_sigmask_t *sigmask)
Definition: JackControlAPI.cpp:678
jack_driver_param_constraint_desc_t::enumeration
struct jack_driver_param_constraint_desc_t::@0::@2 enumeration
jack_driver_param_desc_t::long_desc
char long_desc[1024]
Definition: driver_interface.h:120
jackctl_parameter_get_default_value
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1302
jackctl_parameter
Definition: JackControlAPI.cpp:128
jack_driver_param_desc_t::type
jack_driver_param_type_t type
Definition: driver_interface.h:116
jack_driver_param_constraint_desc_t::flags
uint32_t flags
Definition: driver_interface.h:98
jackctl_internal_get_name
const SERVER_EXPORT char * jackctl_internal_get_name(jackctl_internal *internal_ptr)
Definition: JackControlAPI.cpp:1320
jack_driver_desc_t
Definition: driver_interface.h:132
jackctl_param_type_t
jackctl_param_type_t
Definition: control.h:40
jack_driver_desc_t::type
jack_driver_type_t type
Definition: driver_interface.h:134
jackctl_parameter_value::ui
uint32_t ui
member used for JackParamUInt
Definition: JackControlAPI.h:55
_JSList
Definition: linux/alsa/jslist.h:35
jackctl_parameter_value::c
char c
member used for JackParamChar
Definition: JackControlAPI.h:57
jackctl_parameter_get_range_constraint
SERVER_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parameter_ptr, union jackctl_parameter_value *min_ptr, union jackctl_parameter_value *max_ptr)
Definition: JackControlAPI.cpp:1214
jack_driver_param_desc_t
Definition: driver_interface.h:113
jackctl_parameter_get_enum_constraints_count
SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
Definition: JackControlAPI.cpp:1161
jackctl_driver_type_t
jackctl_driver_type_t
Definition: control.h:50
jackctl_sigmask
Definition: JackControlAPI.cpp:576