jackdbus: slave-drivers parameter

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4317 0c269be4-1314-0410-8aa9-9f06e86f4224
This commit is contained in:
nedko 2011-04-17 21:52:26 +00:00
parent 1d06e19943
commit 5cc529d9cf
5 changed files with 245 additions and 30 deletions

View File

@ -65,9 +65,7 @@ jack_controller_find_driver(
return NULL;
}
bool
jack_controller_add_slave_drivers(
struct jack_controller * controller_ptr)
static bool jack_controller_check_slave_driver(struct jack_controller * controller_ptr, const char * name)
{
struct list_head * node_ptr;
struct jack_controller_slave_driver * driver_ptr;
@ -75,31 +73,40 @@ jack_controller_add_slave_drivers(
list_for_each(node_ptr, &controller_ptr->slave_drivers)
{
driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
driver_ptr->handle = jack_controller_find_driver(controller_ptr->server, driver_ptr->name);
if (driver_ptr->handle == NULL)
if (strcmp(name, driver_ptr->name) == 0)
{
jack_error("Unknown driver \"%s\"", driver_ptr->name);
goto fail;
return true;
}
}
return false;
}
static bool jack_controller_load_slave_drivers(struct jack_controller * controller_ptr)
{
struct list_head * node_ptr;
struct jack_controller_slave_driver * driver_ptr;
list_for_each(node_ptr, &controller_ptr->slave_drivers)
{
driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
assert(driver_ptr->handle != NULL);
assert(!driver_ptr->loaded);
if (!jackctl_server_add_slave(controller_ptr->server, driver_ptr->handle))
{
jack_error("Driver \"%s\" cannot be loaded", driver_ptr->name);
goto fail;
return false;
}
driver_ptr->loaded = true;
}
return true;
fail:
driver_ptr->handle = NULL;
return false;
}
void
jack_controller_remove_slave_drivers(
struct jack_controller * controller_ptr)
static void jack_controller_unload_slave_drivers(struct jack_controller * controller_ptr)
{
struct list_head * node_ptr;
struct jack_controller_slave_driver * driver_ptr;
@ -107,14 +114,30 @@ jack_controller_remove_slave_drivers(
list_for_each(node_ptr, &controller_ptr->slave_drivers)
{
driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
if (driver_ptr->handle != NULL)
if (driver_ptr->loaded)
{
jackctl_server_remove_slave(controller_ptr->server, driver_ptr->handle);
driver_ptr->handle = NULL;
driver_ptr->loaded = false;
}
}
}
static void jack_controller_remove_slave_drivers(struct jack_controller * controller_ptr)
{
struct jack_controller_slave_driver * driver_ptr;
while (!list_empty(&controller_ptr->slave_drivers))
{
driver_ptr = list_entry(controller_ptr->slave_drivers.next, struct jack_controller_slave_driver, siblings);
assert(!driver_ptr->loaded);
list_del(&driver_ptr->siblings);
free(driver_ptr->name);
free(driver_ptr);
}
controller_ptr->slave_drivers_vparam_value.str[0] = 0;
}
static
jackctl_internal_t *
jack_controller_find_internal(
@ -183,7 +206,7 @@ jack_controller_start_server(
goto fail;
}
jack_controller_add_slave_drivers(controller_ptr);
jack_controller_load_slave_drivers(controller_ptr);
if (!jackctl_server_start(
controller_ptr->server))
@ -245,7 +268,7 @@ fail_stop_server:
}
fail_close_server:
jack_controller_remove_slave_drivers(controller_ptr);
jack_controller_unload_slave_drivers(controller_ptr);
if (!jackctl_server_close(controller_ptr->server))
{
@ -289,7 +312,7 @@ jack_controller_stop_server(
return FALSE;
}
jack_controller_remove_slave_drivers(controller_ptr);
jack_controller_unload_slave_drivers(controller_ptr);
if (!jackctl_server_close(controller_ptr->server))
{
@ -381,11 +404,108 @@ on_device_release(const char * device_name)
g_device_count--;
}
#define controller_ptr ((struct jack_controller *)obj)
static bool slave_drivers_parameter_is_set(void * obj)
{
return controller_ptr->slave_drivers_set;
}
static bool slave_drivers_parameter_reset(void * obj)
{
if (controller_ptr->started)
{
jack_error("Cannot modify slave-drivers when server is started");
return false;
}
jack_controller_remove_slave_drivers(controller_ptr);
controller_ptr->slave_drivers_set = false;
return true;
}
static union jackctl_parameter_value slave_drivers_parameter_get_value(void * obj)
{
return controller_ptr->slave_drivers_vparam_value;
}
static bool slave_drivers_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr)
{
char * buffer;
char * save;
const char * token;
struct list_head old_list;
struct list_head new_list;
union jackctl_parameter_value old_value;
union jackctl_parameter_value new_value;
bool old_set;
if (controller_ptr->started)
{
jack_error("Cannot modify slave-drivers when server is started");
return false;
}
old_set = controller_ptr->slave_drivers_set;
old_value = controller_ptr->slave_drivers_vparam_value;
controller_ptr->slave_drivers_vparam_value.str[0] = 0;
old_list = controller_ptr->slave_drivers;
INIT_LIST_HEAD(&controller_ptr->slave_drivers);
buffer = strdup(value_ptr->str);
if (buffer == NULL)
{
jack_error("strdup() failed.");
return false;
}
token = strtok_r(buffer, ",", &save);
while (token)
{
//jack_info("slave driver '%s'", token);
if (!jack_controller_add_slave_driver(controller_ptr, token))
{
jack_controller_remove_slave_drivers(controller_ptr);
controller_ptr->slave_drivers = old_list;
controller_ptr->slave_drivers_vparam_value = old_value;
controller_ptr->slave_drivers_set = old_set;
free(buffer);
return false;
}
token = strtok_r(NULL, ",", &save);
}
new_value = controller_ptr->slave_drivers_vparam_value;
new_list = controller_ptr->slave_drivers;
controller_ptr->slave_drivers = old_list;
jack_controller_remove_slave_drivers(controller_ptr);
controller_ptr->slave_drivers_vparam_value = new_value;
controller_ptr->slave_drivers = new_list;
controller_ptr->slave_drivers_set = true;
free(buffer);
return true;
}
static union jackctl_parameter_value slave_drivers_parameter_get_default_value(void * obj)
{
union jackctl_parameter_value value;
value.str[0] = 0;
return value;
}
#undef controller_ptr
void *
jack_controller_create(
DBusConnection *connection)
{
struct jack_controller *controller_ptr;
const char * address[PARAM_ADDRESS_SIZE];
DBusObjectPathVTable vtable =
{
jack_dbus_message_handler_unregister,
@ -416,7 +536,28 @@ jack_controller_create(
controller_ptr->client = NULL;
controller_ptr->started = false;
INIT_LIST_HEAD(&controller_ptr->slave_drivers);
controller_ptr->slave_drivers_set = false;
controller_ptr->slave_drivers_vparam_value.str[0] = 0;
controller_ptr->slave_drivers_vparam.obj = controller_ptr;
controller_ptr->slave_drivers_vparam.vtable.is_set = slave_drivers_parameter_is_set;
controller_ptr->slave_drivers_vparam.vtable.reset = slave_drivers_parameter_reset;
controller_ptr->slave_drivers_vparam.vtable.get_value = slave_drivers_parameter_get_value;
controller_ptr->slave_drivers_vparam.vtable.set_value = slave_drivers_parameter_set_value;
controller_ptr->slave_drivers_vparam.vtable.get_default_value = slave_drivers_parameter_get_default_value;
controller_ptr->slave_drivers_vparam.type = JackParamString;
controller_ptr->slave_drivers_vparam.name = "slave-drivers";
controller_ptr->slave_drivers_vparam.short_decr = "Slave drivers to use";
controller_ptr->slave_drivers_vparam.long_descr = "A comma separated list of slave drivers";
controller_ptr->slave_drivers_vparam.constraint_flags = 0;
address[0] = PTNODE_ENGINE;
address[1] = NULL;
jack_params_add_parameter(controller_ptr->params, address, true, &controller_ptr->slave_drivers_vparam);
controller_ptr->dbus_descriptor.context = controller_ptr;
controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces;
@ -453,7 +594,31 @@ jack_controller_add_slave_driver(
struct jack_controller * controller_ptr,
const char * driver_name)
{
jackctl_driver_t * driver;
struct jack_controller_slave_driver * driver_ptr;
size_t len_old;
size_t len_new;
len_old = strlen(controller_ptr->slave_drivers_vparam_value.str);
len_new = strlen(driver_name);
if (len_old + len_new + 2 > sizeof(controller_ptr->slave_drivers_vparam_value.str))
{
jack_error("No more space for slave drivers.");
return false;
}
driver = jack_controller_find_driver(controller_ptr->server, driver_name);
if (driver == NULL)
{
jack_error("Unknown driver \"%s\"", driver_name);
return false;
}
if (jack_controller_check_slave_driver(controller_ptr, driver_name))
{
jack_info("Driver \"%s\" is already slave", driver_name);
return true;
}
driver_ptr = malloc(sizeof(struct jack_controller_slave_driver));
if (driver_ptr == NULL)
@ -470,12 +635,21 @@ jack_controller_add_slave_driver(
return false;
}
driver_ptr->handle = NULL;
driver_ptr->handle = driver;
driver_ptr->loaded = false;
jack_info("slave driver \"%s\" added", driver_name);
jack_info("driver \"%s\" set as slave", driver_name);
list_add_tail(&driver_ptr->siblings, &controller_ptr->slave_drivers);
if (len_old != 0)
{
controller_ptr->slave_drivers_vparam_value.str[len_old++] = ',';
}
memcpy(controller_ptr->slave_drivers_vparam_value.str + len_old, driver_name, len_new + 1);
controller_ptr->slave_drivers_set = true;
return true;
}
@ -492,10 +666,25 @@ jack_controller_remove_slave_driver(
driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
if (strcmp(driver_ptr->name, driver_name) == 0)
{
jack_info("slave driver \"%s\" removed", driver_name);
list_del(&driver_ptr->siblings);
free(driver_ptr->name);
free(driver_ptr);
/* update the slave-drivers param value */
controller_ptr->slave_drivers_vparam_value.str[0] = 0;
list_for_each(node_ptr, &controller_ptr->slave_drivers)
{
driver_ptr = list_entry(node_ptr, struct jack_controller_slave_driver, siblings);
if (controller_ptr->slave_drivers_vparam_value.str[0] != 0)
{
strcat(controller_ptr->slave_drivers_vparam_value.str, ",");
}
strcat(controller_ptr->slave_drivers_vparam_value.str, driver_ptr->name);
}
jack_info("driver \"%s\" is not slave anymore", driver_name);
return true;
}
}
@ -550,6 +739,7 @@ jack_controller_destroy(
jack_controller_stop_server(controller_ptr, NULL);
}
jack_controller_remove_slave_drivers(controller_ptr);
jack_params_destroy(controller_ptr->params);
jackctl_server_destroy(controller_ptr->server);

View File

@ -30,6 +30,7 @@
#include "jackdbus.h"
#include "controller_internal.h"
#include "xml.h"
#define JACK_DBUS_IFACE_NAME "org.jackaudio.JackControl"
@ -244,12 +245,17 @@ jack_control_run_method(
goto exit;
}
if (!jack_controller_add_slave_driver(controller_ptr, driver_name)) {
if (!jack_controller_add_slave_driver(controller_ptr, driver_name))
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_GENERIC,
"jack_controller_add_slave_driver failed for driver (%s)", driver_name);
}
else
{
jack_controller_settings_save_auto(controller_ptr);
}
}
else if (strcmp (call->method_name, "RemoveSlaveDriver") == 0)
{
@ -268,12 +274,17 @@ jack_control_run_method(
goto exit;
}
if (!jack_controller_remove_slave_driver(controller_ptr, driver_name)) {
if (!jack_controller_remove_slave_driver(controller_ptr, driver_name))
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_GENERIC,
"jack_controller_remove_slave_driver failed for driver (%s)", driver_name);
}
else
{
jack_controller_settings_save_auto(controller_ptr);
}
}
else if (strcmp (call->method_name, "UnloadInternal") == 0)
{

View File

@ -34,6 +34,7 @@ struct jack_controller_slave_driver
struct list_head siblings;
char * name;
jackctl_driver_t * handle;
bool loaded;
};
struct jack_controller
@ -48,6 +49,9 @@ struct jack_controller
unsigned int xruns;
struct list_head slave_drivers;
bool slave_drivers_set;
struct jack_parameter slave_drivers_vparam;
union jackctl_parameter_value slave_drivers_vparam_value;
struct jack_dbus_object_descriptor dbus_descriptor;
};

View File

@ -142,6 +142,7 @@ static bool add_controlapi_param(struct list_head * parent_list_ptr, jackctl_par
goto fail;
}
param_ptr->ext = false;
param_ptr->obj = param;
param_ptr->vtable.is_set = controlapi_parameter_is_set;
param_ptr->vtable.reset = controlapi_parameter_reset;
@ -212,6 +213,11 @@ static void free_params(struct list_head * parent_list_ptr)
param_ptr = list_entry(parent_list_ptr->next, struct jack_parameter, siblings);
list_del(&param_ptr->siblings);
if (param_ptr->ext)
{
continue;
}
if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0 &&
!param_ptr->constraint_range &&
param_ptr->constraint.enumeration.possible_values_array != NULL)
@ -456,6 +462,7 @@ static bool init_engine_driver_parameter(struct jack_params * params_ptr)
goto fail;
}
param_ptr->ext = false;
param_ptr->obj = params_ptr;
param_ptr->vtable.is_set = engine_driver_parameter_is_set;
param_ptr->vtable.reset = engine_driver_parameter_reset;
@ -691,7 +698,7 @@ const struct jack_parameter * jack_params_get_parameter(jack_params_handle param
return NULL;
}
bool jack_params_add_parameter(jack_params_handle params, const char * const * address, bool end, struct jack_parameter * param_ptr)
void jack_params_add_parameter(jack_params_handle params, const char * const * address, bool end, struct jack_parameter * param_ptr)
{
struct jack_parameter_container * container_ptr;
@ -699,9 +706,11 @@ bool jack_params_add_parameter(jack_params_handle params, const char * const * a
if (container_ptr == NULL || !container_ptr->leaf)
{
assert(false);
return false;
return;
}
param_ptr->ext = true;
if (end)
{
list_add_tail(&param_ptr->siblings, &container_ptr->children);
@ -711,7 +720,7 @@ bool jack_params_add_parameter(jack_params_handle params, const char * const * a
list_add(&param_ptr->siblings, &container_ptr->children);
}
return true;
return;
}
#undef params_ptr

View File

@ -54,6 +54,7 @@ struct jack_parameter
void * obj;
struct jack_parameter_vtable vtable;
struct list_head siblings;
bool ext;
jackctl_param_type_t type;
const char * name;
const char * short_decr;
@ -105,6 +106,6 @@ jack_params_iterate_params(
const struct jack_parameter * jack_params_get_parameter(jack_params_handle params, const char * const * address);
bool jack_params_add_parameter(jack_params_handle params, const char * const * address, bool end, struct jack_parameter * param_ptr);
void jack_params_add_parameter(jack_params_handle params, const char * const * address, bool end, struct jack_parameter * param_ptr);
#endif /* #ifndef PARAMS_H__A23EDE06_C1C9_4489_B253_FD1B26B66929__INCLUDED */