git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2866 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -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. | |||
| @@ -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: | |||
| @@ -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 | |||
| @@ -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, ¶meter_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, ¶meter_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, ¶meter_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") | |||
| @@ -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) | |||
| @@ -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); | |||
| @@ -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. | |||
| @@ -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, | |||
| @@ -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); | |||
| } | |||
| @@ -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--; | |||
| @@ -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); | |||
| @@ -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(×tamp); | |||
| ctime_r(×tamp, 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)) | |||
| { | |||