Implement DBUS entry points to handle internal clients, add new commands in jack_control.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2866 0c269be4-1314-0410-8aa9-9f06e86f4224
This commit is contained in:
sletz 2008-09-03 10:57:27 +00:00
parent 0375f9023e
commit 6642ea118d
12 changed files with 957 additions and 24 deletions

View File

@ -22,6 +22,10 @@ Florian Faber
Jackdmp changes log
---------------------------
2008-09-03 Stephane Letz <letz@grame.fr>
* Implement DBUS entry points to handle internal clients, add new commands in jack_control."
2008-09-01 Stephane Letz <letz@grame.fr>
* Add new jack_set_port_rename_callback API, jack_port_set_name is now a server request that call port rename callbacks.

View File

@ -84,19 +84,25 @@ def main():
if len(sys.argv) == 1:
print "Usage: %s [command] [command] ..." % os.path.basename(sys.argv[0])
print "Commands:"
print " exit - exit jack dbus service (stops jack server if currently running)"
print " status - check whether jack server is started, return value is 0 if runing and 1 otherwise"
print " start - start jack server if not currently started"
print " stop - stop jack server if currenly started"
print " dl - get list of available drivers"
print " dg - get currently selected driver"
print " ds <driver> - select driver"
print " dp - get parameters of currently selected driver"
print " dpd <param> - get long description for driver parameter"
print " dps <param> <value> - set driver parameter"
print " ep - get engine parameters"
print " epd <param> - get long description for engine parameter"
print " eps <param> <value> - set engine parameter"
print " exit - exit jack dbus service (stops jack server if currently running)"
print " status - check whether jack server is started, return value is 0 if runing and 1 otherwise"
print " start - start jack server if not currently started"
print " stop - stop jack server if currenly started"
print " dl - get list of available drivers"
print " dg - get currently selected driver"
print " ds <driver> - select driver"
print " dp - get parameters of currently selected driver"
print " dpd <param> - get long description for driver parameter"
print " dps <param> <value> - set driver parameter"
print " il - get list of available internals"
print " ip <name> - get parameters of given internal"
print " ipd <name> <param> - get long description for internal parameter"
print " ips <name> <param> <value> - set internal parameter"
print " iload <name> - load internal"
print " iunload <name> - unload internal"
print " ep - get engine parameters"
print " epd <param> - get long description for engine parameter"
print " eps <param> <value> - set engine parameter"
sys.exit(0)
bus = dbus.SessionBus()
@ -179,7 +185,7 @@ def main():
print "%20s: %s (%s:%s:%s:%s)" %(name, descr, typestr, isset, default, value)
elif arg == 'dpd':
if index >= len(sys.argv):
print "get driver parameter long description command requires driver name argument"
print "get driver parameter long description command requires parameter name argument"
sys.exit()
param = sys.argv[index]
@ -190,7 +196,7 @@ def main():
print long_descr,
elif arg == 'dps':
if index + 1 >= len(sys.argv):
print "driver parameter set command requires parametr name and value arguments"
print "driver parameter set command requires parameter name and value arguments"
sys.exit()
param = sys.argv[index]
@ -226,7 +232,7 @@ def main():
print "%20s: %s (%s:%s:%s:%s)" %(name, descr, typestr, isset, default, value)
elif arg == 'epd':
if index >= len(sys.argv):
print "get engine parameter long description command requires driver name argument"
print "get engine parameter long description command requires parameter name argument"
sys.exit()
param_name = sys.argv[index]
@ -238,7 +244,7 @@ def main():
print long_descr,
elif arg == 'eps':
if index + 1 >= len(sys.argv):
print "engine parameter set command requires parametr name and value arguments"
print "engine parameter set command requires parameter name and value arguments"
sys.exit()
param = sys.argv[index]
@ -250,6 +256,88 @@ def main():
type_char, name, short_descr, long_descr = configure_iface.GetEngineParameterInfo(param)
configure_iface.SetEngineParameterValue(param, python_type_to_jackdbus_type(value, type_char))
elif arg == 'il':
print "--- internals list"
internals = configure_iface.GetAvailableInternals()
for internal in internals:
print internal
elif arg == 'ip':
print "--- get internal parameters (type:isset:default:value)"
if index >= len(sys.argv):
print "internal parameters command requires internal name argument"
sys.exit()
internal_name = sys.argv[index]
index += 1
params = configure_iface.GetInternalParametersInfo(internal_name)
#print params
for param in params:
typestr = dbus_typesig_to_type_string(param[0])
name = param[1]
#print name
descr = param[2]
#print descr
isset, default, value = configure_iface.GetInternalParameterValue(internal_name, name)
#print typestr
if bool(isset):
isset = "set"
else:
isset = "notset"
value = dbus_type_to_python_type(value)
default = dbus_type_to_python_type(default)
print "%20s: %s (%s:%s:%s:%s)" %(name, descr, typestr, isset, default, value)
elif arg == 'ipd':
if index + 1 >= len(sys.argv):
print "get internal parameter long description command requires internal and parameter name arguments"
sys.exit()
name = sys.argv[index]
index += 1
param = sys.argv[index]
index += 1
print "--- get internal parameter description (%s)" % param
type_char, name, short_descr, long_descr = configure_iface.GetInternalParameterInfo(name, param)
print long_descr
elif arg == 'ips':
if index + 2 >= len(sys.argv):
print "get internal parameter long description command requires internal, parameter name and value arguments"
sys.exit()
internal_name = sys.argv[index]
index += 1
param = sys.argv[index]
index += 1
value = sys.argv[index]
index += 1
print "--- internal param set \"%s\" -> \"%s\"" % (param, value)
type_char, name, short_descr, long_descr = configure_iface.GetInternalParameterInfo(internal_name, param)
configure_iface.SetInternalParameterValue(internal_name, param, python_type_to_jackdbus_type(value, type_char))
elif arg == 'iload':
print "--- load internal"
if index >= len(sys.argv):
print "load internal command requires internal name argument"
sys.exit()
name = sys.argv[index]
index += 1
result = control_iface.LoadInternal(name)
elif arg == 'iunload':
print "--- unload internal"
if index >= len(sys.argv):
print "unload internal command requires internal name argument"
sys.exit()
name = sys.argv[index]
index += 1
result = control_iface.UnloadInternal(name)
else:
print "Unknown command '%s'" % arg
except dbus.DBusException, e:

View File

@ -62,6 +62,28 @@ jack_controller_find_driver(
return NULL;
}
jackctl_internal_t *
jack_controller_find_internal(
jackctl_server_t *server,
const char *internal_name)
{
const JSList * node_ptr;
node_ptr = jackctl_server_get_internals_list(server);
while (node_ptr)
{
if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0)
{
return node_ptr->data;
}
node_ptr = jack_slist_next(node_ptr);
}
return NULL;
}
jackctl_parameter_t *
jack_controller_find_parameter(
const JSList * parameters_list,
@ -344,6 +366,42 @@ fail:
return NULL;
}
bool
jack_controller_load_internal(
struct jack_controller *controller_ptr,
const char * internal_name)
{
jackctl_internal_t *internal;
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
return false;
}
jack_info("internal \"%s\" selected", internal_name);
return jackctl_server_load_internal(controller_ptr->server, internal);
}
bool
jack_controller_unload_internal(
struct jack_controller *controller_ptr,
const char * internal_name)
{
jackctl_internal_t *internal;
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
return false;
}
jack_info("internal \"%s\" selected", internal_name);
return jackctl_server_unload_internal(controller_ptr->server, internal);
}
#define controller_ptr ((struct jack_controller *)context)
void

View File

@ -764,6 +764,241 @@ jack_controller_dbus_set_engine_parameter_value(
jack_dbus_construct_method_return_empty(call);
}
static
void
jack_controller_dbus_get_available_internals(
struct jack_dbus_method_call *call)
{
jack_dbus_construct_method_return_array_of_strings(
call,
controller_ptr->internals_count,
controller_ptr->internal_names);
}
/*
* Execute GetInternalParametersInfo method call.
*/
static
void
jack_controller_dbus_get_internal_parameters_info(
struct jack_dbus_method_call *call)
{
const char *internal_name;
jackctl_internal_t * internal;
if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
{
/* The method call had invalid arguments meaning that
* get_method_args() has constructed an error for us.
*/
return;
}
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
"Unknown internal \"%s\"",
internal_name);
return;
}
jack_controller_get_parameters_info(call, jackctl_internal_get_parameters(internal));
}
/*
* Execute GetInternalParameterInfo method call.
*/
static
void
jack_controller_dbus_get_internal_parameter_info(
struct jack_dbus_method_call *call)
{
const char *internal_name;
const char *parameter_name;
jackctl_parameter_t *parameter;
jackctl_internal_t * internal;
if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_STRING, &parameter_name, DBUS_TYPE_INVALID))
{
/* The method call had invalid arguments meaning that
* get_method_args() has constructed an error for us.
*/
return;
}
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
"Unknown internal \"%s\"",
internal_name);
return;
}
parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), parameter_name);
if (parameter == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_DRIVER_PARAMETER,
"Unknown parameter \"%s\" for driver \"%s\"",
parameter_name,
jackctl_driver_get_name(controller_ptr->driver));
return;
}
jack_controller_get_parameter_info(call, parameter);
}
/*
* Execute GetInternalParameterValue method call.
*/
static void
jack_controller_dbus_get_internal_parameter_value(
struct jack_dbus_method_call *call)
{
const char *internal_name;
const char *parameter_name;
jackctl_parameter_t *parameter;
jackctl_internal_t * internal;
int type;
union jackctl_parameter_value jackctl_value;
union jackctl_parameter_value jackctl_default_value;
message_arg_t value;
message_arg_t default_value;
if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_STRING, &parameter_name, DBUS_TYPE_INVALID))
{
/* The method call had invalid arguments meaning that
* get_method_args() has constructed an error for us.
*/
return;
}
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
"Unknown internal \"%s\"",
internal_name);
return;
}
parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), parameter_name);
if (parameter == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_DRIVER_PARAMETER,
"Unknown parameter \"%s\" for driver \"%s\"",
parameter,
jackctl_driver_get_name(controller_ptr->driver));
return;
}
type = jackctl_parameter_get_type(parameter);
jackctl_default_value = jackctl_parameter_get_default_value(parameter);
jackctl_value = jackctl_parameter_get_value(parameter);
jack_controller_jack_to_dbus_variant(type, &jackctl_value, &value);
jack_controller_jack_to_dbus_variant(type, &jackctl_default_value, &default_value);
/* Construct the reply. */
jack_dbus_construct_method_return_parameter(
call,
(dbus_bool_t)(jackctl_parameter_is_set(parameter) ? TRUE : FALSE),
PARAM_TYPE_JACK_TO_DBUS(type),
PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type),
default_value,
value);
}
static
void
jack_controller_dbus_set_internal_parameter_value(
struct jack_dbus_method_call *call)
{
const char *internal_name;
const char *parameter_name;
jackctl_internal_t * internal;
message_arg_t arg;
int arg_type;
jackctl_parameter_t *parameter;
jackctl_param_type_t type;
union jackctl_parameter_value value;
if (!jack_dbus_get_method_args_two_strings_and_variant(call, &internal_name, &parameter_name, &arg, &arg_type))
{
/* The method call had invalid arguments meaning that
* jack_dbus_get_method_args_two_strings_and_variant() has constructed
* an error for us.
*/
return;
}
internal = jack_controller_find_internal(controller_ptr->server, internal_name);
if (internal == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
"Unknown internal \"%s\"",
internal_name);
return;
}
parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), parameter_name);
if (parameter == NULL)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_UNKNOWN_DRIVER_PARAMETER,
"Unknown parameter \"%s\" for driver \"%s\"",
parameter,
jackctl_driver_get_name(controller_ptr->driver));
return;
}
type = jackctl_parameter_get_type(parameter);
if (PARAM_TYPE_JACK_TO_DBUS(type) != arg_type)
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_INVALID_ARGS,
"Engine parameter value type mismatch: was expecting '%c', got '%c'",
(char)PARAM_TYPE_JACK_TO_DBUS(type),
(char)arg_type);
return;
}
if (!jack_controller_dbus_to_jack_variant(
arg_type,
&arg,
&value))
{
jack_dbus_error(
call,
JACK_DBUS_ERROR_INVALID_ARGS,
"Cannot convert engine parameter value");
return;
}
jackctl_parameter_set_value(parameter, &value);
jack_controller_settings_save_auto(controller_ptr);
jack_dbus_construct_method_return_empty(call);
}
#undef controller_ptr
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetAvailableDrivers)
@ -820,6 +1055,35 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetEngineParameterValue)
JACK_DBUS_METHOD_ARGUMENT("value", "v", false)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetAvailableInternals)
JACK_DBUS_METHOD_ARGUMENT("internals_list", "as", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetInternalParametersInfo)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("parameter_info_array", "a(ysss)", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetInternalParameterInfo)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("parameter", "s", false)
JACK_DBUS_METHOD_ARGUMENT("parameter_info", "(ysss)", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetInternalParameterValue)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("parameter", "s", false)
JACK_DBUS_METHOD_ARGUMENT("is_set", "b", true)
JACK_DBUS_METHOD_ARGUMENT("default", "v", true)
JACK_DBUS_METHOD_ARGUMENT("value", "v", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetInternalParameterValue)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("parameter", "s", false)
JACK_DBUS_METHOD_ARGUMENT("value", "v", false)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHODS_BEGIN
JACK_DBUS_METHOD_DESCRIBE(GetAvailableDrivers, jack_controller_dbus_get_available_drivers)
JACK_DBUS_METHOD_DESCRIBE(GetSelectedDriver, jack_controller_dbus_get_selected_driver)
@ -832,6 +1096,11 @@ JACK_DBUS_METHODS_BEGIN
JACK_DBUS_METHOD_DESCRIBE(GetEngineParameterInfo, jack_controller_dbus_get_engine_parameter_info)
JACK_DBUS_METHOD_DESCRIBE(GetEngineParameterValue, jack_controller_dbus_get_engine_parameter_value)
JACK_DBUS_METHOD_DESCRIBE(SetEngineParameterValue, jack_controller_dbus_set_engine_parameter_value)
JACK_DBUS_METHOD_DESCRIBE(GetAvailableInternals, jack_controller_dbus_get_available_internals)
JACK_DBUS_METHOD_DESCRIBE(GetInternalParametersInfo, jack_controller_dbus_get_internal_parameters_info)
JACK_DBUS_METHOD_DESCRIBE(GetInternalParameterInfo, jack_controller_dbus_get_internal_parameter_info)
JACK_DBUS_METHOD_DESCRIBE(GetInternalParameterValue, jack_controller_dbus_get_internal_parameter_value)
JACK_DBUS_METHOD_DESCRIBE(SetInternalParameterValue, jack_controller_dbus_set_internal_parameter_value)
JACK_DBUS_METHODS_END
JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_configure, "org.jackaudio.JackConfigure")

View File

@ -76,7 +76,7 @@ jack_control_run_method(
if (strcmp (call->method_name, "Exit") == 0)
{
g_exit_command = TRUE;
g_exit_command = TRUE;
}
else if (strcmp (call->method_name, "IsStarted") == 0)
{
@ -185,6 +185,34 @@ jack_control_run_method(
{
controller_ptr->xruns = 0;
}
else if (strcmp (call->method_name, "LoadInternal") == 0)
{
const char *internal_name;
if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
{
/* The method call had invalid arguments meaning that
* get_method_args() has constructed an error for us.
*/
goto exit;
}
type = DBUS_TYPE_BOOLEAN;
arg.boolean = jack_controller_load_internal(controller_ptr, internal_name) ? TRUE : FALSE;
}
else if (strcmp (call->method_name, "UnloadInternal") == 0)
{
const char *internal_name;
if (!jack_dbus_get_method_args(call, DBUS_TYPE_STRING, &internal_name, DBUS_TYPE_INVALID))
{
/* The method call had invalid arguments meaning that
* get_method_args() has constructed an error for us.
*/
goto exit;
}
type = DBUS_TYPE_BOOLEAN;
arg.boolean = jack_controller_unload_internal(controller_ptr, internal_name) ? TRUE : FALSE;
}
else
{
return false;
@ -245,6 +273,16 @@ JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(LoadInternal)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("result", "b", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnlooadInternal)
JACK_DBUS_METHOD_ARGUMENT("internal", "s", false)
JACK_DBUS_METHOD_ARGUMENT("result", "b", true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHODS_BEGIN
JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL)
JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL)
@ -257,6 +295,8 @@ JACK_DBUS_METHODS_BEGIN
JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL)
JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL)
JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL)
JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL)
JACK_DBUS_METHOD_DESCRIBE(UnlooadInternal, NULL)
JACK_DBUS_METHODS_END
JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(ServerStarted)

View File

@ -58,6 +58,11 @@ jackctl_driver_t *
jack_controller_find_driver(
jackctl_server_t *server,
const char *driver_name);
jackctl_internal_t *
jack_controller_find_internal(
jackctl_server_t *server,
const char *internal_name);
jackctl_parameter_t *
jack_controller_find_parameter(
@ -79,12 +84,28 @@ jack_controller_select_driver(
struct jack_controller *controller_ptr,
const char * driver_name);
bool
jack_controller_load_internal(
struct jack_controller *controller_ptr,
const char * internal_name);
bool
jack_controller_unload_internal(
struct jack_controller *controller_ptr,
const char * internal_name);
void
jack_controller_settings_set_driver_option(
jackctl_driver_t *driver,
const char *option_name,
const char *option_value);
void
jack_controller_settings_set_internal_option(
jackctl_internal_t *internal,
const char *option_name,
const char *option_value);
void
jack_controller_settings_set_engine_option(
struct jack_controller *controller_ptr,
@ -110,6 +131,12 @@ jack_controller_settings_save_driver_options(
jackctl_driver_t *driver,
void *dbus_call_context_ptr);
bool
jack_controller_settings_save_internal_options(
void *context,
jackctl_internal_t *internal,
void *dbus_call_context_ptr);
bool
jack_controller_patchbay_init(
struct jack_controller *controller_ptr);

View File

@ -339,6 +339,57 @@ jack_dbus_get_method_args_string_and_variant(
return false;
}
/*
* Read two strings and a variant argument from a method call.
* If the operation fails construct an error and return false,
* otherwise return true.
*/
bool
jack_dbus_get_method_args_two_strings_and_variant(
struct jack_dbus_method_call *call,
const char **arg1,
const char **arg2,
message_arg_t *arg3,
int *type_ptr)
{
DBusMessageIter iter, sub_iter;
/* First we want a string... */
if (dbus_message_iter_init (call->message, &iter)
&& dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
{
dbus_message_iter_get_basic (&iter, arg1);
dbus_message_iter_next (&iter);
/* ...and then a second string. */
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
{
return false;
}
/* Got what we wanted. */
dbus_message_iter_get_basic (&iter, arg2);
dbus_message_iter_next (&iter);
/* ...and then a variant. */
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_VARIANT)
{
dbus_message_iter_recurse (&iter, &sub_iter);
dbus_message_iter_get_basic (&sub_iter, arg3);
*type_ptr = dbus_message_iter_get_arg_type (&sub_iter);
/* Got what we wanted. */
return true;
}
}
jack_dbus_error (call, JACK_DBUS_ERROR_INVALID_ARGS,
"Invalid arguments to method \"%s\"",
call->method_name);
return false;
}
/*
* Append a variant type to a D-Bus message.
* Return false if something fails, true otherwise.

View File

@ -50,6 +50,7 @@ jack_controller_settings_uninit();
#define JACK_DBUS_ERROR_NEED_DRIVER "org.jackaudio.Error.NeedDriver"
#define JACK_DBUS_ERROR_UNKNOWN_DRIVER_PARAMETER "org.jackaudio.Error.UnknownDriverParameter"
#define JACK_DBUS_ERROR_UNKNOWN_ENGINE_PARAMETER "org.jackaudio.Error.UnknownEngineParameter"
#define JACK_DBUS_ERROR_UNKNOWN_INTERNAL "org.jackaudio.Error.UnknownInternal"
#define JACK_DBUS_ERROR_INVALID_ARGS "org.jackaudio.Error.InvalidArgs"
#define JACK_DBUS_ERROR_GENERIC "org.jackaudio.Error.Generic"
#define JACK_DBUS_ERROR_FATAL "org.jackaudio.Error.Fatal"
@ -245,6 +246,14 @@ jack_dbus_get_method_args_string_and_variant(
message_arg_t *arg2,
int *type_ptr);
bool
jack_dbus_get_method_args_two_strings_and_variant(
struct jack_dbus_method_call *call,
const char **arg1,
const char **arg2,
message_arg_t *arg3,
int *type_ptr);
bool
jack_dbus_message_append_variant(
DBusMessageIter *iter,

View File

@ -153,6 +153,62 @@ jack_controller_settings_set_driver_option(
jackctl_parameter_set_value(parameter, &value);
}
void
jack_controller_settings_set_internal_option(
jackctl_internal_t *internal,
const char *option_name,
const char *option_value)
{
jackctl_parameter_t *parameter;
jackctl_param_type_t type;
int value_int;
unsigned int value_uint;
union jackctl_parameter_value value;
jack_info("setting internal option \"%s\" to value \"%s\"", option_name, option_value);
parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), option_name);
if (parameter == NULL)
{
jack_error(
"Unknown parameter \"%s\" of internal \"%s\"",
option_name,
jackctl_internal_get_name(internal));
return;
}
type = jackctl_parameter_get_type(parameter);
switch (type)
{
case JackParamInt:
jack_controller_settings_set_sint_option(option_value, &value_int);
value.i = value_int;
break;
case JackParamUInt:
jack_controller_settings_set_uint_option(option_value, &value_uint);
value.ui = value_uint;
break;
case JackParamChar:
jack_controller_settings_set_char_option(option_value, &value.c);
break;
case JackParamString:
jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str));
break;
case JackParamBool:
jack_controller_settings_set_bool_option(option_value, &value_int);
value.i = value_int;
break;
default:
jack_error("Parameter \"%s\" of internal \"%s\" is of unknown type %d",
jackctl_parameter_get_name(parameter),
jackctl_internal_get_name(internal),
type);
}
jackctl_parameter_set_value(parameter, &value);
}
void
jack_controller_settings_set_engine_option(
struct jack_controller *controller_ptr,
@ -315,3 +371,12 @@ jack_controller_settings_save_driver_options(
{
return jack_controller_settings_save_options(context, jackctl_driver_get_parameters(driver), dbus_call_context_ptr);
}
bool
jack_controller_settings_save_internal_options(
void *context,
jackctl_internal_t *internal,
void *dbus_call_context_ptr)
{
return jack_controller_settings_save_options(context, jackctl_internal_get_parameters(internal), dbus_call_context_ptr);
}

View File

@ -46,12 +46,14 @@ jack_controller_settings_uninit()
{
}
#define PARSE_CONTEXT_ROOT 0
#define PARSE_CONTEXT_JACK 1
#define PARSE_CONTEXT_ENGINE 1
#define PARSE_CONTEXT_DRIVERS 2
#define PARSE_CONTEXT_DRIVER 3
#define PARSE_CONTEXT_OPTION 4
#define PARSE_CONTEXT_ROOT 0
#define PARSE_CONTEXT_JACK 1
#define PARSE_CONTEXT_ENGINE 1
#define PARSE_CONTEXT_DRIVERS 2
#define PARSE_CONTEXT_DRIVER 3
#define PARSE_CONTEXT_OPTION 4
#define PARSE_CONTEXT_INTERNALS 5
#define PARSE_CONTEXT_INTERNAL 6
#define MAX_STACK_DEPTH 10
@ -62,6 +64,7 @@ struct parse_context
unsigned int element[MAX_STACK_DEPTH];
signed int depth;
jackctl_driver_t *driver;
jackctl_internal_t *internal;
char option[JACK_PARAM_STRING_MAX+1];
int option_used;
char *name;
@ -95,6 +98,7 @@ void
jack_controller_settings_callback_elstart(void *data, const char *el, const char **attr)
{
jackctl_driver_t *driver;
jackctl_internal_t *internal;
if (context_ptr->error)
{
@ -128,6 +132,13 @@ jack_controller_settings_callback_elstart(void *data, const char *el, const char
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVERS;
return;
}
if (strcmp(el, "internals") == 0)
{
//jack_info("<internals>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_INTERNALS;
return;
}
if (strcmp(el, "driver") == 0)
{
@ -155,6 +166,34 @@ jack_controller_settings_callback_elstart(void *data, const char *el, const char
return;
}
if (strcmp(el, "internal") == 0)
{
if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0)
{
jack_error("<driver> XML element must contain exactly one attribute, named \"name\"");
context_ptr->error = XML_TRUE;
return;
}
//jack_info("<internal>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_INTERNAL;
internal = jack_controller_find_internal(context_ptr->controller_ptr->server, attr[1]);
if (internal == NULL)
{
jack_error("ignoring settings for unknown internal \"%s\"", attr[1]);
}
else
{
jack_info("setting for internal \"%s\" found", attr[1]);
}
context_ptr->internal = internal;
return;
}
if (strcmp(el, "option") == 0)
{
@ -212,6 +251,15 @@ jack_controller_settings_callback_elend(void *data, const char *el)
{
jack_controller_settings_set_driver_option(context_ptr->driver, context_ptr->name, context_ptr->option);
}
if (context_ptr->depth == 3 &&
context_ptr->element[0] == PARSE_CONTEXT_JACK &&
context_ptr->element[1] == PARSE_CONTEXT_INTERNALS &&
context_ptr->element[2] == PARSE_CONTEXT_INTERNAL &&
context_ptr->internal != NULL)
{
jack_controller_settings_set_internal_option(context_ptr->internal, context_ptr->name, context_ptr->option);
}
}
context_ptr->depth--;

View File

@ -215,6 +215,87 @@ jack_controller_settings_write_drivers(
return true;
}
bool
jack_controller_settings_write_internal(
struct jack_controller * controller_ptr,
xmlTextWriterPtr writer,
jackctl_internal internal,
void *dbus_call_context_ptr)
{
/* if (xmlTextWriterWriteComment(writer, BAD_CAST "driver parameters") == -1) */
/* { */
/* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
/* return false; */
/* } */
if (xmlTextWriterStartElement(writer, BAD_CAST "internal") == -1)
{
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
return false;
}
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST jackctl_internal_get_name(driver)) == -1)
{
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
return false;
}
if (!jack_controller_settings_save_internal_options(writer, internal, dbus_call_context_ptr))
{
return false;
}
if (xmlTextWriterEndElement(writer) == -1)
{
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
return false;
}
return true;
}
bool
jack_controller_settings_write_internals(
struct jack_controller * controller_ptr,
xmlTextWriterPtr writer,
void *dbus_call_context_ptr)
{
const JSList * node_ptr;
jackctl_driver internal;
if (xmlTextWriterStartElement(writer, BAD_CAST "internals") == -1)
{
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
return false;
}
node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
while (node_ptr != NULL)
{
internal = (jackctl_internal)node_ptr->data;
if (!jack_controller_settings_write_internal(
controller_ptr,
writer,
internal,
dbus_call_context_ptr))
{
return false;
}
node_ptr = jack_slist_next(node_ptr);
}
if (xmlTextWriterEndElement(writer) == -1)
{
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
return false;
}
return true;
}
bool
jack_controller_settings_save(
struct jack_controller * controller_ptr,
@ -295,6 +376,11 @@ jack_controller_settings_save(
{
goto fail_free_writter;
}
if (!jack_controller_settings_write_internals(controller_ptr, writer, dbus_call_context_ptr))
{
goto fail_free_writter;
}
if (xmlTextWriterEndElement(writer) == -1)
{
@ -466,6 +552,91 @@ exit:
return;
}
void
jack_controller_settings_read_internal(
struct jack_controller * controller_ptr,
xmlXPathContextPtr xpath_ctx_ptr,
jackctl_internal internal)
{
char *xpath;
size_t xpath_len;
xmlXPathObjectPtr xpath_obj_ptr;
xmlBufferPtr content_buffer_ptr;
int i;
const char *option_name;
const char *option_value;
const char *internal_name;
internal_name = jackctl_internal_get_name(internal);
jack_info("reading options for internal \"%s\"", internal_name);
xpath_len = snprintf(NULL, 0, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
xpath = malloc(xpath_len);
if (xpath == NULL)
{
jack_error("Out of memory.");
goto exit;
}
snprintf(xpath, xpath_len, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
//jack_info("xpath = \"%s\"", xpath);
/* Evaluate xpath expression */
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_ctx_ptr);
if (xpath_obj_ptr == NULL)
{
jack_error("Unable to evaluate XPath expression \"%s\"", xpath);
goto free_xpath;
}
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
{
//jack_info("XPath \"%s\" evaluation returned no data", xpath);
goto free_xpath_obj;
}
content_buffer_ptr = xmlBufferCreate();
if (content_buffer_ptr == NULL)
{
jack_error("xmlBufferCreate() failed.");
goto free_xpath_obj;
}
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
{
//jack_info("driver option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
{
jack_error("xmlNodeBufGetContent() failed.");
goto next_option;
}
option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
option_value = (const char *)xmlBufferContent(content_buffer_ptr);
jack_controller_settings_set_internal_option(internal, option_name, option_value);
next_option:
xmlBufferEmpty(content_buffer_ptr);
}
//free_buffer:
xmlBufferFree(content_buffer_ptr);
free_xpath_obj:
xmlXPathFreeObject(xpath_obj_ptr);
free_xpath:
free(xpath);
exit:
return;
}
void
jack_controller_settings_read_drivers(
struct jack_controller * controller_ptr,
@ -514,6 +685,55 @@ exit:
return;
}
void
jack_controller_settings_read_internals(
struct jack_controller * controller_ptr,
xmlXPathContextPtr xpath_ctx_ptr)
{
xmlXPathObjectPtr xpath_obj_ptr;
int i;
const char *internal_name;
jackctl_internal internal;
/* Evaluate xpath expression */
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_DRIVERS_EXPRESSION, xpath_ctx_ptr);
if (xpath_obj_ptr == NULL)
{
jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_DRIVERS_EXPRESSION);
goto exit;
}
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
{
jack_error("XPath \"%s\" evaluation returned no data", XPATH_DRIVERS_EXPRESSION);
goto free_xpath_obj;
}
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
{
internal_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
driver = jack_controller_find_internal(controller_ptr->server, driver_name);
if (driver == NULL)
{
jack_error("ignoring settings for unknown internal \"%s\"", internal_name);
}
else
{
jack_info("setting for internal \"%s\" found", internal_name);
jack_controller_settings_read_internal(controller_ptr, xpath_ctx_ptr, driver);
}
}
free_xpath_obj:
xmlXPathFreeObject(xpath_obj_ptr);
exit:
return;
}
void
jack_controller_settings_load(
struct jack_controller * controller_ptr)
@ -555,6 +775,7 @@ jack_controller_settings_load(
jack_controller_settings_read_engine(controller_ptr, xpath_ctx_ptr);
jack_controller_settings_read_drivers(controller_ptr, xpath_ctx_ptr);
jack_controller_settings_read_internals(controller_ptr, xpath_ctx_ptr);
xmlXPathFreeContext(xpath_ctx_ptr);

View File

@ -116,6 +116,7 @@ jack_controller_settings_save(
struct save_context context;
const JSList * node_ptr;
jackctl_driver_t *driver;
jackctl_internal_t *internal;
time(&timestamp);
ctime_r(&timestamp, timestamp_str);
@ -186,6 +187,8 @@ jack_controller_settings_save(
{
goto exit_close;
}
/* engine */
if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
{
@ -203,6 +206,8 @@ jack_controller_settings_save(
goto exit_close;
}
/* drivers */
if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr))
{
goto exit_close;
@ -248,6 +253,54 @@ jack_controller_settings_save(
{
goto exit_close;
}
/* internals */
if (!jack_controller_settings_write_string(fd, " <internals>\n", dbus_call_context_ptr))
{
goto exit_close;
}
node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
while (node_ptr != NULL)
{
internal = (jackctl_internal_t *)node_ptr->data;
if (!jack_controller_settings_write_string(fd, " <internal name=\"", dbus_call_context_ptr))
{
goto exit_close;
}
if (!jack_controller_settings_write_string(fd, jackctl_internal_get_name(internal), dbus_call_context_ptr))
{
goto exit_close;
}
if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
{
goto exit_close;
}
context.indent = " ";
if (!jack_controller_settings_save_internal_options(&context, internal, dbus_call_context_ptr))
{
goto exit_close;
}
if (!jack_controller_settings_write_string(fd, " </internal>\n", dbus_call_context_ptr))
{
goto exit_close;
}
node_ptr = jack_slist_next(node_ptr);
}
if (!jack_controller_settings_write_string(fd, " </internal>\n", dbus_call_context_ptr))
{
goto exit_close;
}
if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
{