From cf36c02aeb303ba8ae7fe37819a210d223004823 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Fri, 25 May 2012 02:25:14 +0300 Subject: [PATCH] Control API: Enforce driver/internal parameter order. This changeset is required for proper jackdbus handling of parameters. jackd handling of parameters is improved by making driver/internal parameters order on commandline irrelevant. E.g. "jackd -d alsa -d hw:Intel,0 -P hw:Intel,3" should now give same result as "jackd -d alsa -P hw:Intel,3 -d hw:Intel,0". The code used to create the driver parameter list in jackctl_parameter_set_value(). Apart from the ordering problem, the old implementation was not properly handling reset of driver/internal parameters, because upon reset the parameter was not removed from the set_parameters list which is supplied to driver/internal. This commit shifts driver/internal parameter list composition just before it is needed. I.e master or slave driver open, switch master, or internal load. The order of parameters is ensured to be the one defined by the driver/internal. --- common/JackControlAPI.cpp | 170 ++++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 69 deletions(-) diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 48152f71..45990530 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -100,7 +100,6 @@ struct jackctl_driver { jack_driver_desc_t * desc_ptr; JSList * parameters; - JSList * set_parameters; JSList * infos; }; @@ -108,7 +107,6 @@ struct jackctl_internal { jack_driver_desc_t * desc_ptr; JSList * parameters; - JSList * set_parameters; int refnum; }; @@ -126,7 +124,6 @@ struct jackctl_parameter union jackctl_parameter_value default_value; struct jackctl_driver * driver_ptr; char id; - jack_driver_param_t * driver_parameter_ptr; jack_driver_param_constraint_desc_t * constraint_ptr; }; @@ -174,7 +171,6 @@ jackctl_add_parameter( *value_ptr = *default_value_ptr = value; parameter_ptr->driver_ptr = NULL; - parameter_ptr->driver_parameter_ptr = NULL; parameter_ptr->id = 0; parameter_ptr->constraint_ptr = constraint_ptr; @@ -200,14 +196,6 @@ jackctl_free_driver_parameters( free(driver_ptr->parameters); driver_ptr->parameters = next_node_ptr; } - - while (driver_ptr->set_parameters) - { - next_node_ptr = driver_ptr->set_parameters->next; - free(driver_ptr->set_parameters->data); - free(driver_ptr->set_parameters); - driver_ptr->set_parameters = next_node_ptr; - } } static @@ -282,6 +270,86 @@ fail: return false; } +/* destroy jack_driver_param_desc_t list created by jackctl_create_param_list() */ +static void +jackctl_destroy_param_list( + JSList * params) +{ + JSList * next; + + while (params) + { + next = params->next; + free(params->data); + free(params); + params = next; + } +} + +/* for drivers and internals are configured through jack_driver_param_t JSList */ +/* this function creates such list from a jackctl_parameter list */ +static JSList * +jackctl_create_param_list( + const JSList * paramlist) +{ + jackctl_parameter * param_ptr; + jack_driver_param_t * retparam_ptr; + JSList * retparamlist; + + retparamlist = NULL; + while (paramlist != NULL) + { + param_ptr = (jackctl_parameter *)paramlist->data; + if (param_ptr->is_set) + { + /* jack_info("setting driver parameter %p ...", parameter_ptr); */ + retparam_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t)); + if (retparam_ptr == NULL) + { + jack_error ("Allocation of jack_driver_param_t structure failed"); + goto destroy; + } + + retparam_ptr->character = param_ptr->id; + + switch (param_ptr->type) + { + case JackParamInt: + retparam_ptr->value.i = param_ptr->value_ptr->i; + break; + case JackParamUInt: + retparam_ptr->value.ui = param_ptr->value_ptr->ui; + break; + case JackParamChar: + retparam_ptr->value.c = param_ptr->value_ptr->c; + break; + case JackParamString: + strcpy(retparam_ptr->value.str, param_ptr->value_ptr->str); + break; + case JackParamBool: + retparam_ptr->value.i = param_ptr->value_ptr->b; + break; + default: + jack_error("unknown parameter type %i", (int)param_ptr->type); + assert(0); + goto free; + } + + retparamlist = jack_slist_append(retparamlist, retparam_ptr); + } + + paramlist = paramlist->next; + } + + return retparamlist; + +free: + free(retparam_ptr); +destroy: + jackctl_destroy_param_list(retparamlist); + return NULL; +} + static int jackctl_drivers_load( struct jackctl_server * server_ptr) @@ -308,7 +376,6 @@ jackctl_drivers_load( driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; driver_ptr->parameters = NULL; - driver_ptr->set_parameters = NULL; driver_ptr->infos = NULL; if (!jackctl_add_driver_parameters(driver_ptr)) @@ -378,7 +445,6 @@ jackctl_internals_load( internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; internal_ptr->parameters = NULL; - internal_ptr->set_parameters = NULL; internal_ptr->refnum = -1; if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr)) @@ -875,6 +941,8 @@ jackctl_server_open( jackctl_server *server_ptr, jackctl_driver *driver_ptr) { + JSList * paramlist = NULL; + try { if (!server_ptr || !driver_ptr) { @@ -929,7 +997,10 @@ jackctl_server_open( goto fail_unregister; } - rc = server_ptr->engine->Open(driver_ptr->desc_ptr, driver_ptr->set_parameters); + paramlist = jackctl_create_param_list(driver_ptr->parameters); + if (paramlist == NULL) goto fail_delete; + rc = server_ptr->engine->Open(driver_ptr->desc_ptr, paramlist); + jackctl_destroy_param_list(paramlist); if (rc < 0) { jack_error("JackServer::Open() failed with %d", rc); @@ -940,6 +1011,7 @@ jackctl_server_open( } catch (std::exception e) { jack_error("jackctl_server_open error..."); + jackctl_destroy_param_list(paramlist); } fail_delete: @@ -1160,57 +1232,6 @@ SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, return NULL; } - bool new_driver_parameter; - - /* for driver parameters, set the parameter by adding jack_driver_param_t in the set_parameters list */ - if (parameter_ptr->driver_ptr != NULL) - { -/* jack_info("setting driver parameter %p ...", parameter_ptr); */ - new_driver_parameter = parameter_ptr->driver_parameter_ptr == NULL; - if (new_driver_parameter) - { -/* jack_info("new driver parameter..."); */ - parameter_ptr->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t)); - if (parameter_ptr->driver_parameter_ptr == NULL) - { - jack_error ("Allocation of jack_driver_param_t structure failed"); - return false; - } - - parameter_ptr->driver_parameter_ptr->character = parameter_ptr->id; - parameter_ptr->driver_ptr->set_parameters = jack_slist_append(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr); - } - - switch (parameter_ptr->type) - { - case JackParamInt: - parameter_ptr->driver_parameter_ptr->value.i = value_ptr->i; - break; - case JackParamUInt: - parameter_ptr->driver_parameter_ptr->value.ui = value_ptr->ui; - break; - case JackParamChar: - parameter_ptr->driver_parameter_ptr->value.c = value_ptr->c; - break; - case JackParamString: - strcpy(parameter_ptr->driver_parameter_ptr->value.str, value_ptr->str); - break; - case JackParamBool: - parameter_ptr->driver_parameter_ptr->value.i = value_ptr->b; - break; - default: - jack_error("unknown parameter type %i", (int)parameter_ptr->type); - assert(0); - - if (new_driver_parameter) - { - parameter_ptr->driver_ptr->set_parameters = jack_slist_remove(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr); - } - - return false; - } - } - parameter_ptr->is_set = true; *parameter_ptr->value_ptr = *value_ptr; @@ -1255,7 +1276,10 @@ SERVER_EXPORT bool jackctl_server_load_internal( int status; if (server_ptr->engine != NULL) { - server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); + JSList * paramlist = jackctl_create_param_list(internal->parameters); + if (paramlist == NULL) return false; + server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, paramlist, JackNullOption, &internal->refnum, -1, &status); + jackctl_destroy_param_list(paramlist); return (internal->refnum > 0); } else { return false; @@ -1286,7 +1310,10 @@ SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl jack_error("cannot add a slave in a running server"); return false; } else { - JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); + JSList * paramlist = jackctl_create_param_list(driver_ptr->parameters); + if (paramlist == NULL) return false; + JackDriverInfo* info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, paramlist); + jackctl_destroy_param_list(paramlist); if (info) { driver_ptr->infos = jack_slist_append(driver_ptr->infos, info); return true; @@ -1325,7 +1352,12 @@ SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jack SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr && server_ptr->engine) { - return (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0); + JSList * paramlist = jackctl_create_param_list(driver_ptr->parameters); + if (paramlist == NULL) return false; + jackctl_destroy_param_list(paramlist); + bool ret = (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, paramlist) == 0); + jackctl_destroy_param_list(paramlist); + return ret; } else { return false; }