jackdbus: remove the libxml backend
It was be problematic in past (FFADO uses libxml as well). Most systems will have both libxml and expat. Maintaining two backends is waste of effort. If needed, the libxml backend can be resurrected. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4314 0c269be4-1314-0410-8aa9-9f06e86f4224
This commit is contained in:
parent
8a845aa02a
commit
4b9b621a31
|
@ -59,7 +59,6 @@ def build(bld):
|
|||
'controller_iface_transport.c',
|
||||
'xml.c',
|
||||
'xml_expat.c',
|
||||
#'xml_libxml.c',
|
||||
#'xml_nop.c',
|
||||
'xml_write_raw.c',
|
||||
'sigsegv.c',
|
||||
|
|
|
@ -1,797 +0,0 @@
|
|||
/* -*- Mode: C ; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
Copyright (C) 2007,2008 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.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
#include <jack/driver.h>
|
||||
#include <jack/engine.h>
|
||||
#include "controller_internal.h"
|
||||
#include "dbus.h"
|
||||
|
||||
/* XPath expression used for engine options selection */
|
||||
#define XPATH_ENGINE_OPTIONS_EXPRESSION "/jack/engine/option"
|
||||
|
||||
/* XPath expression used for drivers selection */
|
||||
#define XPATH_DRIVERS_EXPRESSION "/jack/drivers/driver"
|
||||
|
||||
/* XPath expression used for driver options selection */
|
||||
#define XPATH_DRIVER_OPTIONS_EXPRESSION "/jack/drivers/driver[@name = '%s']/option"
|
||||
|
||||
bool
|
||||
jack_controller_settings_init()
|
||||
{
|
||||
/*
|
||||
* this initialize the library and check potential ABI mismatches
|
||||
* between the version it was compiled for and the actual shared
|
||||
* library used.
|
||||
*/
|
||||
LIBXML_TEST_VERSION;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_uninit()
|
||||
{
|
||||
}
|
||||
|
||||
#define writer ((xmlTextWriterPtr)context)
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_option(
|
||||
void *context,
|
||||
const char *name,
|
||||
const char *content,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "option") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteString(writer, BAD_CAST content) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteString() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef writer
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_engine(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlTextWriterPtr writer,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
/* jack_info("engine settings begin"); */
|
||||
|
||||
/* if (xmlTextWriterWriteComment(writer, BAD_CAST "engine parameters") == -1) */
|
||||
/* { */
|
||||
/* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
|
||||
/* return false; */
|
||||
/* } */
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "engine") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_save_engine_options(writer, controller_ptr, dbus_call_context_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* jack_info("engine settings end"); */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_driver(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlTextWriterPtr writer,
|
||||
jackctl_driver driver,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
/* if (xmlTextWriterWriteComment(writer, BAD_CAST "driver parameters") == -1) */
|
||||
/* { */
|
||||
/* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
|
||||
/* return false; */
|
||||
/* } */
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "driver") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST jackctl_driver_get_name(driver)) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_save_driver_options(writer, driver, dbus_call_context_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_drivers(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlTextWriterPtr writer,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
const JSList * node_ptr;
|
||||
jackctl_driver driver;
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "drivers") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
|
||||
|
||||
while (node_ptr != NULL)
|
||||
{
|
||||
driver = (jackctl_driver)node_ptr->data;
|
||||
|
||||
if (!jack_controller_settings_write_driver(
|
||||
controller_ptr,
|
||||
writer,
|
||||
driver,
|
||||
dbus_call_context_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
node_ptr = jack_slist_next(node_ptr);
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_internal(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlTextWriterPtr writer,
|
||||
jackctl_internal internal,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
/* if (xmlTextWriterWriteComment(writer, BAD_CAST "driver parameters") == -1) */
|
||||
/* { */
|
||||
/* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
|
||||
/* return false; */
|
||||
/* } */
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "internal") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST jackctl_internal_get_name(driver)) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_save_internal_options(writer, internal, dbus_call_context_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_controller_settings_write_internals(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlTextWriterPtr writer,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
const JSList * node_ptr;
|
||||
jackctl_driver internal;
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "internals") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
|
||||
|
||||
while (node_ptr != NULL)
|
||||
{
|
||||
internal = (jackctl_internal)node_ptr->data;
|
||||
|
||||
if (!jack_controller_settings_write_internal(
|
||||
controller_ptr,
|
||||
writer,
|
||||
internal,
|
||||
dbus_call_context_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
node_ptr = jack_slist_next(node_ptr);
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_controller_settings_save(
|
||||
struct jack_controller * controller_ptr,
|
||||
void *dbus_call_context_ptr)
|
||||
{
|
||||
xmlTextWriterPtr writer;
|
||||
char *filename;
|
||||
size_t conf_len;
|
||||
bool ret;
|
||||
time_t timestamp;
|
||||
char timestamp_str[28];
|
||||
|
||||
time(×tamp);
|
||||
timestamp_str[0] = ' ';
|
||||
ctime_r(×tamp, timestamp_str + 1);
|
||||
timestamp_str[25] = ' ';
|
||||
|
||||
ret = false;
|
||||
|
||||
conf_len = strlen(JACKDBUS_CONF);
|
||||
|
||||
filename = malloc(g_jackdbus_dir_len + conf_len + 1);
|
||||
if (filename == NULL)
|
||||
{
|
||||
jack_error("Out of memory.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(filename, g_jackdbus_dir, g_jackdbus_dir_len);
|
||||
memcpy(filename + g_jackdbus_dir_len, JACKDBUS_CONF, conf_len);
|
||||
filename[g_jackdbus_dir_len + conf_len] = 0;
|
||||
|
||||
jack_info("saving settings to \"%s\"", filename);
|
||||
|
||||
writer = xmlNewTextWriterFilename(filename, 0);
|
||||
if (writer == NULL)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Error creating the xml writer.");
|
||||
goto fail_free_filename;
|
||||
}
|
||||
|
||||
if (xmlTextWriterSetIndent(writer, 1) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterSetIndent() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterStartDocument(writer, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartDocument() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteComment(writer, BAD_CAST "\n" JACK_CONF_HEADER_TEXT) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterWriteComment(writer, BAD_CAST timestamp_str) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "jack") == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_write_engine(controller_ptr, writer, dbus_call_context_ptr))
|
||||
{
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_write_drivers(controller_ptr, writer, dbus_call_context_ptr))
|
||||
{
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (!jack_controller_settings_write_internals(controller_ptr, writer, dbus_call_context_ptr))
|
||||
{
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndElement(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
if (xmlTextWriterEndDocument(writer) == -1)
|
||||
{
|
||||
jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndDocument() failed.");
|
||||
goto fail_free_writter;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
fail_free_writter:
|
||||
xmlFreeTextWriter(writer);
|
||||
|
||||
fail_free_filename:
|
||||
free(filename);
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_read_engine(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlXPathContextPtr xpath_ctx_ptr)
|
||||
{
|
||||
xmlXPathObjectPtr xpath_obj_ptr;
|
||||
xmlBufferPtr content_buffer_ptr;
|
||||
int i;
|
||||
const char *option_name;
|
||||
const char *option_value;
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_ENGINE_OPTIONS_EXPRESSION, xpath_ctx_ptr);
|
||||
if (xpath_obj_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_ENGINE_OPTIONS_EXPRESSION);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
|
||||
{
|
||||
jack_error("XPath \"%s\" evaluation returned no data", XPATH_ENGINE_OPTIONS_EXPRESSION);
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
content_buffer_ptr = xmlBufferCreate();
|
||||
if (content_buffer_ptr == NULL)
|
||||
{
|
||||
jack_error("xmlBufferCreate() failed.");
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
|
||||
{
|
||||
//jack_info("engine option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
|
||||
|
||||
if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
|
||||
{
|
||||
jack_error("xmlNodeBufGetContent() failed.");
|
||||
goto next_option;
|
||||
}
|
||||
|
||||
option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
|
||||
option_value = (const char *)xmlBufferContent(content_buffer_ptr);
|
||||
|
||||
jack_controller_settings_set_engine_option(controller_ptr, option_name, option_value);
|
||||
|
||||
next_option:
|
||||
xmlBufferEmpty(content_buffer_ptr);
|
||||
}
|
||||
|
||||
//free_buffer:
|
||||
xmlBufferFree(content_buffer_ptr);
|
||||
|
||||
free_xpath_obj:
|
||||
xmlXPathFreeObject(xpath_obj_ptr);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_read_driver(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlXPathContextPtr xpath_ctx_ptr,
|
||||
jackctl_driver driver)
|
||||
{
|
||||
char *xpath;
|
||||
size_t xpath_len;
|
||||
xmlXPathObjectPtr xpath_obj_ptr;
|
||||
xmlBufferPtr content_buffer_ptr;
|
||||
int i;
|
||||
const char *option_name;
|
||||
const char *option_value;
|
||||
const char *driver_name;
|
||||
|
||||
driver_name = jackctl_driver_get_name(driver);
|
||||
|
||||
jack_info("reading options for driver \"%s\"", driver_name);
|
||||
|
||||
xpath_len = snprintf(NULL, 0, XPATH_DRIVER_OPTIONS_EXPRESSION, driver_name);
|
||||
|
||||
xpath = malloc(xpath_len);
|
||||
if (xpath == NULL)
|
||||
{
|
||||
jack_error("Out of memory.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
snprintf(xpath, xpath_len, XPATH_DRIVER_OPTIONS_EXPRESSION, driver_name);
|
||||
|
||||
//jack_info("xpath = \"%s\"", xpath);
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_ctx_ptr);
|
||||
if (xpath_obj_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to evaluate XPath expression \"%s\"", xpath);
|
||||
goto free_xpath;
|
||||
}
|
||||
|
||||
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
|
||||
{
|
||||
//jack_info("XPath \"%s\" evaluation returned no data", xpath);
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
content_buffer_ptr = xmlBufferCreate();
|
||||
if (content_buffer_ptr == NULL)
|
||||
{
|
||||
jack_error("xmlBufferCreate() failed.");
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
|
||||
{
|
||||
//jack_info("driver option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
|
||||
|
||||
if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
|
||||
{
|
||||
jack_error("xmlNodeBufGetContent() failed.");
|
||||
goto next_option;
|
||||
}
|
||||
|
||||
option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
|
||||
option_value = (const char *)xmlBufferContent(content_buffer_ptr);
|
||||
|
||||
jack_controller_settings_set_driver_option(driver, option_name, option_value);
|
||||
|
||||
next_option:
|
||||
xmlBufferEmpty(content_buffer_ptr);
|
||||
}
|
||||
|
||||
//free_buffer:
|
||||
xmlBufferFree(content_buffer_ptr);
|
||||
|
||||
free_xpath_obj:
|
||||
xmlXPathFreeObject(xpath_obj_ptr);
|
||||
|
||||
free_xpath:
|
||||
free(xpath);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_read_internal(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlXPathContextPtr xpath_ctx_ptr,
|
||||
jackctl_internal internal)
|
||||
{
|
||||
char *xpath;
|
||||
size_t xpath_len;
|
||||
xmlXPathObjectPtr xpath_obj_ptr;
|
||||
xmlBufferPtr content_buffer_ptr;
|
||||
int i;
|
||||
const char *option_name;
|
||||
const char *option_value;
|
||||
const char *internal_name;
|
||||
|
||||
internal_name = jackctl_internal_get_name(internal);
|
||||
|
||||
jack_info("reading options for internal \"%s\"", internal_name);
|
||||
|
||||
xpath_len = snprintf(NULL, 0, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
|
||||
|
||||
xpath = malloc(xpath_len);
|
||||
if (xpath == NULL)
|
||||
{
|
||||
jack_error("Out of memory.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
snprintf(xpath, xpath_len, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
|
||||
|
||||
//jack_info("xpath = \"%s\"", xpath);
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_ctx_ptr);
|
||||
if (xpath_obj_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to evaluate XPath expression \"%s\"", xpath);
|
||||
goto free_xpath;
|
||||
}
|
||||
|
||||
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
|
||||
{
|
||||
//jack_info("XPath \"%s\" evaluation returned no data", xpath);
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
content_buffer_ptr = xmlBufferCreate();
|
||||
if (content_buffer_ptr == NULL)
|
||||
{
|
||||
jack_error("xmlBufferCreate() failed.");
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
|
||||
{
|
||||
//jack_info("driver option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
|
||||
|
||||
if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
|
||||
{
|
||||
jack_error("xmlNodeBufGetContent() failed.");
|
||||
goto next_option;
|
||||
}
|
||||
|
||||
option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
|
||||
option_value = (const char *)xmlBufferContent(content_buffer_ptr);
|
||||
|
||||
jack_controller_settings_set_internal_option(internal, option_name, option_value);
|
||||
|
||||
next_option:
|
||||
xmlBufferEmpty(content_buffer_ptr);
|
||||
}
|
||||
|
||||
//free_buffer:
|
||||
xmlBufferFree(content_buffer_ptr);
|
||||
|
||||
free_xpath_obj:
|
||||
xmlXPathFreeObject(xpath_obj_ptr);
|
||||
|
||||
free_xpath:
|
||||
free(xpath);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_read_drivers(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlXPathContextPtr xpath_ctx_ptr)
|
||||
{
|
||||
xmlXPathObjectPtr xpath_obj_ptr;
|
||||
int i;
|
||||
const char *driver_name;
|
||||
jackctl_driver driver;
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_DRIVERS_EXPRESSION, xpath_ctx_ptr);
|
||||
if (xpath_obj_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_DRIVERS_EXPRESSION);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
|
||||
{
|
||||
jack_error("XPath \"%s\" evaluation returned no data", XPATH_DRIVERS_EXPRESSION);
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
|
||||
{
|
||||
driver_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
|
||||
|
||||
driver = jack_controller_find_driver(controller_ptr->server, driver_name);
|
||||
if (driver == NULL)
|
||||
{
|
||||
jack_error("ignoring settings for unknown driver \"%s\"", driver_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
jack_info("setting for driver \"%s\" found", driver_name);
|
||||
|
||||
jack_controller_settings_read_driver(controller_ptr, xpath_ctx_ptr, driver);
|
||||
}
|
||||
}
|
||||
|
||||
free_xpath_obj:
|
||||
xmlXPathFreeObject(xpath_obj_ptr);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_read_internals(
|
||||
struct jack_controller * controller_ptr,
|
||||
xmlXPathContextPtr xpath_ctx_ptr)
|
||||
{
|
||||
xmlXPathObjectPtr xpath_obj_ptr;
|
||||
int i;
|
||||
const char *internal_name;
|
||||
jackctl_internal internal;
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_DRIVERS_EXPRESSION, xpath_ctx_ptr);
|
||||
if (xpath_obj_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_DRIVERS_EXPRESSION);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
|
||||
{
|
||||
jack_error("XPath \"%s\" evaluation returned no data", XPATH_DRIVERS_EXPRESSION);
|
||||
goto free_xpath_obj;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
|
||||
{
|
||||
internal_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
|
||||
|
||||
driver = jack_controller_find_internal(controller_ptr->server, driver_name);
|
||||
if (driver == NULL)
|
||||
{
|
||||
jack_error("ignoring settings for unknown internal \"%s\"", internal_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
jack_info("setting for internal \"%s\" found", internal_name);
|
||||
|
||||
jack_controller_settings_read_internal(controller_ptr, xpath_ctx_ptr, driver);
|
||||
}
|
||||
}
|
||||
|
||||
free_xpath_obj:
|
||||
xmlXPathFreeObject(xpath_obj_ptr);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
jack_controller_settings_load(
|
||||
struct jack_controller * controller_ptr)
|
||||
{
|
||||
char *filename;
|
||||
size_t conf_len;
|
||||
xmlDocPtr doc_ptr;
|
||||
xmlXPathContextPtr xpath_ctx_ptr;
|
||||
|
||||
conf_len = strlen(JACKDBUS_CONF);
|
||||
|
||||
filename = malloc(g_jackdbus_dir_len + conf_len + 1);
|
||||
if (filename == NULL)
|
||||
{
|
||||
jack_error("Out of memory.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(filename, g_jackdbus_dir, g_jackdbus_dir_len);
|
||||
memcpy(filename + g_jackdbus_dir_len, JACKDBUS_CONF, conf_len);
|
||||
filename[g_jackdbus_dir_len + conf_len] = 0;
|
||||
|
||||
jack_info("loading settings from \"%s\"", filename);
|
||||
|
||||
doc_ptr = xmlParseFile(filename);
|
||||
if (doc_ptr == NULL)
|
||||
{
|
||||
jack_error("Failed to parse \"%s\"", filename);
|
||||
goto free_filename;
|
||||
}
|
||||
|
||||
/* Create xpath evaluation context */
|
||||
xpath_ctx_ptr = xmlXPathNewContext(doc_ptr);
|
||||
if (xpath_ctx_ptr == NULL)
|
||||
{
|
||||
jack_error("Unable to create new XPath context");
|
||||
goto free_doc;
|
||||
}
|
||||
|
||||
jack_controller_settings_read_engine(controller_ptr, xpath_ctx_ptr);
|
||||
jack_controller_settings_read_drivers(controller_ptr, xpath_ctx_ptr);
|
||||
jack_controller_settings_read_internals(controller_ptr, xpath_ctx_ptr);
|
||||
|
||||
xmlXPathFreeContext(xpath_ctx_ptr);
|
||||
|
||||
free_doc:
|
||||
xmlFreeDoc(doc_ptr);
|
||||
|
||||
free_filename:
|
||||
free(filename);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
jack_controller_settings_save_auto(
|
||||
struct jack_controller * controller_ptr)
|
||||
{
|
||||
jack_controller_settings_save(controller_ptr, NULL);
|
||||
}
|
Loading…
Reference in New Issue