21 #include "JackSystemDeps.h"    22 #include "JackDriverLoader.h"    23 #include "JackDriverInfo.h"    24 #include "JackConstants.h"    25 #include "JackError.h"    37 static char* locate_dll_driver_dir()
    39     HMODULE libjack_handle = NULL;
    40     GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
    41                       reinterpret_cast<LPCSTR>(locate_dll_driver_dir), &libjack_handle);
    44     char driver_dir_storage[512];
    45     if (3 < GetModuleFileName(libjack_handle, driver_dir_storage, 512)) {
    46         char *p = strrchr(driver_dir_storage, 
'\\');
    47         if (p && (p != driver_dir_storage)) {
    50         jack_info(
"Drivers/internals found in : %s", driver_dir_storage);
    51         strcat(driver_dir_storage, 
"/");
    52         strcat(driver_dir_storage, ADDON_DIR);
    53         return strdup(driver_dir_storage);
    55         jack_error(
"Cannot get JACK dll directory : %d", GetLastError());
    60 static char* locate_driver_dir(HANDLE& file, WIN32_FIND_DATA& filedata)
    63     char* driver_dir = locate_dll_driver_dir();
    64     char dll_filename[512];
    65     snprintf(dll_filename, 
sizeof(dll_filename), 
"%s/*.dll", driver_dir);
    66     file = (HANDLE)FindFirstFile(dll_filename, &filedata);
    68     if (file == INVALID_HANDLE_VALUE) {
    84     char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1];
    86     for (i = 0; i < desc->
nparams; i++) {
    88             case JackDriverParamInt:
    89                 sprintf (arg_default, 
"%" "i", desc->
params[i].
value.i);
    91             case JackDriverParamUInt:
    92                 sprintf (arg_default, 
"%" "u", desc->
params[i].
value.ui);
    94             case JackDriverParamChar:
    95                 sprintf (arg_default, 
"%c", desc->
params[i].
value.c);
    97             case JackDriverParamString:
    99                     sprintf (arg_default, 
"%s", desc->
params[i].
value.str);
   101                     sprintf (arg_default, 
"none");
   104             case JackDriverParamBool:
   105                 sprintf (arg_default, 
"%s", desc->
params[i].
value.i ? 
"true" : 
"false");
   109         fprintf(file, 
"\t-%c, --%s \t%s (default: %s)\n",
   117 static void jack_print_driver_param_usage (
jack_driver_desc_t* desc, 
unsigned long param, FILE *file)
   119     fprintf (file, 
"Usage information for the '%s' parameter for driver '%s':\n",
   124 void jack_free_driver_params(
JSList * driver_params)
   126     JSList*node_ptr = driver_params;
   130         next_node_ptr = node_ptr->next;
   131         free(node_ptr->data);
   133         node_ptr = next_node_ptr;
   139     struct option * long_options;
   140     char* options, * options_ptr;
   143     unsigned int param_index;
   153     if (strcmp (argv[1], 
"-h") == 0 || strcmp (argv[1], 
"--help") == 0) {
   155             for (i = 0; i < desc->
nparams; i++) {
   156                 if (strcmp (desc->
params[i].
name, argv[2]) == 0) {
   157                     jack_print_driver_param_usage (desc, i, stdout);
   162             fprintf (stderr, 
"Jackd: unknown option '%s' "   163                      "for driver '%s'\n", argv[2],
   167         jack_log(
"Parameters for driver '%s' (all parameters are optional):", desc->
name);
   168         jack_print_driver_options (desc, stdout);
   173     options = (
char*)calloc (desc->
nparams * 3 + 1, sizeof (
char));
   176     options_ptr = options;
   177     for (i = 0; i < desc->
nparams; i++) {
   181         long_options[i].flag = NULL;
   183         long_options[i].has_arg = optional_argument;
   189     while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
   191         if (opt == 
':' || opt == 
'?') {
   193                 fprintf (stderr, 
"Missing option to argument '%c'\n", optopt);
   195                 fprintf (stderr, 
"Unknownage with option '%c'\n", optopt);
   198             fprintf (stderr, 
"Options for driver '%s':\n", desc->
name);
   199             jack_print_driver_options (desc, stderr);
   203         for (param_index = 0; param_index < desc->
nparams; param_index++) {
   212         if (!optarg && optind < argc &&
   213                 strlen(argv[optind]) &&
   214                 argv[optind][0] != 
'-') {
   215             optarg = argv[optind];
   220                 case JackDriverParamInt:
   221                     driver_param->value.i = atoi(optarg);
   223                 case JackDriverParamUInt:
   224                     driver_param->value.ui = strtoul(optarg, NULL, 10);
   226                 case JackDriverParamChar:
   227                     driver_param->value.c = optarg[0];
   229                 case JackDriverParamString:
   230                     strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
   232                 case JackDriverParamBool:
   233                     if (strcasecmp(
"false", optarg) == 0 ||
   234                         strcasecmp(
"off", optarg) == 0 ||
   235                         strcasecmp(
"no", optarg) == 0 ||
   236                         strcasecmp(
"0", optarg) == 0 ||
   237                         strcasecmp(
"(null)", optarg) == 0 ) {
   238                         driver_param->value.i = 
false;
   240                         driver_param->value.i = 
true;
   245             if (desc->
params[param_index].
type == JackDriverParamBool) {
   246                 driver_param->value.i = 
true;
   248                 driver_param->value = desc->
params[param_index].
value;
   252         params = jack_slist_append (params, driver_param);
   266     struct option* long_options;
   267     char* options, * options_ptr;
   279     if (driver_params == NULL) {
   286     if (strcmp (argv[1], 
"-h") == 0 || strcmp (argv[1], 
"--help") == 0) {
   290                     jack_print_driver_param_usage (desc, 
i, stdout);
   295             fprintf (stderr, 
"Jackd: unknown option '%s' "   296                      "for driver '%s'\n", argv[2],
   300         jack_log(
"Parameters for driver '%s' (all parameters are optional):", desc->
name);
   301         jack_print_driver_options (desc, stdout);
   306     options = (
char*)calloc (desc->
nparams * 3 + 1, sizeof (
char));
   309     options_ptr = options;
   314         long_options[
i].flag = NULL;
   316         long_options[
i].has_arg = optional_argument;
   322     while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
   324         if (opt == 
':' || opt == 
'?') {
   326                 fprintf (stderr, 
"Missing option to argument '%c'\n", optopt);
   328                 fprintf (stderr, 
"Unknownage with option '%c'\n", optopt);
   331             fprintf (stderr, 
"Options for driver '%s':\n", desc->
name);
   332             jack_print_driver_options(desc, stderr);
   336         node_ptr = (
JSList *)driver_params;
   342             node_ptr = node_ptr->next;
   345         if (!optarg && optind < argc &&
   346             strlen(argv[optind]) &&
   347             argv[optind][0] != 
'-') {
   348             optarg = argv[optind];
   353                 case JackDriverParamInt:
   354                     value.
i = atoi(optarg);
   357                 case JackDriverParamUInt:
   358                     value.
ui = strtoul(optarg, NULL, 10);
   361                 case JackDriverParamChar:
   365                 case JackDriverParamString:
   366                     strncpy(value.
str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
   369                 case JackDriverParamBool:
   370                     if (strcasecmp(
"false", optarg) == 0 ||
   371                         strcasecmp(
"off", optarg) == 0 ||
   372                         strcasecmp(
"no", optarg) == 0 ||
   373                         strcasecmp(
"0", optarg) == 0 ||
   374                         strcasecmp(
"(null)", optarg) == 0 ) {
   402     for (node = drivers; node; node = jack_slist_next (node)) {
   405         if (strcmp (desc->
name, name) != 0) {
   415 static void* check_symbol(
const char* sofile, 
const char* symbol, 
const char* driver_dir, 
void** res_dllhandle = NULL)
   420     sprintf(filename, 
"%s/%s", driver_dir, sofile);
   422     if ((dlhandle = LoadDriverModule(filename)) == NULL) {
   424         jack_error (
"Could not open component .dll '%s': %ld", filename, GetLastError());
   426         jack_error (
"Could not open component .so '%s': %s", filename, dlerror());
   429         res = (
void*)GetDriverProc(dlhandle, symbol);
   431             *res_dllhandle = dlhandle;
   433             UnloadDriverModule(dlhandle);
   440 static jack_driver_desc_t* jack_get_descriptor (
JSList* drivers, 
const char* sofile, 
const char* symbol, 
const char* driver_dir)
   444     JackDriverDescFunction so_get_descriptor = NULL;
   447     void* dlhandle = NULL;
   449     sprintf(filename, 
"%s/%s", driver_dir, sofile);
   450     so_get_descriptor = (JackDriverDescFunction)check_symbol(sofile, symbol, driver_dir, &dlhandle);
   452     if (so_get_descriptor == NULL) {
   453         jack_error(
"jack_get_descriptor : dll %s is not a driver", sofile);
   457     if ((descriptor = so_get_descriptor ()) == NULL) {
   458         jack_error(
"Driver from '%s' returned NULL descriptor", filename);
   463     for (node = drivers; node; node = jack_slist_next (node)) {
   465         if (strcmp(descriptor->
name, other_descriptor->
name) == 0) {
   466             jack_error(
"The drivers in '%s' and '%s' both have the name '%s'; using the first",
   467                        other_descriptor->
file, filename, other_descriptor->
name);
   473     strncpy(descriptor->
file, filename, JACK_PATH_MAX);
   477         UnloadDriverModule(dlhandle);
   487     WIN32_FIND_DATA filedata;
   489     const char* ptr = NULL;
   490     JSList* driver_list = NULL;
   493     char* driver_dir = locate_driver_dir(file, filedata);
   501         if (strncmp (
"jack_", filedata.cFileName, 5) != 0) {
   505         ptr = strrchr (filedata.cFileName, 
'.');
   511         if (strncmp (
"dll", ptr, 3) != 0) {
   516         if (check_symbol(filedata.cFileName, 
"jack_internal_initialize", driver_dir) != NULL) {
   520         desc = jack_get_descriptor (drivers, filedata.cFileName, 
"driver_get_descriptor", driver_dir);
   522             driver_list = jack_slist_append (driver_list, desc);
   524             jack_error (
"jack_get_descriptor returns null for \'%s\'", filedata.cFileName);
   527     } 
while (FindNextFile(file, &filedata));
   530         jack_error (
"Could not find any drivers in %s!", driver_dir);
   545     struct dirent * dir_entry;
   549     JSList* driver_list = NULL;
   552     const char* driver_dir;
   553     if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
   554         driver_dir = ADDON_DIR;
   559     dir_stream = opendir (driver_dir);
   561         jack_error (
"Could not open driver directory %s: %s",
   562                     driver_dir, strerror (errno));
   566     while ((dir_entry = readdir(dir_stream))) {
   569         if (strncmp (
"jack_", dir_entry->d_name, 5) != 0) {
   573         ptr = strrchr (dir_entry->d_name, 
'.');
   578         if (strncmp (
"so", ptr, 2) != 0) {
   583         if (check_symbol(dir_entry->d_name, 
"jack_internal_initialize", driver_dir) != NULL) {
   587         desc = jack_get_descriptor (drivers, dir_entry->d_name, 
"driver_get_descriptor", driver_dir);
   589             driver_list = jack_slist_append (driver_list, desc);
   591             jack_error (
"jack_get_descriptor returns null for \'%s\'", dir_entry->d_name);
   595     err = closedir (dir_stream);
   597         jack_error (
"Error closing driver directory %s: %s",
   598                     driver_dir, strerror (errno));
   602         jack_error (
"Could not find any drivers in %s!", driver_dir);
   616     WIN32_FIND_DATA filedata;
   618     const char* ptr = NULL;
   619     JSList* driver_list = NULL;
   622     char* driver_dir = locate_driver_dir(file, filedata);
   630         ptr = strrchr (filedata.cFileName, 
'.');
   636         if (strncmp (
"dll", ptr, 3) != 0) {
   641         if (check_symbol(filedata.cFileName, 
"jack_internal_initialize", driver_dir) == NULL) {
   645         desc = jack_get_descriptor (internals, filedata.cFileName, 
"jack_get_descriptor", driver_dir);
   647             driver_list = jack_slist_append (driver_list, desc);
   649             jack_error (
"jack_get_descriptor returns null for \'%s\'", filedata.cFileName);
   652     } 
while (FindNextFile(file, &filedata));
   655         jack_error (
"Could not find any internals in %s!", driver_dir);
   670     struct dirent * dir_entry;
   674     JSList* driver_list = NULL;
   677     const char* driver_dir;
   678     if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
   679         driver_dir = ADDON_DIR;
   684     dir_stream = opendir (driver_dir);
   686         jack_error (
"Could not open driver directory %s: %s\n",
   687                     driver_dir, strerror (errno));
   691     while ((dir_entry = readdir(dir_stream))) {
   693         ptr = strrchr (dir_entry->d_name, 
'.');
   699         if (strncmp (
"so", ptr, 2) != 0) {
   704         if (check_symbol(dir_entry->d_name, 
"jack_internal_initialize", driver_dir) == NULL) {
   708         desc = jack_get_descriptor (internals, dir_entry->d_name, 
"jack_get_descriptor", driver_dir);
   710             driver_list = jack_slist_append (driver_list, desc);
   712             jack_error (
"jack_get_descriptor returns null for \'%s\'", dir_entry->d_name);
   716     err = closedir (dir_stream);
   718         jack_error (
"Error closing internal directory %s: %s\n",
   719                     driver_dir, strerror (errno));
   723         jack_error (
"Could not find any internals in %s!", driver_dir);
   743     fHandle = LoadDriverModule (driver_desc->
file);
   745     if (fHandle == NULL) {
   747         if ((errstr = GetLastError ()) != 0) {
   750         if ((errstr = dlerror ()) != 0) {
   755             jack_error (
"Error loading driver shared object %s", driver_desc->
file);
   760     fInitialize = (driverInitialize)GetDriverProc(fHandle, 
"driver_initialize");
   763     if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) {
   765     if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) {
   767         jack_error(
"No initialize function in shared object %s\n", driver_desc->
file);
   771     fBackend = fInitialize(engine, synchro, params);
   775 JackDriverInfo::~JackDriverInfo()
   779         UnloadDriverModule(fHandle);
   785     jack_driver_type_t type,
   786     const char * description,
   790     size_t description_len;
   793     name_len = strlen(name);
   794     description_len = strlen(description);
   796     if (name_len > 
sizeof(desc_ptr->
name) - 1 ||
   797         description_len > 
sizeof(desc_ptr->
desc) - 1) {
   803     if (desc_ptr == NULL) {
   804         jack_error(
"Error calloc() failed to allocate memory for driver descriptor struct");
   808     memcpy(desc_ptr->
name, name, name_len + 1);
   809     memcpy(desc_ptr->
desc, description, description_len + 1);
   812     desc_ptr->
type = type;
   814     if (filler_ptr != NULL) {
   815         filler_ptr->size = 0;
   821 SERVER_EXPORT 
int jack_driver_descriptor_add_parameter(
   826     jack_driver_param_type_t type,
   829     const char* short_desc,
   830     const char* long_desc)
   833     size_t short_desc_len;
   834     size_t long_desc_len;
   838     name_len = strlen(name);
   839     short_desc_len = strlen(short_desc);
   841     if (long_desc != NULL) {
   842         long_desc_len = strlen(long_desc);
   844         long_desc = short_desc;
   845         long_desc_len = short_desc_len;
   848     if (name_len > 
sizeof(param_ptr->
name) - 1 ||
   849         short_desc_len > 
sizeof(param_ptr->
short_desc) - 1 ||
   850         long_desc_len > 
sizeof(param_ptr->
long_desc) - 1) {
   855     if (desc_ptr->
nparams == filler_ptr->size) {
   856         newsize = filler_ptr->size + 20; 
   858         if (param_ptr == NULL) {
   859             jack_error(
"Error realloc() failed for parameter array of %zu elements", newsize);
   862         filler_ptr->size = newsize;
   863         desc_ptr->
params = param_ptr;
   866     assert(desc_ptr->
nparams < filler_ptr->size);
   869     memcpy(param_ptr->
name, name, name_len + 1);
   871     param_ptr->
type = type;
   872     param_ptr->
value = *value_ptr;
   874     memcpy(param_ptr->
short_desc, short_desc, short_desc_len + 1);
   875     memcpy(param_ptr->
long_desc, long_desc, long_desc_len + 1);
   883 jack_constraint_add_enum(
   885     uint32_t * array_size_ptr,
   887     const char * short_desc)
   894     len = strlen(short_desc) + 1;
   895     if (len > 
sizeof(possible_value_ptr->
short_desc))
   901     constraint_ptr = *constraint_ptr_ptr;
   902     if (constraint_ptr == NULL)
   905         if (constraint_ptr == NULL)
   907             jack_error(
"calloc() failed to allocate memory for param constraint struct");
   915         array_size = *array_size_ptr;
   918     if (constraint_ptr->constraint.
enumeration.count == array_size)
   923                 constraint_ptr->constraint.
enumeration.possible_values_array,
   925         if (possible_value_ptr == NULL)
   927             jack_error(
"realloc() failed to (re)allocate memory for possible values array");
   930         constraint_ptr->constraint.
enumeration.possible_values_array = possible_value_ptr;
   934         possible_value_ptr = constraint_ptr->constraint.
enumeration.possible_values_array;
   937     possible_value_ptr += constraint_ptr->constraint.
enumeration.count;
   940     possible_value_ptr->value = *value_ptr;
   941     memcpy(possible_value_ptr->
short_desc, short_desc, len);
   943     *constraint_ptr_ptr = constraint_ptr;
   944     *array_size_ptr = array_size;
   951 jack_constraint_free(
   954     if (constraint_ptr != NULL)
   956         if ((constraint_ptr->
flags & JACK_CONSTRAINT_FLAG_RANGE) == 0)
   958             free(constraint_ptr->constraint.
enumeration.possible_values_array);
   961         free(constraint_ptr);
   965 #define JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(type, copy)                   \   966 JACK_CONSTRAINT_COMPOSE_ENUM(type)                                      \   968     jack_driver_param_constraint_desc_t * constraint_ptr;               \   969     uint32_t array_size;                                                \   970     jack_driver_param_value_t value;                                    \   971     struct jack_constraint_enum_ ## type ## _descriptor * descr_ptr;    \   973     constraint_ptr = NULL;                                              \   974     for (descr_ptr = descr_array_ptr;                                   \   979         if (!jack_constraint_add_enum(                                  \   983                 descr_ptr->short_desc))                                 \   985             jack_constraint_free(constraint_ptr);                       \   990     constraint_ptr->flags = flags;                                      \   992     return constraint_ptr;                                              \   995 JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(uint32, value.c = descr_ptr->value);
   996 JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(sint32, value.c = descr_ptr->value);
   997 JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(
char,   value.c = descr_ptr->value);
   998 JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(str, strcpy(value.str, descr_ptr->value));
 
SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver *driver_ptr, int argc, char *argv[])
Locked Engine, access to methods is serialized using a mutex.
char str[JACK_PARAM_STRING_MAX+1]
member used for JackParamString
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr)
Inter process synchronization using POSIX semaphore.
char file[JACK_PATH_MAX+1]
SERVER_EXPORT void jack_error(const char *fmt,...)
uint32_t ui
member used for JackParamUInt
jack_driver_param_value_t value
SERVER_EXPORT void jack_info(const char *fmt,...)
int32_t i
member used for JackParamInt
Type for parameter value.
SERVER_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
jack_driver_param_constraint_desc_t * constraint
SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr)
char name[JACK_DRIVER_NAME_MAX+1]
char name[JACK_DRIVER_NAME_MAX+1]
SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value *value_ptr)
The base interface for drivers clients.
char desc[JACK_DRIVER_PARAM_DESC+1]
jack_driver_param_type_t type
SERVER_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t *parameter_ptr)
struct jack_driver_param_constraint_desc_t::@0::@2 enumeration
char c
member used for JackParamChar
SERVER_EXPORT void jack_log(const char *fmt,...)
jack_driver_param_desc_t * params