diff --git a/dbus/controller.c b/dbus/controller.c index e0abd258..15afe65a 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008,2010 Nedko Arnaudov + Copyright (C) 2007,2008,2010,2011 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify @@ -159,19 +159,13 @@ jack_controller_select_driver( struct jack_controller * controller_ptr, const char * driver_name) { - jackctl_driver_t *driver; - - driver = jack_controller_find_driver(controller_ptr->server, driver_name); - if (driver == NULL) + if (!jack_params_set_driver(controller_ptr->params, driver_name)) { return false; } jack_info("driver \"%s\" selected", driver_name); - controller_ptr->driver = driver; - controller_ptr->driver_set = true; - return true; } @@ -195,17 +189,11 @@ jack_controller_start_server( assert(!controller_ptr->started); /* should be ensured by caller */ - if (controller_ptr->driver == NULL) - { - jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Select driver first!"); - goto fail; - } - controller_ptr->xruns = 0; if (!jackctl_server_open( controller_ptr->server, - controller_ptr->driver)) + jack_params_get_driver(controller_ptr->params))) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server"); goto fail; @@ -337,12 +325,13 @@ jack_controller_switch_master( { if (!jackctl_server_switch_master( controller_ptr->server, - controller_ptr->driver)) + jack_params_get_driver(controller_ptr->params))) { jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to switch master"); return FALSE; } + return TRUE; } @@ -413,11 +402,6 @@ jack_controller_create( DBusConnection *connection) { struct jack_controller *controller_ptr; - const JSList * node_ptr; - const char ** driver_name_target; - const char ** internal_name_target; - JSList * drivers; - JSList * internals; DBusObjectPathVTable vtable = { jack_dbus_message_handler_unregister, @@ -439,54 +423,16 @@ jack_controller_create( goto fail_free; } - controller_ptr->client = NULL; - controller_ptr->started = false; - controller_ptr->driver = NULL; - controller_ptr->driver_set = false; - INIT_LIST_HEAD(&controller_ptr->slave_drivers); - - drivers = (JSList *)jackctl_server_get_drivers_list(controller_ptr->server); - controller_ptr->drivers_count = jack_slist_length(drivers); - controller_ptr->driver_names = malloc(controller_ptr->drivers_count * sizeof(const char *)); - if (controller_ptr->driver_names == NULL) + controller_ptr->params = jack_params_create(controller_ptr->server); + if (controller_ptr->params == NULL) { - jack_error("Ran out of memory trying to allocate driver names array"); + jack_error("Failed to initialize parameter tree"); goto fail_destroy_server; } - driver_name_target = controller_ptr->driver_names; - node_ptr = jackctl_server_get_drivers_list(controller_ptr->server); - while (node_ptr != NULL) - { - *driver_name_target = jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data); - - /* select default driver */ - if (controller_ptr->driver == NULL && strcmp(*driver_name_target, DEFAULT_DRIVER) == 0) - { - controller_ptr->driver = (jackctl_driver_t *)node_ptr->data; - } - - node_ptr = jack_slist_next(node_ptr); - driver_name_target++; - } - - internals = (JSList *)jackctl_server_get_internals_list(controller_ptr->server); - controller_ptr->internals_count = jack_slist_length(internals); - controller_ptr->internal_names = malloc(controller_ptr->internals_count * sizeof(const char *)); - if (controller_ptr->internal_names == NULL) - { - jack_error("Ran out of memory trying to allocate internals names array"); - goto fail_free_driver_names_array; - } - - internal_name_target = controller_ptr->internal_names; - node_ptr = jackctl_server_get_internals_list(controller_ptr->server); - while (node_ptr != NULL) - { - *internal_name_target = jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data); - node_ptr = jack_slist_next(node_ptr); - internal_name_target++; - } + controller_ptr->client = NULL; + controller_ptr->started = false; + INIT_LIST_HEAD(&controller_ptr->slave_drivers); controller_ptr->dbus_descriptor.context = controller_ptr; controller_ptr->dbus_descriptor.interfaces = g_jackcontroller_interfaces; @@ -498,18 +444,15 @@ jack_controller_create( &controller_ptr->dbus_descriptor)) { jack_error("Ran out of memory trying to register D-Bus object path"); - goto fail_free_internal_names_array; + goto fail_destroy_params; } jack_controller_settings_load(controller_ptr); return controller_ptr; -fail_free_internal_names_array: - free(controller_ptr->internal_names); - -fail_free_driver_names_array: - free(controller_ptr->driver_names); +fail_destroy_params: + jack_params_destroy(controller_ptr->params); fail_destroy_server: jackctl_server_destroy(controller_ptr->server); @@ -623,9 +566,7 @@ jack_controller_destroy( jack_controller_stop_server(controller_ptr, NULL); } - free(controller_ptr->driver_names); - free(controller_ptr->internal_names); - + jack_params_destroy(controller_ptr->params); jackctl_server_destroy(controller_ptr->server); free(controller_ptr); diff --git a/dbus/controller_iface_configure.c b/dbus/controller_iface_configure.c index f4b6d46f..7e3a8fd9 100644 --- a/dbus/controller_iface_configure.c +++ b/dbus/controller_iface_configure.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2011 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify @@ -31,24 +31,6 @@ #include "controller_internal.h" #include "xml.h" -#define PTNODE_ENGINE "engine" -#define PTNODE_DRIVER "driver" -#define PTNODE_DRIVERS "drivers" -#define PTNODE_INTERNALS "internals" - -#define ENGINE_DRIVER_PARAMETER_NAME "driver" -#define ENGINE_DRIVER_PARAMETER_TYPE JackParamString -#define ENGINE_DRIVER_PARAMETER_SHORT_DESCR "Driver to use" -#define ENGINE_DRIVER_PARAMETER_LONG_DESCR "" - -struct parameter_info -{ - unsigned char type; - const char * name; - const char * short_decr; - const char * long_descr; -}; - unsigned char jack_controller_dbus_types[JACK_PARAM_MAX] = { [JackParamInt] = DBUS_TYPE_INT32, @@ -238,12 +220,13 @@ jack_controller_dbus_get_parameter_address_ex( index = 0; while ((type = dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID) { - if (index == 3) + if (index == PARAM_ADDRESS_SIZE) { jack_dbus_error( call, JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid arguments to method '%s'. Parameter address array must contain not more than three elements.", + "Invalid arguments to method '%s'. Parameter address array must contain not more than %u elements.", + (unsigned int)PARAM_ADDRESS_SIZE, call->method_name); return false; } @@ -267,7 +250,7 @@ jack_controller_dbus_get_parameter_address_ex( index++; } - while (index < 3) + while (index < PARAM_ADDRESS_SIZE) { address_array[index] = NULL; index++; @@ -301,45 +284,9 @@ jack_controller_dbus_get_parameter_address( #define controller_ptr ((struct jack_controller *)call->context) -static -bool -jack_controller_fill_parameter_names( - struct jack_dbus_method_call * call, - DBusMessageIter * iter_ptr, - const char * special_first, - const JSList * parameters_list) +static bool append_node_name(void * context, const char * name) { - DBusMessageIter array_iter; - const char * param_name; - - if (!dbus_message_iter_open_container(iter_ptr, DBUS_TYPE_ARRAY, "s", &array_iter)) - { - return false; - } - - if (special_first != NULL) - { - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &special_first)) - { - dbus_message_iter_close_container(iter_ptr, &array_iter); - return false; - } - } - - /* Append parameter descriptions to the array. */ - while (parameters_list != NULL) - { - param_name = jackctl_parameter_get_name(parameters_list->data); - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, ¶m_name)) - { - dbus_message_iter_close_container(iter_ptr, &array_iter); - return false; - } - - parameters_list = jack_slist_next(parameters_list); - } - - return dbus_message_iter_close_container(iter_ptr, &array_iter); + return dbus_message_iter_append_basic(context, DBUS_TYPE_STRING, &name); } static @@ -347,14 +294,10 @@ void jack_controller_dbus_read_container( struct jack_dbus_method_call * call) { - const char * address[3]; + const char * address[PARAM_ADDRESS_SIZE]; dbus_bool_t leaf; DBusMessageIter iter; DBusMessageIter array_iter; - const char * child_name; - unsigned int index; - jackctl_internal_t * internal; - jackctl_driver_t * driver; //jack_info("jack_controller_dbus_read_container() called"); @@ -377,218 +320,37 @@ jack_controller_dbus_read_container( dbus_message_iter_init_append(call->reply, &iter); - if (address[0] == NULL) /* root node */ + if (!jack_params_check_address(controller_ptr->params, address, false)) { - //jack_info("reading root container"); - - leaf = false; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) - { - goto oom_unref; - } - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter)) - { - goto oom_unref; - } - - child_name = PTNODE_ENGINE; - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name)) - { - goto oom_close_unref; - } - - child_name = PTNODE_DRIVER; - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name)) - { - goto oom_close_unref; - } - - child_name = PTNODE_DRIVERS; - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name)) - { - goto oom_close_unref; - } - - child_name = PTNODE_INTERNALS; - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name)) - { - goto oom_close_unref; - } - - dbus_message_iter_close_container(&iter, &array_iter); - + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); return; } - if (address[0] != NULL && - address[1] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ + leaf = jack_params_is_leaf_container(controller_ptr->params, address); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) { - //jack_info("reading engine params container"); - - leaf = true; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) - { - goto oom_unref; - } - - if (!jack_controller_fill_parameter_names( - call, - &iter, - ENGINE_DRIVER_PARAMETER_NAME, - jackctl_server_get_parameters(controller_ptr->server))) - { - goto oom_unref; - } - - return; + goto oom_unref; } - if (address[0] != NULL && - address[1] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter)) { - //jack_info("reading current driver params container"); - - leaf = true; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) - { - goto oom_unref; - } - - if (!jack_controller_fill_parameter_names( - call, - &iter, - NULL, - jackctl_driver_get_parameters(controller_ptr->driver))) - { - goto oom_unref; - } - - return; + goto oom_unref; } - if (address[0] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) - { - leaf = address[1] != NULL; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) - { - goto oom_unref; - } - - if (!leaf) /* available drivers requested */ - { - //jack_info("reading drivers container"); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter)) - { - goto oom_unref; - } - - for (index = 0; index < controller_ptr->drivers_count; index++) - { - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, controller_ptr->driver_names + index)) - { - goto oom_close_unref; - } - } - - dbus_message_iter_close_container(&iter, &array_iter); - } - else /* specified driver parameters requested */ - { - //jack_info("reading driver '%s' params container", address[1]); - - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - if (!jack_controller_fill_parameter_names( - call, - &iter, - NULL, - jackctl_driver_get_parameters(driver))) - { - goto oom_unref; - } - } - - return; - } - - if (address[0] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) + if (!jack_params_iterate_container(controller_ptr->params, address, append_node_name, &array_iter)) { - leaf = address[1] != NULL; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf)) - { - goto oom_unref; - } - - if (!leaf) /* available internals requested */ - { - //jack_info("reading internals container"); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter)) - { - goto oom_unref; - } - - for (index = 0; index < controller_ptr->internals_count; index++) - { - if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, controller_ptr->internal_names + index)) - { - goto oom_close_unref; - } - } - - dbus_message_iter_close_container(&iter, &array_iter); - } - else /* specified driver parameters requested */ - { - //jack_info("reading internal '%s' params container", address[1]); - - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - if (!jack_controller_fill_parameter_names( - call, - &iter, - NULL, - jackctl_internal_get_parameters(internal))) - { - goto oom_unref; - } - } - - return; + goto oom_close_unref; } - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); + dbus_message_iter_close_container(&iter, &array_iter); return; @@ -603,60 +365,44 @@ oom: jack_error ("Ran out of memory trying to construct method return"); } -static -void -jack_controller_fill_parameter_info( - jackctl_parameter_t * parameter, - struct parameter_info * info_ptr) -{ - info_ptr->type = jackctl_parameter_get_type(parameter); - info_ptr->name = jackctl_parameter_get_name(parameter); - info_ptr->short_decr = jackctl_parameter_get_short_description(parameter); - info_ptr->long_descr = jackctl_parameter_get_long_description(parameter); -} - -static -bool -jack_controller_append_parameter_info_struct( - DBusMessageIter * iter_ptr, - struct parameter_info * info_ptr) +static bool append_parameter(void * context, const struct jack_parameter * param_ptr) { DBusMessageIter struct_iter; unsigned char type; /* Open the struct. */ - if (!dbus_message_iter_open_container(iter_ptr, DBUS_TYPE_STRUCT, NULL, &struct_iter)) + if (!dbus_message_iter_open_container(context, DBUS_TYPE_STRUCT, NULL, &struct_iter)) { goto fail; } /* Append parameter type. */ - type = PARAM_TYPE_JACK_TO_DBUS(info_ptr->type); + type = PARAM_TYPE_JACK_TO_DBUS(param_ptr->type); if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE, &type)) { goto fail_close; } /* Append parameter name. */ - if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->name)) + if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, ¶m_ptr->name)) { goto fail_close; } /* Append parameter short description. */ - if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->short_decr)) + if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, ¶m_ptr->short_decr)) { goto fail_close; } /* Append parameter long description. */ - if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->long_descr)) + if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, ¶m_ptr->long_descr)) { goto fail_close; } /* Close the struct. */ - if (!dbus_message_iter_close_container(iter_ptr, &struct_iter)) + if (!dbus_message_iter_close_container(context, &struct_iter)) { goto fail; } @@ -664,7 +410,7 @@ jack_controller_append_parameter_info_struct( return true; fail_close: - dbus_message_iter_close_container(iter_ptr, &struct_iter); + dbus_message_iter_close_container(context, &struct_iter); fail: return false; @@ -672,13 +418,36 @@ fail: static void -jack_controller_get_parameters_info( - struct jack_dbus_method_call * call, - struct parameter_info * special_parameter_info_ptr, - const JSList * parameters_list) +jack_controller_dbus_get_parameters_info( + struct jack_dbus_method_call * call) { + const char * address[PARAM_ADDRESS_SIZE]; DBusMessageIter iter, array_iter; - struct parameter_info info; + + //jack_info("jack_controller_dbus_get_parameters_info() called"); + + if (!jack_controller_dbus_get_parameter_address(call, address)) + { + /* The method call had invalid arguments meaning that + * jack_controller_dbus_get_parameter_address() has + * constructed an error for us. */ + return; + } + + //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); + + if (!jack_params_check_address(controller_ptr->params, address, true)) + { + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); + return; + } call->reply = dbus_message_new_method_return (call->message); if (!call->reply) @@ -694,24 +463,9 @@ jack_controller_get_parameters_info( goto fail_unref; } - if (special_parameter_info_ptr != NULL) - { - if (!jack_controller_append_parameter_info_struct(&array_iter, special_parameter_info_ptr)) - { - goto fail_close_unref; - } - } - - /* Append parameter descriptions to the array. */ - while (parameters_list != NULL) + if (!jack_params_iterate_params(controller_ptr->params, address, append_parameter, &array_iter)) { - jack_controller_fill_parameter_info(parameters_list->data, &info); - if (!jack_controller_append_parameter_info_struct(&array_iter, &info)) - { - goto fail_close_unref; - } - - parameters_list = jack_slist_next(parameters_list); + goto fail_close_unref; } /* Close the array. */ @@ -735,15 +489,14 @@ fail: static void -jack_controller_dbus_get_parameters_info( +jack_controller_dbus_get_parameter_info( struct jack_dbus_method_call * call) { - const char * address[3]; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - struct parameter_info driver_parameter_info; + const char * address[PARAM_ADDRESS_SIZE]; + const struct jack_parameter * param_ptr; + DBusMessageIter iter; - //jack_info("jack_controller_dbus_get_parameters_info() called"); + //jack_info("jack_controller_dbus_get_parameter_info() called"); if (!jack_controller_dbus_get_parameter_address(call, address)) { @@ -755,101 +508,20 @@ jack_controller_dbus_get_parameters_info( //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); - if (address[0] != NULL && - address[1] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ - { - driver_parameter_info.type = ENGINE_DRIVER_PARAMETER_TYPE; - driver_parameter_info.name = ENGINE_DRIVER_PARAMETER_NAME; - driver_parameter_info.short_decr = ENGINE_DRIVER_PARAMETER_SHORT_DESCR; - driver_parameter_info.long_descr = ENGINE_DRIVER_PARAMETER_LONG_DESCR; - - jack_controller_get_parameters_info( - call, - &driver_parameter_info, - jackctl_server_get_parameters(controller_ptr->server)); - - return; - } - - if (address[0] != NULL && - address[1] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ - { - jack_controller_get_parameters_info( - call, - NULL, - jackctl_driver_get_parameters(controller_ptr->driver)); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) - { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - - jack_controller_get_parameters_info( - call, - NULL, - jackctl_driver_get_parameters(driver)); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - jack_controller_get_parameters_info( + jack_dbus_error( call, - NULL, - jackctl_internal_get_parameters(internal)); - + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); return; } - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); -} - -static -void -jack_controller_get_parameter_info_ex( - struct jack_dbus_method_call * call, - struct parameter_info * info_ptr) -{ - DBusMessageIter iter; - call->reply = dbus_message_new_method_return(call->message); if (!call->reply) { @@ -858,7 +530,7 @@ jack_controller_get_parameter_info_ex( dbus_message_iter_init_append(call->reply, &iter); - if (!jack_controller_append_parameter_info_struct(&iter, info_ptr)) + if (!append_parameter(&iter, param_ptr)) { goto fail_unref; } @@ -875,28 +547,17 @@ fail: static void -jack_controller_get_parameter_info( - struct jack_dbus_method_call * call, - jackctl_parameter_t * parameter) -{ - struct parameter_info info; - - jack_controller_fill_parameter_info(parameter, &info); - jack_controller_get_parameter_info_ex(call, &info); -} - -static -void -jack_controller_dbus_get_parameter_info( +jack_controller_dbus_get_parameter_constraint( struct jack_dbus_method_call * call) { - const char * address[3]; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - jackctl_parameter_t * parameter; - struct parameter_info driver_parameter_info; + const char * address[PARAM_ADDRESS_SIZE]; + const struct jack_parameter * param_ptr; + uint32_t index; + DBusMessageIter iter, array_iter, struct_iter; + const char * descr; + message_arg_t value; - //jack_info("jack_controller_dbus_get_parameter_info() called"); + //jack_info("jack_controller_dbus_get_parameter_constraint() called"); if (!jack_controller_dbus_get_parameter_address(call, address)) { @@ -908,178 +569,57 @@ jack_controller_dbus_get_parameter_info( //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) { - if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0) - { - driver_parameter_info.type = ENGINE_DRIVER_PARAMETER_TYPE; - driver_parameter_info.name = ENGINE_DRIVER_PARAMETER_NAME; - driver_parameter_info.short_decr = ENGINE_DRIVER_PARAMETER_SHORT_DESCR; - driver_parameter_info.long_descr = ENGINE_DRIVER_PARAMETER_LONG_DESCR; - - jack_controller_get_parameter_info_ex(call, &driver_parameter_info); - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown engine parameter '%s'", - address[1]); - return; - } - - jack_controller_get_parameter_info(call, parameter); - + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); return; } - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ + call->reply = dbus_message_new_method_return(call->message); + if (!call->reply) { - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[1], - jackctl_driver_get_name(controller_ptr->driver)); - return; - } + goto fail; + } - jack_controller_get_parameter_info(call, parameter); + dbus_message_iter_init_append(call->reply, &iter); - return; + if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0) + { + value.boolean = param_ptr->constraint_range; } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) + else { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } + value.boolean = false; + } - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_info(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value)) { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for internal '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_info(call, parameter); - - return; + goto fail_unref; } - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); -} - -static -void -jack_controller_get_parameter_constraint( - struct jack_dbus_method_call * call, - jackctl_parameter_t * parameter) -{ - uint32_t index; - uint32_t count; - union jackctl_parameter_value min; - union jackctl_parameter_value max; - union jackctl_parameter_value jackctl_value; - DBusMessageIter iter, array_iter, struct_iter; - const char * descr; - jackctl_param_type_t type; - message_arg_t value; - bool is_range; - - type = jackctl_parameter_get_type(parameter); - - call->reply = dbus_message_new_method_return(call->message); - if (!call->reply) + if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0) { - goto fail; + value.boolean = (param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_STRICT) != 0; } - dbus_message_iter_init_append(call->reply, &iter); - - is_range = jackctl_parameter_has_range_constraint(parameter); - value.boolean = is_range; if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value)) { goto fail_unref; } - value.boolean = jackctl_parameter_constraint_is_strict(parameter); - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value)) + if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0) { - goto fail_unref; + value.boolean = (param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0; } - value.boolean = jackctl_parameter_constraint_is_fake_value(parameter); if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value)) { goto fail_unref; @@ -1091,19 +631,26 @@ jack_controller_get_parameter_constraint( goto fail_unref; } - if (is_range) + if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) == 0) { - jackctl_parameter_get_range_constraint(parameter, &min, &max); + goto close; + } + if (param_ptr->constraint_range) + { /* Open the struct. */ if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter)) { goto fail_close_unref; } - jack_controller_jack_to_dbus_variant(type, &min, &value); + jack_controller_jack_to_dbus_variant(param_ptr->type, ¶m_ptr->constraint.range.min, &value); - if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value)) + if (!jack_dbus_message_append_variant( + &struct_iter, + PARAM_TYPE_JACK_TO_DBUS(param_ptr->type), + PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(param_ptr->type), + &value)) { goto fail_close2_unref; } @@ -1127,9 +674,13 @@ jack_controller_get_parameter_constraint( goto fail_close_unref; } - jack_controller_jack_to_dbus_variant(type, &max, &value); + jack_controller_jack_to_dbus_variant(param_ptr->type, ¶m_ptr->constraint.range.max, &value); - if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value)) + if (!jack_dbus_message_append_variant( + &struct_iter, + PARAM_TYPE_JACK_TO_DBUS(param_ptr->type), + PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(param_ptr->type), + &value)) { goto fail_close2_unref; } @@ -1149,15 +700,12 @@ jack_controller_get_parameter_constraint( } else { - count = jackctl_parameter_get_enum_constraints_count(parameter); - /* Append enum values to the array. */ - for (index = 0 ; index < count ; index++) + for (index = 0 ; index < param_ptr->constraint.enumeration.count ; index++) { - jackctl_value = jackctl_parameter_get_enum_constraint_value(parameter, index); - descr = jackctl_parameter_get_enum_constraint_description(parameter, index); + descr = param_ptr->constraint.enumeration.possible_values_array[index].short_desc; - jack_controller_jack_to_dbus_variant(type, &jackctl_value, &value); + jack_controller_jack_to_dbus_variant(param_ptr->type, ¶m_ptr->constraint.enumeration.possible_values_array[index].value, &value); /* Open the struct. */ if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter)) @@ -1165,7 +713,11 @@ jack_controller_get_parameter_constraint( goto fail_close_unref; } - if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value)) + if (!jack_dbus_message_append_variant( + &struct_iter, + PARAM_TYPE_JACK_TO_DBUS(param_ptr->type), + PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(param_ptr->type), + &value)) { goto fail_close2_unref; } @@ -1183,6 +735,7 @@ jack_controller_get_parameter_constraint( } } +close: /* Close the array. */ if (!dbus_message_iter_close_container(&iter, &array_iter)) { @@ -1205,315 +758,17 @@ fail: jack_error ("Ran out of memory trying to construct method return"); } -static -void -jack_controller_get_parameter_constraint_engine_driver( - struct jack_dbus_method_call * call) -{ - unsigned int index; - DBusMessageIter iter, array_iter, struct_iter; - jackctl_param_type_t type; - dbus_bool_t bval; - message_arg_t value; - - type = ENGINE_DRIVER_PARAMETER_TYPE; - - call->reply = dbus_message_new_method_return(call->message); - if (!call->reply) - { - goto fail; - } - - dbus_message_iter_init_append(call->reply, &iter); - - /* is_range */ - bval = false; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval)) - { - goto fail_unref; - } - - /* is_strict */ - bval = true; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval)) - { - goto fail_unref; - } - - /* is_fake_value */ - bval = true; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval)) - { - goto fail_unref; - } - - /* Open the array. */ - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(vs)", &array_iter)) - { - goto fail_unref; - } - - /* Append enum values to the array. */ - for (index = 0 ; index < controller_ptr->drivers_count ; index++) - { - /* Open the struct. */ - if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter)) - { - goto fail_close_unref; - } - - value.string = controller_ptr->driver_names[index]; - if (!jack_dbus_message_append_variant( - &struct_iter, - PARAM_TYPE_JACK_TO_DBUS(type), - PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), - &value)) - { - goto fail_close2_unref; - } - - if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &value)) - { - goto fail_close2_unref; - } - - /* Close the struct. */ - if (!dbus_message_iter_close_container(&array_iter, &struct_iter)) - { - goto fail_close_unref; - } - } - - /* Close the array. */ - if (!dbus_message_iter_close_container(&iter, &array_iter)) - { - goto fail_unref; - } - - return; - -fail_close2_unref: - dbus_message_iter_close_container(&array_iter, &struct_iter); - -fail_close_unref: - dbus_message_iter_close_container(&iter, &array_iter); - -fail_unref: - dbus_message_unref(call->reply); - call->reply = NULL; - -fail: - jack_error ("Ran out of memory trying to construct method return"); -} - -static -void -jack_controller_dbus_get_parameter_constraint( +static void +jack_controller_dbus_get_parameter_value( struct jack_dbus_method_call * call) { - const char * address[3]; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - jackctl_parameter_t * parameter; - - //jack_info("jack_controller_dbus_get_parameter_constraint() called"); - - if (!jack_controller_dbus_get_parameter_address(call, address)) - { - /* The method call had invalid arguments meaning that - * jack_controller_dbus_get_parameter_address() has - * constructed an error for us. */ - return; - } - - //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ - { - if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0) - { - jack_controller_get_parameter_constraint_engine_driver(call); - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown engine parameter '%s'", - address[1]); - return; - } - - jack_controller_get_parameter_constraint(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ - { - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[1], - jackctl_driver_get_name(controller_ptr->driver)); - return; - } - - jack_controller_get_parameter_constraint(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) - { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_constraint(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) - { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for internal '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_constraint(call, parameter); - - return; - } - - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); -} - -static -void -jack_controller_get_parameter_value( - struct jack_dbus_method_call * call, - jackctl_parameter_t * parameter) -{ - int type; + const char * address[PARAM_ADDRESS_SIZE]; + const struct jack_parameter * param_ptr; union jackctl_parameter_value jackctl_value; union jackctl_parameter_value jackctl_default_value; message_arg_t value; message_arg_t default_value; - 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_get_parameter_value_engine_driver( - struct jack_dbus_method_call * call) -{ - message_arg_t value; - message_arg_t default_value; - - default_value.string = DEFAULT_DRIVER; - value.string = jackctl_driver_get_name(controller_ptr->driver); - - /* Construct the reply. */ - jack_dbus_construct_method_return_parameter( - call, - controller_ptr->driver_set, - DBUS_TYPE_STRING, - DBUS_TYPE_STRING_AS_STRING, - default_value, - value); -} - - -static void -jack_controller_dbus_get_parameter_value( - struct jack_dbus_method_call * call) -{ - const char * address[3]; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - jackctl_parameter_t * parameter; - //jack_info("jack_controller_dbus_get_parameter_value() called"); if (!jack_controller_dbus_get_parameter_address(call, address)) @@ -1526,221 +781,34 @@ jack_controller_dbus_get_parameter_value( //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ - { - if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0) - { - jack_controller_get_parameter_value_engine_driver(call); - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown engine parameter '%s'", - address[1]); - return; - } - - jack_controller_get_parameter_value(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ - { - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[1], - jackctl_driver_get_name(controller_ptr->driver)); - return; - } - - jack_controller_get_parameter_value(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) - { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_value(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) - { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for internal '%s'", - address[2], - address[1]); - return; - } - - jack_controller_get_parameter_value(call, parameter); - - return; - } - - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); -} - -static -void -jack_controller_set_parameter_value( - struct jack_dbus_method_call * call, - jackctl_parameter_t * parameter, - message_arg_t * arg_ptr, - int arg_type) -{ - jackctl_param_type_t type; - union jackctl_parameter_value value; - - type = jackctl_parameter_get_type(parameter); - - if (PARAM_TYPE_JACK_TO_DBUS(type) != arg_type) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "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_ptr, - &value)) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Cannot convert parameter value"); - return; - } - - jackctl_parameter_set_value(parameter, &value); - - jack_controller_settings_save_auto(controller_ptr); - - jack_dbus_construct_method_return_empty(call); -} - -static -void -jack_controller_set_parameter_value_engine_driver( - struct jack_dbus_method_call * call, - message_arg_t * arg_ptr, - int arg_type) -{ - union jackctl_parameter_value value; - - if (arg_type != DBUS_TYPE_STRING) + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) { jack_dbus_error( call, JACK_DBUS_ERROR_INVALID_ARGS, - "Engine parameter value type mismatch: was expecting '%c', got '%c'", - (char)DBUS_TYPE_STRING, - (char)arg_type); - return; - } - - if (!jack_controller_dbus_to_jack_variant( - arg_type, - arg_ptr, - &value)) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Cannot convert engine parameter value"); + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); return; } - if (!jack_controller_select_driver(controller_ptr, value.str)) - { - /* Couldn't find driver with the specified name. */ - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_DRIVER, - "Unknown driver '%s'", - value.str); - return; - } + jackctl_default_value = param_ptr->vtable.get_default_value(param_ptr->obj); + jackctl_value = param_ptr->vtable.get_value(param_ptr->obj); - jack_controller_settings_save_auto(controller_ptr); + jack_controller_jack_to_dbus_variant(param_ptr->type, &jackctl_value, &value); + jack_controller_jack_to_dbus_variant(param_ptr->type, &jackctl_default_value, &default_value); - jack_dbus_construct_method_return_empty(call); + /* Construct the reply. */ + jack_dbus_construct_method_return_parameter( + call, + (dbus_bool_t)(param_ptr->vtable.is_set(param_ptr->obj) ? TRUE : FALSE), + PARAM_TYPE_JACK_TO_DBUS(param_ptr->type), + PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(param_ptr->type), + default_value, + value); } static @@ -1748,14 +816,13 @@ void jack_controller_dbus_set_parameter_value( struct jack_dbus_method_call * call) { - const char * address[3]; + const char * address[PARAM_ADDRESS_SIZE]; + const struct jack_parameter * param_ptr; DBusMessageIter iter; DBusMessageIter variant_iter; message_arg_t arg; int arg_type; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - jackctl_parameter_t * parameter; + union jackctl_parameter_value value; //jack_info("jack_controller_dbus_set_parameter_value() called"); @@ -1769,6 +836,20 @@ jack_controller_dbus_set_parameter_value( //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) + { + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); + return; + } + dbus_message_iter_next(&iter); if (dbus_message_iter_has_next(&iter)) @@ -1797,166 +878,35 @@ jack_controller_dbus_set_parameter_value( //jack_info("argument of type '%c'", arg_type); - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ - { - if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0) - { - jack_controller_set_parameter_value_engine_driver(call, &arg, arg_type); - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown engine parameter '%s'", - address[1]); - return; - } - - jack_controller_set_parameter_value(call, parameter, &arg, arg_type); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ - { - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[1], - jackctl_driver_get_name(controller_ptr->driver)); - return; - } - - jack_controller_set_parameter_value(call, parameter, &arg, arg_type); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) - { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[2], - address[1]); - return; - } - - jack_controller_set_parameter_value(call, parameter, &arg, arg_type); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) + if (PARAM_TYPE_JACK_TO_DBUS(param_ptr->type) != arg_type) { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for internal '%s'", - address[2], - address[1]); - return; - } - - jack_controller_set_parameter_value(call, parameter, &arg, arg_type); - + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Parameter value type mismatch: was expecting '%c', got '%c'", + (char)PARAM_TYPE_JACK_TO_DBUS(param_ptr->type), + (char)arg_type); return; } - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); -} - -static -void -jack_controller_reset_parameter_value( - struct jack_dbus_method_call * call, - jackctl_parameter_t * parameter) -{ - jackctl_parameter_reset(parameter); - - jack_controller_settings_save_auto(controller_ptr); - - jack_dbus_construct_method_return_empty(call); -} - -static -void -jack_controller_reset_parameter_value_engine_driver( - struct jack_dbus_method_call * call) -{ - if (!jack_controller_select_driver(controller_ptr, DEFAULT_DRIVER)) + if (!jack_controller_dbus_to_jack_variant( + arg_type, + &arg, + &value)) { - /* Couldn't find driver with the specified name. */ jack_dbus_error( call, - JACK_DBUS_ERROR_UNKNOWN_DRIVER, - "Default driver '%s' is unknown", - DEFAULT_DRIVER); + JACK_DBUS_ERROR_INVALID_ARGS, + "Cannot convert parameter value"); return; } - controller_ptr->driver_set = false; + param_ptr->vtable.set_value(param_ptr->obj, &value); jack_controller_settings_save_auto(controller_ptr); jack_dbus_construct_method_return_empty(call); + } static @@ -1964,10 +914,8 @@ void jack_controller_dbus_reset_parameter_value( struct jack_dbus_method_call * call) { - const char * address[3]; - jackctl_internal_t * internal; - jackctl_driver_t * driver; - jackctl_parameter_t * parameter; + const char * address[PARAM_ADDRESS_SIZE]; + const struct jack_parameter * param_ptr; //jack_info("jack_controller_dbus_reset_parameter_value() called"); @@ -1981,130 +929,25 @@ jack_controller_dbus_reset_parameter_value( //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]); - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */ - { - if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0) - { - jack_controller_reset_parameter_value_engine_driver(call); - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown engine parameter '%s'", - address[1]); - return; - } - - jack_controller_reset_parameter_value(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] == NULL && - strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */ - { - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[1], - jackctl_driver_get_name(controller_ptr->driver)); - return; - } - - jack_controller_reset_parameter_value(call, parameter); - - return; - } - - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_DRIVERS) == 0) + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) { - driver = jack_controller_find_driver(controller_ptr->server, address[1]); - if (driver == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown driver '%s'", - address[1]); - return; - } - - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for driver '%s'", - address[2], - address[1]); - return; - } - - jack_controller_reset_parameter_value(call, parameter); - + jack_dbus_error( + call, + JACK_DBUS_ERROR_INVALID_ARGS, + "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", + address[0], + address[1], + address[2], + call->method_name); return; } - if (address[0] != NULL && - address[1] != NULL && - address[2] != NULL && - strcmp(address[0], PTNODE_INTERNALS) == 0) - { - internal = jack_controller_find_internal(controller_ptr->server, address[1]); - if (internal == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_INTERNAL, - "Unknown internal '%s'", - address[1]); - return; - } + param_ptr->vtable.reset(param_ptr->obj); - parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]); - if (parameter == NULL) - { - jack_dbus_error( - call, - JACK_DBUS_ERROR_UNKNOWN_PARAMETER, - "Unknown parameter '%s' for internal '%s'", - address[2], - address[1]); - return; - } - - jack_controller_reset_parameter_value(call, parameter); - - return; - } + jack_controller_settings_save_auto(controller_ptr); - jack_dbus_error( - call, - JACK_DBUS_ERROR_INVALID_ARGS, - "Invalid container address '%s':'%s':'%s' supplied to method '%s'.", - address[0], - address[1], - address[2], - call->method_name); + jack_dbus_construct_method_return_empty(call); } #undef controller_ptr diff --git a/dbus/controller_internal.h b/dbus/controller_internal.h index 6bb223a8..ae247c39 100644 --- a/dbus/controller_internal.h +++ b/dbus/controller_internal.h @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2011 Nedko Arnaudov Copyright (C) 2007-2008 Juuso Alasuutari This program is free software; you can redistribute it and/or modify @@ -27,6 +27,7 @@ #include "jack/jack.h" #include "jackdbus.h" #include "list.h" +#include "params.h" struct jack_controller_slave_driver { @@ -38,6 +39,7 @@ struct jack_controller_slave_driver struct jack_controller { jackctl_server_t *server; + jack_params_handle params; void *patchbay_context; @@ -45,14 +47,6 @@ struct jack_controller jack_client_t *client; unsigned int xruns; - const char **driver_names; - unsigned int drivers_count; - - const char **internal_names; - unsigned int internals_count; - - jackctl_driver_t *driver; - bool driver_set; /* whether driver is manually set, if false - DEFAULT_DRIVER is auto set */ struct list_head slave_drivers; struct jack_dbus_object_descriptor dbus_descriptor; @@ -121,47 +115,15 @@ jack_controller_unload_internal( 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( +jack_controller_deserialize_parameter_value( struct jack_controller *controller_ptr, - const char *option_name, - const char *option_value); - -bool -jack_controller_settings_save_engine_options( - void *context, - struct jack_controller *controller_ptr, - void *dbus_call_context_ptr); + const char * const * address, + const char * value); -bool -jack_controller_settings_write_option( - void *context, - const char *name, - const char *content, - void *dbus_call_context_ptr); - -bool -jack_controller_settings_save_driver_options( - void *context, - 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); +void +jack_controller_serialize_parameter_value( + const struct jack_parameter * param_ptr, + char * value_buffer); bool jack_controller_patchbay_init( diff --git a/dbus/params.c b/dbus/params.c new file mode 100644 index 00000000..b6f913de --- /dev/null +++ b/dbus/params.c @@ -0,0 +1,717 @@ +/* -*- Mode: C ; c-basic-offset: 4 -*- */ +/* + Copyright (C) 2011 Nedko Arnaudov + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + * Parameter addresses: + * + * "engine" + * "engine", "driver" + * "engine", "realtime" + * "engine", ...more engine parameters + * + * "driver", "device" + * "driver", ...more driver parameters + * + * "drivers", "alsa", "device" + * "drivers", "alsa", ...more alsa driver parameters + * + * "drivers", ...more drivers + * + * "internals", "netmanager", "multicast_ip" + * "internals", "netmanager", ...more netmanager parameters + * + * "internals", ...more internals + * + */ + +#include +#include +#include +#include + +#include "params.h" +#include "controller_internal.h" + +#define PTNODE_ENGINE "engine" +#define PTNODE_DRIVER "driver" +#define PTNODE_DRIVERS "drivers" +#define PTNODE_INTERNALS "internals" + +struct jack_parameter_container +{ + struct list_head siblings; + char * name; + struct jack_parameter_container * symlink; + bool leaf; + struct list_head children; + void * obj; +}; + +struct jack_params +{ + jackctl_server_t * server; + struct jack_parameter_container root; + struct list_head * drivers_ptr; + uint32_t drivers_count; + struct jack_parameter_container * driver_ptr; + bool driver_set; /* whether driver is manually set, if false - DEFAULT_DRIVER is auto set */ +}; + +static bool controlapi_parameter_is_set(void * obj) +{ + return jackctl_parameter_is_set((jackctl_parameter_t *)obj); +} + +static bool controlapi_parameter_reset(void * obj) +{ + return jackctl_parameter_reset((jackctl_parameter_t *)obj); +} + +union jackctl_parameter_value controlapi_parameter_get_value(void * obj) +{ + return jackctl_parameter_get_value((jackctl_parameter_t *)obj); +} + +bool controlapi_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr) +{ + return jackctl_parameter_set_value((jackctl_parameter_t *)obj, value_ptr); +} + +union jackctl_parameter_value controlapi_parameter_get_default_value(void * obj) +{ + return jackctl_parameter_get_default_value((jackctl_parameter_t *)obj); +} + +static struct jack_parameter_container * create_container(struct list_head * parent_list_ptr, const char * name) +{ + struct jack_parameter_container * container_ptr; + + container_ptr = malloc(sizeof(struct jack_parameter_container)); + if (container_ptr == NULL) + { + jack_error("Ran out of memory trying to allocate struct jack_parameter_container"); + goto fail; + } + + container_ptr->name = strdup(name); + if (container_ptr->name == NULL) + { + jack_error("Ran out of memory trying to strdup parameter container name"); + goto free; + } + + container_ptr->leaf = false; + container_ptr->symlink = NULL; + container_ptr->obj = NULL; + INIT_LIST_HEAD(&container_ptr->children); + list_add_tail(&container_ptr->siblings, parent_list_ptr); + + return container_ptr; + +free: + free(container_ptr); +fail: + return NULL; +} + +static bool add_controlapi_param(struct list_head * parent_list_ptr, jackctl_parameter_t * param) +{ + struct jack_parameter * param_ptr; + uint32_t i; + + param_ptr = malloc(sizeof(struct jack_parameter)); + if (param_ptr == NULL) + { + jack_error("Ran out of memory trying to allocate struct jack_parameter"); + goto fail; + } + + param_ptr->obj = param; + param_ptr->vtable.is_set = controlapi_parameter_is_set; + param_ptr->vtable.reset = controlapi_parameter_reset; + param_ptr->vtable.get_value = controlapi_parameter_get_value; + param_ptr->vtable.set_value = controlapi_parameter_set_value; + param_ptr->vtable.get_default_value = controlapi_parameter_get_default_value; + + param_ptr->type = jackctl_parameter_get_type(param); + param_ptr->name = jackctl_parameter_get_name(param); + param_ptr->short_decr = jackctl_parameter_get_short_description(param); + param_ptr->long_descr = jackctl_parameter_get_long_description(param); + + if (jackctl_parameter_has_range_constraint(param)) + { + param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID; + param_ptr->constraint_range = true; + jackctl_parameter_get_range_constraint(param, ¶m_ptr->constraint.range.min, ¶m_ptr->constraint.range.max); + } + else if (jackctl_parameter_has_enum_constraint(param)) + { + param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID; + param_ptr->constraint_range = false; + param_ptr->constraint.enumeration.count = jackctl_parameter_get_enum_constraints_count(param); + param_ptr->constraint.enumeration.possible_values_array = malloc(sizeof(struct jack_parameter_enum) * param_ptr->constraint.enumeration.count); + if (param_ptr->constraint.enumeration.possible_values_array == NULL) + { + goto free; + } + + for (i = 0; i < param_ptr->constraint.enumeration.count; i++) + { + param_ptr->constraint.enumeration.possible_values_array[i].value = jackctl_parameter_get_enum_constraint_value(param, i); + param_ptr->constraint.enumeration.possible_values_array[i].short_desc = jackctl_parameter_get_enum_constraint_description(param, i); + } + } + else + { + param_ptr->constraint_flags = 0; + goto add; + } + + if (jackctl_parameter_constraint_is_strict(param)) + { + param_ptr->constraint_flags |= JACK_CONSTRAINT_FLAG_STRICT; + } + + if (jackctl_parameter_constraint_is_fake_value(param)) + { + param_ptr->constraint_flags |= JACK_CONSTRAINT_FLAG_FAKE_VALUE; + } + +add: + list_add_tail(¶m_ptr->siblings, parent_list_ptr); + return true; + +free: + free(param_ptr); +fail: + return false; +} + +static void free_params(struct list_head * parent_list_ptr) +{ + struct jack_parameter * param_ptr; + + while (!list_empty(parent_list_ptr)) + { + param_ptr = list_entry(parent_list_ptr->next, struct jack_parameter, siblings); + list_del(¶m_ptr->siblings); + + if ((param_ptr->constraint_flags & JACK_CONSTRAINT_FLAG_VALID) != 0 && + !param_ptr->constraint_range && + param_ptr->constraint.enumeration.possible_values_array != NULL) + { + free(param_ptr->constraint.enumeration.possible_values_array); + } + + free(param_ptr); + } +} + +static void free_containers(struct list_head * parent_list_ptr) +{ + struct jack_parameter_container * container_ptr; + + while (!list_empty(parent_list_ptr)) + { + container_ptr = list_entry(parent_list_ptr->next, struct jack_parameter_container, siblings); + list_del(&container_ptr->siblings); + + if (container_ptr->leaf) + { + free_params(&container_ptr->children); + } + else + { + free_containers(&container_ptr->children); + } + + free(container_ptr->name); + free(container_ptr); + } +} + +static struct jack_parameter_container * find_container(struct jack_parameter_container * parent_ptr, const char * const * address, int max_depth) +{ + struct list_head * node_ptr; + struct jack_parameter_container * container_ptr; + + if (max_depth == 0 || *address == NULL) + { + return parent_ptr; + } + + if (parent_ptr->leaf) + { + return NULL; + } + + if (max_depth > 0) + { + max_depth--; + } + + list_for_each(node_ptr, &parent_ptr->children) + { + container_ptr = list_entry(node_ptr, struct jack_parameter_container, siblings); + if (strcmp(container_ptr->name, *address) == 0) + { + if (container_ptr->symlink != NULL) + { + container_ptr = container_ptr->symlink; + } + + return find_container(container_ptr, address + 1, max_depth); + } + } + + return NULL; +} + +static bool init_leaf(struct list_head * parent_list_ptr, const char * name, const JSList * params_list, void * obj) +{ + struct jack_parameter_container * container_ptr; + + container_ptr = create_container(parent_list_ptr, name); + if (container_ptr == NULL) + { + return false; + } + + container_ptr->leaf = true; + container_ptr->obj = obj; + + while (params_list) + { + if (!add_controlapi_param(&container_ptr->children, params_list->data)) + { + return false; + } + + params_list = jack_slist_next(params_list); + } + + return true; +} + +static bool init_engine(struct jack_params * params_ptr) +{ + return init_leaf(¶ms_ptr->root.children, PTNODE_ENGINE, jackctl_server_get_parameters(params_ptr->server), NULL); +} + +static bool init_drivers(struct jack_params * params_ptr) +{ + const JSList * list; + struct jack_parameter_container * container_ptr; + + container_ptr = create_container(¶ms_ptr->root.children, PTNODE_DRIVERS); + if (container_ptr == NULL) + { + return false; + } + + params_ptr->drivers_ptr = &container_ptr->children; + params_ptr->drivers_count = 0; + + list = jackctl_server_get_drivers_list(params_ptr->server); + while (list) + { + if (!init_leaf(&container_ptr->children, jackctl_driver_get_name(list->data), jackctl_driver_get_parameters(list->data), list->data)) + { + return false; + } + + params_ptr->drivers_count++; + + list = jack_slist_next(list); + } + + return true; +} + +static bool init_internals(struct jack_params * params_ptr) +{ + const JSList * list; + struct jack_parameter_container * container_ptr; + + container_ptr = create_container(¶ms_ptr->root.children, PTNODE_INTERNALS); + if (container_ptr == NULL) + { + return false; + } + + list = jackctl_server_get_internals_list(params_ptr->server); + while (list) + { + if (!init_leaf(&container_ptr->children, jackctl_internal_get_name(list->data), jackctl_internal_get_parameters(list->data), NULL)) + { + return false; + } + + list = jack_slist_next(list); + } + + return true; +} + +static bool init_driver(struct jack_params * params_ptr) +{ + struct jack_parameter_container * container_ptr; + + container_ptr = create_container(¶ms_ptr->root.children, PTNODE_DRIVER); + if (container_ptr == NULL) + { + return false; + } + + params_ptr->driver_ptr = container_ptr; + + return true; +} + +#define params_ptr ((struct jack_params *)obj) + +static bool engine_driver_parameter_is_set(void * obj) +{ + return params_ptr->driver_set; +} + +static bool engine_driver_parameter_reset(void * obj) +{ + if (!jack_params_set_driver(obj, DEFAULT_DRIVER)) + { + return false; + } + + params_ptr->driver_set = false; + + return true; +} + +union jackctl_parameter_value engine_driver_parameter_get_value(void * obj) +{ + union jackctl_parameter_value value; + + strcpy(value.str, params_ptr->driver_ptr->symlink->name); + + return value; +} + +bool engine_driver_parameter_set_value(void * obj, const union jackctl_parameter_value * value_ptr) +{ + return jack_params_set_driver(obj, value_ptr->str); +} + +union jackctl_parameter_value engine_driver_parameter_get_default_value(void * obj) +{ + union jackctl_parameter_value value; + + strcpy(value.str, DEFAULT_DRIVER); + + return value; +} + +#undef params_ptr + +static bool add_engine_driver_enum_constraint(void * context, const char * name) +{ + strcpy((*((struct jack_parameter_enum **)context))->value.str, name); + (*((struct jack_parameter_enum **)context))->short_desc = name; + (*((struct jack_parameter_enum **)context))++; + return true; +} + +static bool init_engine_driver_parameter(struct jack_params * params_ptr) +{ + struct jack_parameter * param_ptr; + const char * address[PARAM_ADDRESS_SIZE] = {PTNODE_ENGINE, NULL}; + struct jack_parameter_container * engine_ptr; + struct jack_parameter_enum * possible_value; + + engine_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (engine_ptr == NULL) + { + return false; + } + + param_ptr = malloc(sizeof(struct jack_parameter)); + if (param_ptr == NULL) + { + jack_error("Ran out of memory trying to allocate struct jack_parameter"); + goto fail; + } + + param_ptr->obj = params_ptr; + param_ptr->vtable.is_set = engine_driver_parameter_is_set; + param_ptr->vtable.reset = engine_driver_parameter_reset; + param_ptr->vtable.get_value = engine_driver_parameter_get_value; + param_ptr->vtable.set_value = engine_driver_parameter_set_value; + param_ptr->vtable.get_default_value = engine_driver_parameter_get_default_value; + + param_ptr->type = JackParamString; + param_ptr->name = "driver"; + param_ptr->short_decr = "Driver to use"; + param_ptr->long_descr = ""; + + param_ptr->constraint_flags = JACK_CONSTRAINT_FLAG_VALID | JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE; + param_ptr->constraint_range = false; + param_ptr->constraint.enumeration.count = params_ptr->drivers_count; + param_ptr->constraint.enumeration.possible_values_array = malloc(sizeof(struct jack_parameter_enum) * params_ptr->drivers_count); + if (param_ptr->constraint.enumeration.possible_values_array == NULL) + { + goto free; + } + + address[0] = PTNODE_DRIVERS; + possible_value = param_ptr->constraint.enumeration.possible_values_array; + jack_params_iterate_container((jack_params_handle)params_ptr, address, add_engine_driver_enum_constraint, &possible_value); + + list_add(¶m_ptr->siblings, &engine_ptr->children); + return true; + +free: + free(param_ptr); +fail: + return false; +} + +jack_params_handle jack_params_create(jackctl_server_t * server) +{ + struct jack_params * params_ptr; + + params_ptr = malloc(sizeof(struct jack_params)); + if (params_ptr == NULL) + { + jack_error("Ran out of memory trying to allocate struct jack_params"); + return NULL; + } + + params_ptr->server = server; + INIT_LIST_HEAD(¶ms_ptr->root.children); + params_ptr->root.leaf = false; + params_ptr->root.name = NULL; + + if (!init_engine(params_ptr) || + !init_drivers(params_ptr) || + !init_driver(params_ptr) || + !init_engine_driver_parameter(params_ptr) || + !jack_params_set_driver((jack_params_handle)params_ptr, DEFAULT_DRIVER) || + !init_internals(params_ptr)) + { + jack_params_destroy((jack_params_handle)params_ptr); + return NULL; + } + + params_ptr->driver_set = false; + + assert(strcmp(params_ptr->driver_ptr->symlink->name, DEFAULT_DRIVER) == 0); + + return (jack_params_handle)params_ptr; +} + +#define params_ptr ((struct jack_params *)params) + +void jack_params_destroy(jack_params_handle params) +{ + free_containers(¶ms_ptr->root.children); + free(params); +} + +bool jack_params_set_driver(jack_params_handle params, const char * name) +{ + struct list_head * node_ptr; + struct jack_parameter_container * container_ptr; + + list_for_each(node_ptr, params_ptr->drivers_ptr) + { + container_ptr = list_entry(node_ptr, struct jack_parameter_container, siblings); + if (strcmp(container_ptr->name, name) == 0) + { + params_ptr->driver_ptr->symlink = container_ptr; + params_ptr->driver_set = true; + return true; + } + } + + return false; +} + +jackctl_driver_t * jack_params_get_driver(jack_params_handle params) +{ + return params_ptr->driver_ptr->symlink->obj; +} + +bool jack_params_check_address(jack_params_handle params, const char * const * address, bool want_leaf) +{ + struct jack_parameter_container * container_ptr; + + container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (container_ptr == NULL) + { + return false; + } + + if (want_leaf && !container_ptr->leaf) + { + return false; + } + + return true; +} + +bool jack_params_is_leaf_container(jack_params_handle params, const char * const * address) +{ + struct jack_parameter_container * container_ptr; + + container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (container_ptr == NULL) + { + assert(false); + return false; + } + + return container_ptr->leaf; +} + +bool +jack_params_iterate_container( + jack_params_handle params, + const char * const * address, + bool (* callback)(void * context, const char * name), + void * context) +{ + struct jack_parameter_container * container_ptr; + struct list_head * node_ptr; + const char * name; + + container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (container_ptr == NULL) + { + assert(false); + return true; + } + + list_for_each(node_ptr, &container_ptr->children) + { + if (container_ptr->leaf) + { + name = list_entry(node_ptr, struct jack_parameter, siblings)->name; + } + else + { + name = list_entry(node_ptr, struct jack_parameter_container, siblings)->name; + } + + if (!callback(context, name)) + { + return false; + } + } + + return true; +} + +bool +jack_params_iterate_params( + jack_params_handle params, + const char * const * address, + bool (* callback)(void * context, const struct jack_parameter * param_ptr), + void * context) +{ + struct jack_parameter_container * container_ptr; + struct list_head * node_ptr; + struct jack_parameter * param_ptr; + + container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (container_ptr == NULL || !container_ptr->leaf) + { + assert(false); + return true; + } + + list_for_each(node_ptr, &container_ptr->children) + { + param_ptr = list_entry(node_ptr, struct jack_parameter, siblings); + if (!callback(context, param_ptr)) + { + return false; + } + } + + return true; +} + +const struct jack_parameter * jack_params_get_parameter(jack_params_handle params, const char * const * address) +{ + int depth; + struct jack_parameter_container * container_ptr; + struct list_head * node_ptr; + struct jack_parameter * param_ptr; + + for (depth = 0; depth < PARAM_ADDRESS_SIZE; depth++) + { + if (address[depth] == NULL) + { + break; + } + } + + depth--; + + container_ptr = find_container(¶ms_ptr->root, address, depth); + if (container_ptr == NULL || !container_ptr->leaf) + { + return NULL; + } + + list_for_each(node_ptr, &container_ptr->children) + { + param_ptr = list_entry(node_ptr, struct jack_parameter, siblings); + if (strcmp(param_ptr->name, address[depth]) == 0) + { + return param_ptr; + } + } + + return NULL; +} + +bool 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; + + container_ptr = find_container(¶ms_ptr->root, address, PARAM_ADDRESS_SIZE); + if (container_ptr == NULL || !container_ptr->leaf) + { + assert(false); + return false; + } + + if (end) + { + list_add_tail(¶m_ptr->siblings, &container_ptr->children); + } + else + { + list_add(¶m_ptr->siblings, &container_ptr->children); + } + + return true; +} + +#undef params_ptr diff --git a/dbus/params.h b/dbus/params.h new file mode 100644 index 00000000..d880a7dd --- /dev/null +++ b/dbus/params.h @@ -0,0 +1,110 @@ +/* -*- Mode: C ; c-basic-offset: 4 -*- */ +/* + Copyright (C) 2011 Nedko Arnaudov + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef PARAMS_H__A23EDE06_C1C9_4489_B253_FD1B26B66929__INCLUDED +#define PARAMS_H__A23EDE06_C1C9_4489_B253_FD1B26B66929__INCLUDED + +#include "jack/control.h" +#include "list.h" + +#define PARAM_ADDRESS_SIZE 3 + +#define PTNODE_ENGINE "engine" +#define PTNODE_DRIVER "driver" +#define PTNODE_DRIVERS "drivers" +#define PTNODE_INTERNALS "internals" + +struct jack_parameter_vtable +{ + bool (* is_set)(void * obj); + bool (* reset)(void * obj); + union jackctl_parameter_value (* get_value)(void * obj); + bool (* set_value)(void * obj, const union jackctl_parameter_value * value_ptr); + union jackctl_parameter_value (* get_default_value)(void * obj); +}; + +#define JACK_CONSTRAINT_FLAG_VALID ((uint32_t)1) /**< if not set, there is no constraint */ +#define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ +#define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ + +struct jack_parameter_enum +{ + union jackctl_parameter_value value; + const char * short_desc; +}; + +struct jack_parameter +{ + void * obj; + struct jack_parameter_vtable vtable; + struct list_head siblings; + jackctl_param_type_t type; + const char * name; + const char * short_decr; + const char * long_descr; + + uint32_t constraint_flags; /**< JACK_CONSTRAINT_FLAG_XXX */ + bool constraint_range; /**< if true, constraint is a range (min-max), otherwise it is an enumeration */ + + union + { + struct + { + union jackctl_parameter_value min; + union jackctl_parameter_value max; + } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ + + struct + { + uint32_t count; + struct jack_parameter_enum * possible_values_array; + } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ + } constraint; +}; + +typedef struct _jack_params { int unused; } * jack_params_handle; + +jack_params_handle jack_params_create(jackctl_server_t * server); +void jack_params_destroy(jack_params_handle params); + +bool jack_params_set_driver(jack_params_handle params, const char * name); +jackctl_driver_t * jack_params_get_driver(jack_params_handle params); + +bool jack_params_check_address(jack_params_handle params, const char * const * address, bool want_leaf); +bool jack_params_is_leaf_container(jack_params_handle params, const char * const * address); + +bool +jack_params_iterate_container( + jack_params_handle params, + const char * const * address, + bool (* callback)(void * context, const char * name), + void * context); + +bool +jack_params_iterate_params( + jack_params_handle params, + const char * const * address, + bool (* callback)(void * context, const struct jack_parameter * param_ptr), + void * context); + +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); + +#endif /* #ifndef PARAMS_H__A23EDE06_C1C9_4489_B253_FD1B26B66929__INCLUDED */ diff --git a/dbus/wscript b/dbus/wscript index 6aa716d2..2045c33f 100644 --- a/dbus/wscript +++ b/dbus/wscript @@ -52,6 +52,7 @@ def build(bld): obj.source = [ 'jackdbus.c', 'controller.c', + 'params.c', 'controller_iface_configure.c', 'controller_iface_control.c', 'controller_iface_introspectable.c', diff --git a/dbus/xml.c b/dbus/xml.c index b506c5d5..c7e11377 100644 --- a/dbus/xml.c +++ b/dbus/xml.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2011 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,358 +25,116 @@ #include #include #include +#include #include #include "controller_internal.h" void -jack_controller_settings_set_bool_option( - const char *value_str, - int *value_ptr) -{ - if (strcmp(value_str, "true") == 0) - { - *value_ptr = true; - } - else if (strcmp(value_str, "false") == 0) - { - *value_ptr = false; - } - else - { - jack_error("ignoring unknown bool value \"%s\"", value_str); - } -} - -void -jack_controller_settings_set_sint_option( - const char *value_str, - int *value_ptr) -{ - *value_ptr = atoi(value_str); -} - -void -jack_controller_settings_set_uint_option( - const char *value_str, - unsigned int *value_ptr) -{ - *value_ptr = strtoul(value_str, NULL, 10); -} - -void -jack_controller_settings_set_char_option( - const char *value_str, - char *value_ptr) -{ - if (value_str[0] == 0 || value_str[1] != 0) - { - jack_error("invalid char option value \"%s\"", value_str); - return; - } - - *value_ptr = *value_str; -} - -void -jack_controller_settings_set_string_option( - const char *value_str, - char *value_ptr, - size_t max_size) -{ - size_t size; - - size = strlen(value_str); - - if (size >= max_size) - { - jack_error("string option value \"%s\" is too long, max is %u chars (including terminating zero)", value_str, (unsigned int)max_size); - return; - } - - strcpy(value_ptr, value_str); -} - -void -jack_controller_settings_set_driver_option( - jackctl_driver_t *driver, - const char *option_name, - const char *option_value) +jack_controller_deserialize_parameter_value( + struct jack_controller *controller_ptr, + const char * const * address, + const char * option_value) { - jackctl_parameter_t *parameter; - jackctl_param_type_t type; - int value_int = 0; - unsigned int value_uint = 0; + const struct jack_parameter * param_ptr; union jackctl_parameter_value value; + size_t size; - jack_info("setting driver option \"%s\" to value \"%s\"", option_name, option_value); - - parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), option_name); - if (parameter == NULL) + param_ptr = jack_params_get_parameter(controller_ptr->params, address); + if (param_ptr == NULL) { - jack_error( - "Unknown parameter \"%s\" of driver \"%s\"", - option_name, - jackctl_driver_get_name(driver)); - return; + jack_error("Unknown parameter"); + goto ignore; } - type = jackctl_parameter_get_type(parameter); + jack_info("setting parameter '%s':'%s':'%s' to value \"%s\"", address[0], address[1], address[2], option_value); - switch (type) + switch (param_ptr->type) { case JackParamInt: - jack_controller_settings_set_sint_option(option_value, &value_int); - value.i = value_int; + value.i = atoi(option_value); break; case JackParamUInt: - jack_controller_settings_set_uint_option(option_value, &value_uint); - value.ui = value_uint; + value.ui = strtoul(option_value, NULL, 10); break; case JackParamChar: - jack_controller_settings_set_char_option(option_value, &value.c); + if (option_value[0] == 0 || option_value[1] != 0) + { + jack_error("invalid char option value \"%s\"", option_value); + goto ignore; + } + value.c = *option_value; break; case JackParamString: - jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); + size = strlen(option_value); + if (size >= sizeof(value.str)) + { + jack_error("string option value \"%s\" is too long, max is %zu chars (including terminating zero)", option_value, sizeof(value.str)); + goto ignore; + } + + strcpy(value.str, option_value); break; case JackParamBool: - jack_controller_settings_set_bool_option(option_value, &value_int); - value.i = value_int; + if (strcmp(option_value, "true") == 0) + { + value.b = true; + } + else if (strcmp(option_value, "false") == 0) + { + value.b = false; + } + else + { + jack_error("ignoring unknown bool value \"%s\"", option_value); + goto ignore; + } break; default: - jack_error("Parameter \"%s\" of driver \"%s\" is of unknown type %d", - jackctl_parameter_get_name(parameter), - jackctl_driver_get_name(driver), - type); + jack_error("Unknown type %d", (int)param_ptr->type); + goto ignore; } - 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 = 0; - unsigned int value_uint = 0; - 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) + if (param_ptr->vtable.set_value(param_ptr->obj, &value)) { - 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); - } + jack_error("Parameter set failed"); - jackctl_parameter_set_value(parameter, &value); +ignore: + jack_error("Ignoring restore attempt of parameter '%s':'%s':'%s'", address[0], address[1], address[2]); } void -jack_controller_settings_set_engine_option( - struct jack_controller *controller_ptr, - const char *option_name, - const char *option_value) +jack_controller_serialize_parameter_value( + const struct jack_parameter * param_ptr, + char * value_buffer) { - jackctl_parameter_t *parameter; - jackctl_param_type_t type; - int value_int = 0; - unsigned int value_uint = 0; union jackctl_parameter_value value; - jack_info("setting engine option \"%s\" to value \"%s\"", option_name, option_value); + value = param_ptr->vtable.get_value(param_ptr->obj); - if (strcmp(option_name, "driver") == 0) - { - if (!jack_controller_select_driver(controller_ptr, option_value)) - { - jack_error("unknown driver '%s'", option_value); - } - - return; - } - - parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), option_name); - if (parameter == NULL) - { - jack_error( - "Unknown engine parameter \"%s\"", - option_name); - return; - } - - type = jackctl_parameter_get_type(parameter); - - switch (type) + switch (param_ptr->type) { case JackParamInt: - jack_controller_settings_set_sint_option(option_value, &value_int); - value.i = value_int; - break; + sprintf(value_buffer, "%d", (int)value.i); + return; case JackParamUInt: - jack_controller_settings_set_uint_option(option_value, &value_uint); - value.ui = value_uint; - break; + sprintf(value_buffer, "%u", (unsigned int)value.ui); + return; case JackParamChar: - jack_controller_settings_set_char_option(option_value, &value.c); - break; + sprintf(value_buffer, "%c", (char)value.c); + return; case JackParamString: - jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); - break; + strcpy(value_buffer, value.str); + return; case JackParamBool: - jack_controller_settings_set_bool_option(option_value, &value_int); - value.i = value_int; - break; - default: - jack_error("Engine parameter \"%s\" is of unknown type %d", - jackctl_parameter_get_name(parameter), - type); - } - - jackctl_parameter_set_value(parameter, &value); -} - -static -bool -jack_controller_settings_save_options( - void *context, - const JSList * parameters_list, - void *dbus_call_context_ptr) -{ - jackctl_parameter_t *parameter; - jackctl_param_type_t type; - union jackctl_parameter_value value; - const char * name; - char value_str[50]; - - while (parameters_list != NULL) - { - parameter = (jackctl_parameter_t *)parameters_list->data; - - if (jackctl_parameter_is_set(parameter)) - { - type = jackctl_parameter_get_type(parameter); - value = jackctl_parameter_get_value(parameter); - name = jackctl_parameter_get_name(parameter); - - switch (type) - { - case JackParamInt: - sprintf(value_str, "%d", (int)value.i); - if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) - { - return false; - } - break; - case JackParamUInt: - sprintf(value_str, "%u", (unsigned int)value.ui); - if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) - { - return false; - } - break; - case JackParamChar: - sprintf(value_str, "%c", (char)value.c); - if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) - { - return false; - } - break; - case JackParamString: - if (!jack_controller_settings_write_option(context, name, value.str, dbus_call_context_ptr)) - { - return false; - } - break; - case JackParamBool: - if (!jack_controller_settings_write_option(context, name, value.b ? "true" : "false", dbus_call_context_ptr)) - { - return false; - } - break; - default: - jack_error("parameter of unknown type %d", type); - } - } - - parameters_list = jack_slist_next(parameters_list); - } - - return true; -} - -bool -jack_controller_settings_save_engine_options( - void *context, - struct jack_controller *controller_ptr, - void *dbus_call_context_ptr) -{ - if (controller_ptr->driver != NULL) - { - if (!jack_controller_settings_write_option( - context, - "driver", - jackctl_driver_get_name(controller_ptr->driver), - dbus_call_context_ptr)) - { - return false; - } + strcpy(value_buffer, value.b ? "true" : "false"); + return; } - return jack_controller_settings_save_options(context, jackctl_server_get_parameters(controller_ptr->server), dbus_call_context_ptr); -} - -bool -jack_controller_settings_save_driver_options( - void *context, - jackctl_driver_t *driver, - void *dbus_call_context_ptr) -{ - 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); + jack_error("parameter of unknown type %d", (int)param_ptr->type); + assert(false); + *value_buffer = 0; } diff --git a/dbus/xml_expat.c b/dbus/xml_expat.c index 1ee1bd2e..f5a5aa68 100644 --- a/dbus/xml_expat.c +++ b/dbus/xml_expat.c @@ -1,6 +1,6 @@ /* -*- Mode: C ; c-basic-offset: 4 -*- */ /* - Copyright (C) 2007,2008 Nedko Arnaudov + Copyright (C) 2007,2008,2011 Nedko Arnaudov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -46,27 +47,16 @@ 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_INTERNALS 5 -#define PARSE_CONTEXT_INTERNAL 6 - -#define MAX_STACK_DEPTH 10 - struct parse_context { struct jack_controller *controller_ptr; XML_Bool error; - unsigned int element[MAX_STACK_DEPTH]; - signed int depth; - jackctl_driver_t *driver; - jackctl_internal_t *internal; + bool option_value_capture; char option[JACK_PARAM_STRING_MAX+1]; int option_used; + const char * address[PARAM_ADDRESS_SIZE]; + int address_index; + char * container; char *name; }; @@ -80,7 +70,7 @@ jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len return; } - if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) + if (context_ptr->option_value_capture) { if (context_ptr->option_used + len >= JACK_PARAM_STRING_MAX) { @@ -97,107 +87,69 @@ jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len 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) { return; } - if (context_ptr->depth + 1 >= MAX_STACK_DEPTH) + if (context_ptr->address_index >= PARAM_ADDRESS_SIZE) { - jack_error("xml parse max stack depth reached"); + assert(context_ptr->address_index == PARAM_ADDRESS_SIZE); + jack_error("xml param address max depth reached"); context_ptr->error = XML_TRUE; return; } + //jack_info("<%s>", el); + if (strcmp(el, "jack") == 0) { - //jack_info(""); - context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_JACK; return; } - if (strcmp(el, "engine") == 0) + if (strcmp(el, PTNODE_ENGINE) == 0) { - //jack_info(""); - context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ENGINE; + context_ptr->address[context_ptr->address_index++] = PTNODE_ENGINE; return; } - if (strcmp(el, "drivers") == 0) + if (strcmp(el, PTNODE_DRIVERS) == 0) { - //jack_info(""); - context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVERS; + context_ptr->address[context_ptr->address_index++] = PTNODE_DRIVERS; return; } - if (strcmp(el, "internals") == 0) + if (strcmp(el, PTNODE_INTERNALS) == 0) { - //jack_info(""); - context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_INTERNALS; + context_ptr->address[context_ptr->address_index++] = PTNODE_INTERNALS; return; } - if (strcmp(el, "driver") == 0) + if (strcmp(el, "driver") == 0 || + strcmp(el, "internal") == 0) { if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) { - jack_error(" XML element must contain exactly one attribute, named \"name\""); + jack_error("<%s> XML element must contain exactly one attribute, named \"name\"", el); context_ptr->error = XML_TRUE; return; } - //jack_info(""); - context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVER; - - driver = jack_controller_find_driver(context_ptr->controller_ptr->server, attr[1]); - if (driver == NULL) - { - jack_error("ignoring settings for unknown driver \"%s\"", attr[1]); - } - else - { - jack_info("setting for driver \"%s\" found", attr[1]); - } - - context_ptr->driver = driver; - - return; - } - - if (strcmp(el, "internal") == 0) - { - if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) + context_ptr->container = strdup(attr[1]); + if (context_ptr->container == NULL) { - jack_error(" XML element must contain exactly one attribute, named \"name\""); + jack_error("strdup() failed"); context_ptr->error = XML_TRUE; return; } - //jack_info(""); - 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; + context_ptr->address[context_ptr->address_index++] = context_ptr->container; return; } - - + if (strcmp(el, "option") == 0) { - //jack_info("\n", dbus_call_context_ptr)) - { - return false; - } + return + jack_controller_settings_write_string(fd, ctx_ptr->indent, ctx_ptr->call) && + jack_controller_settings_write_string(fd, "\n", ctx_ptr->call); +} - return true; +bool serialize_modules(void * context, const char * name) +{ + ctx_ptr->indent = " "; + ctx_ptr->address[1] = name; + ctx_ptr->address[2] = NULL; + + return + jack_controller_settings_write_string(fd, " <", ctx_ptr->call) && + jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) && + jack_controller_settings_write_string(fd, " name=\"", ctx_ptr->call) && + jack_controller_settings_write_string(fd, name, ctx_ptr->call) && + jack_controller_settings_write_string(fd, "\">\n", ctx_ptr->call) && + jack_params_iterate_params(ctx_ptr->params, ctx_ptr->address, jack_controller_serialize_parameter, ctx_ptr) && + jack_controller_settings_write_string(fd, " call) && + jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) && + jack_controller_settings_write_string(fd, ">\n", ctx_ptr->call); } #undef fd +#undef ctx_ptr bool jack_controller_settings_save( @@ -114,9 +117,9 @@ jack_controller_settings_save( time_t timestamp; char timestamp_str[26]; struct save_context context; - const JSList * node_ptr; - jackctl_driver_t *driver; - jackctl_internal_t *internal; + const char * modules[] = {"driver", "internal", NULL}; + char buffer[100]; + unsigned int i; time(×tamp); ctime_r(×tamp, timestamp_str); @@ -147,6 +150,7 @@ jack_controller_settings_save( } context.fd = fd; + context.call = dbus_call_context_ptr; if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr)) { @@ -196,7 +200,9 @@ jack_controller_settings_save( } context.indent = " "; - if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr)) + context.address[0] = PTNODE_ENGINE; + context.address[1] = NULL; + if (!jack_params_iterate_params(controller_ptr->params, context.address, jack_controller_serialize_parameter, &context)) { goto exit_close; } @@ -206,100 +212,50 @@ jack_controller_settings_save( goto exit_close; } - /* drivers */ - - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) + for (i = 0; modules[i] != NULL; i++) { - goto exit_close; - } - - node_ptr = jackctl_server_get_drivers_list(controller_ptr->server); - - while (node_ptr != NULL) - { - driver = (jackctl_driver_t *)node_ptr->data; - - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, " <", dbus_call_context_ptr)) { goto exit_close; } - context.indent = " "; - - if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, modules[i], dbus_call_context_ptr)) { goto exit_close; } - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, "s>\n", dbus_call_context_ptr)) { goto exit_close; } - node_ptr = jack_slist_next(node_ptr); - } + context.indent = " "; + context.params = controller_ptr->params; + context.str = modules[i]; + strcpy(buffer, modules[i]); + strcat(buffer, "s"); + context.address[0] = buffer; + context.address[1] = NULL; - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) - { - goto exit_close; - } - - /* internals */ - - if (!jack_controller_settings_write_string(fd, " \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, " params, context.address, serialize_modules, &context)) { goto exit_close; } - if (!jack_controller_settings_write_string(fd, jackctl_internal_get_name(internal), dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, modules[i], dbus_call_context_ptr)) { goto exit_close; } - context.indent = " "; - - if (!jack_controller_settings_save_internal_options(&context, internal, dbus_call_context_ptr)) + if (!jack_controller_settings_write_string(fd, "s>\n", dbus_call_context_ptr)) { goto exit_close; } - - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) - { - goto exit_close; - } - - node_ptr = jack_slist_next(node_ptr); - } - - if (!jack_controller_settings_write_string(fd, " \n", dbus_call_context_ptr)) - { - goto exit_close; } if (!jack_controller_settings_write_string(fd, "\n", dbus_call_context_ptr))