| 
							- /* -*- 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_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 (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_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_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);
 - 
 -     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);
 - }
 
 
  |