Merge branch 'master' into port_register_notification_defer
[jack2.git] / dbus / xml_libxml.c
blob8644182d4319311694ee1bd1a5ad8fbb7addaef8
1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
2 /*
3 Copyright (C) 2007,2008 Nedko Arnaudov
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #if defined(HAVE_CONFIG_H)
21 #include "config.h"
22 #endif
24 #include <stdbool.h>
25 #include <string.h>
26 #include <dbus/dbus.h>
28 #include <libxml/xmlwriter.h>
29 #include <libxml/parser.h>
30 #include <libxml/xpath.h>
32 #include <jack/driver.h>
33 #include <jack/engine.h>
34 #include "controller_internal.h"
35 #include "dbus.h"
37 /* XPath expression used for engine options selection */
38 #define XPATH_ENGINE_OPTIONS_EXPRESSION "/jack/engine/option"
40 /* XPath expression used for drivers selection */
41 #define XPATH_DRIVERS_EXPRESSION "/jack/drivers/driver"
43 /* XPath expression used for driver options selection */
44 #define XPATH_DRIVER_OPTIONS_EXPRESSION "/jack/drivers/driver[@name = '%s']/option"
46 bool
47 jack_controller_settings_init()
50 * this initialize the library and check potential ABI mismatches
51 * between the version it was compiled for and the actual shared
52 * library used.
54 LIBXML_TEST_VERSION;
56 return true;
59 void
60 jack_controller_settings_uninit()
64 #define writer ((xmlTextWriterPtr)context)
66 bool
67 jack_controller_settings_write_option(
68 void *context,
69 const char *name,
70 const char *content,
71 void *dbus_call_context_ptr)
73 if (xmlTextWriterStartElement(writer, BAD_CAST "option") == -1)
75 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
76 return false;
79 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name) == -1)
81 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
82 return false;
85 if (xmlTextWriterWriteString(writer, BAD_CAST content) == -1)
87 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteString() failed.");
88 return false;
91 if (xmlTextWriterEndElement(writer) == -1)
93 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
94 return false;
97 return true;
100 #undef writer
102 bool
103 jack_controller_settings_write_engine(
104 struct jack_controller * controller_ptr,
105 xmlTextWriterPtr writer,
106 void *dbus_call_context_ptr)
108 /* jack_info("engine settings begin"); */
110 /* if (xmlTextWriterWriteComment(writer, BAD_CAST "engine parameters") == -1) */
111 /* { */
112 /* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
113 /* return false; */
114 /* } */
116 if (xmlTextWriterStartElement(writer, BAD_CAST "engine") == -1)
118 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
119 return false;
122 if (!jack_controller_settings_save_engine_options(writer, controller_ptr, dbus_call_context_ptr))
124 return false;
127 if (xmlTextWriterEndElement(writer) == -1)
129 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
130 return false;
133 /* jack_info("engine settings end"); */
134 return true;
137 bool
138 jack_controller_settings_write_driver(
139 struct jack_controller * controller_ptr,
140 xmlTextWriterPtr writer,
141 jackctl_driver driver,
142 void *dbus_call_context_ptr)
144 /* if (xmlTextWriterWriteComment(writer, BAD_CAST "driver parameters") == -1) */
145 /* { */
146 /* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
147 /* return false; */
148 /* } */
150 if (xmlTextWriterStartElement(writer, BAD_CAST "driver") == -1)
152 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
153 return false;
156 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST jackctl_driver_get_name(driver)) == -1)
158 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
159 return false;
162 if (!jack_controller_settings_save_driver_options(writer, driver, dbus_call_context_ptr))
164 return false;
167 if (xmlTextWriterEndElement(writer) == -1)
169 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
170 return false;
173 return true;
176 bool
177 jack_controller_settings_write_drivers(
178 struct jack_controller * controller_ptr,
179 xmlTextWriterPtr writer,
180 void *dbus_call_context_ptr)
182 const JSList * node_ptr;
183 jackctl_driver driver;
185 if (xmlTextWriterStartElement(writer, BAD_CAST "drivers") == -1)
187 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
188 return false;
191 node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
193 while (node_ptr != NULL)
195 driver = (jackctl_driver)node_ptr->data;
197 if (!jack_controller_settings_write_driver(
198 controller_ptr,
199 writer,
200 driver,
201 dbus_call_context_ptr))
203 return false;
206 node_ptr = jack_slist_next(node_ptr);
209 if (xmlTextWriterEndElement(writer) == -1)
211 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
212 return false;
215 return true;
218 bool
219 jack_controller_settings_write_internal(
220 struct jack_controller * controller_ptr,
221 xmlTextWriterPtr writer,
222 jackctl_internal internal,
223 void *dbus_call_context_ptr)
225 /* if (xmlTextWriterWriteComment(writer, BAD_CAST "driver parameters") == -1) */
226 /* { */
227 /* jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed."); */
228 /* return false; */
229 /* } */
231 if (xmlTextWriterStartElement(writer, BAD_CAST "internal") == -1)
233 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
234 return false;
237 if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST jackctl_internal_get_name(driver)) == -1)
239 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteAttribute() failed.");
240 return false;
243 if (!jack_controller_settings_save_internal_options(writer, internal, dbus_call_context_ptr))
245 return false;
248 if (xmlTextWriterEndElement(writer) == -1)
250 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
251 return false;
254 return true;
257 bool
258 jack_controller_settings_write_internals(
259 struct jack_controller * controller_ptr,
260 xmlTextWriterPtr writer,
261 void *dbus_call_context_ptr)
263 const JSList * node_ptr;
264 jackctl_driver internal;
266 if (xmlTextWriterStartElement(writer, BAD_CAST "internals") == -1)
268 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
269 return false;
272 node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
274 while (node_ptr != NULL)
276 internal = (jackctl_internal)node_ptr->data;
278 if (!jack_controller_settings_write_internal(
279 controller_ptr,
280 writer,
281 internal,
282 dbus_call_context_ptr))
284 return false;
287 node_ptr = jack_slist_next(node_ptr);
290 if (xmlTextWriterEndElement(writer) == -1)
292 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndElement() failed.");
293 return false;
296 return true;
299 bool
300 jack_controller_settings_save(
301 struct jack_controller * controller_ptr,
302 void *dbus_call_context_ptr)
304 xmlTextWriterPtr writer;
305 char *filename;
306 size_t conf_len;
307 bool ret;
308 time_t timestamp;
309 char timestamp_str[28];
311 time(&timestamp);
312 timestamp_str[0] = ' ';
313 ctime_r(&timestamp, timestamp_str + 1);
314 timestamp_str[25] = ' ';
316 ret = false;
318 conf_len = strlen(JACKDBUS_CONF);
320 filename = malloc(g_jackdbus_dir_len + conf_len + 1);
321 if (filename == NULL)
323 jack_error("Out of memory.");
324 goto fail;
327 memcpy(filename, g_jackdbus_dir, g_jackdbus_dir_len);
328 memcpy(filename + g_jackdbus_dir_len, JACKDBUS_CONF, conf_len);
329 filename[g_jackdbus_dir_len + conf_len] = 0;
331 jack_info("saving settings to \"%s\"", filename);
333 writer = xmlNewTextWriterFilename(filename, 0);
334 if (writer == NULL)
336 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Error creating the xml writer.");
337 goto fail_free_filename;
340 if (xmlTextWriterSetIndent(writer, 1) == -1)
342 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterSetIndent() failed.");
343 goto fail_free_writter;
346 if (xmlTextWriterStartDocument(writer, NULL, NULL, NULL) == -1)
348 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartDocument() failed.");
349 goto fail_free_writter;
352 if (xmlTextWriterWriteComment(writer, BAD_CAST "\n" JACK_CONF_HEADER_TEXT) == -1)
354 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed.");
355 goto fail_free_writter;
358 if (xmlTextWriterWriteComment(writer, BAD_CAST timestamp_str) == -1)
360 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterWriteComment() failed.");
361 goto fail_free_writter;
364 if (xmlTextWriterStartElement(writer, BAD_CAST "jack") == -1)
366 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
367 goto fail_free_writter;
370 if (!jack_controller_settings_write_engine(controller_ptr, writer, dbus_call_context_ptr))
372 goto fail_free_writter;
375 if (!jack_controller_settings_write_drivers(controller_ptr, writer, dbus_call_context_ptr))
377 goto fail_free_writter;
380 if (!jack_controller_settings_write_internals(controller_ptr, writer, dbus_call_context_ptr))
382 goto fail_free_writter;
385 if (xmlTextWriterEndElement(writer) == -1)
387 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterStartElement() failed.");
388 goto fail_free_writter;
391 if (xmlTextWriterEndDocument(writer) == -1)
393 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "xmlTextWriterEndDocument() failed.");
394 goto fail_free_writter;
397 ret = true;
399 fail_free_writter:
400 xmlFreeTextWriter(writer);
402 fail_free_filename:
403 free(filename);
405 fail:
406 return ret;
409 void
410 jack_controller_settings_read_engine(
411 struct jack_controller * controller_ptr,
412 xmlXPathContextPtr xpath_ctx_ptr)
414 xmlXPathObjectPtr xpath_obj_ptr;
415 xmlBufferPtr content_buffer_ptr;
416 int i;
417 const char *option_name;
418 const char *option_value;
420 /* Evaluate xpath expression */
421 xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_ENGINE_OPTIONS_EXPRESSION, xpath_ctx_ptr);
422 if (xpath_obj_ptr == NULL)
424 jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_ENGINE_OPTIONS_EXPRESSION);
425 goto exit;
428 if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
430 jack_error("XPath \"%s\" evaluation returned no data", XPATH_ENGINE_OPTIONS_EXPRESSION);
431 goto free_xpath_obj;
434 content_buffer_ptr = xmlBufferCreate();
435 if (content_buffer_ptr == NULL)
437 jack_error("xmlBufferCreate() failed.");
438 goto free_xpath_obj;
441 for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
443 //jack_info("engine option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
445 if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
447 jack_error("xmlNodeBufGetContent() failed.");
448 goto next_option;
451 option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
452 option_value = (const char *)xmlBufferContent(content_buffer_ptr);
454 jack_controller_settings_set_engine_option(controller_ptr, option_name, option_value);
456 next_option:
457 xmlBufferEmpty(content_buffer_ptr);
460 //free_buffer:
461 xmlBufferFree(content_buffer_ptr);
463 free_xpath_obj:
464 xmlXPathFreeObject(xpath_obj_ptr);
466 exit:
467 return;
470 void
471 jack_controller_settings_read_driver(
472 struct jack_controller * controller_ptr,
473 xmlXPathContextPtr xpath_ctx_ptr,
474 jackctl_driver driver)
476 char *xpath;
477 size_t xpath_len;
478 xmlXPathObjectPtr xpath_obj_ptr;
479 xmlBufferPtr content_buffer_ptr;
480 int i;
481 const char *option_name;
482 const char *option_value;
483 const char *driver_name;
485 driver_name = jackctl_driver_get_name(driver);
487 jack_info("reading options for driver \"%s\"", driver_name);
489 xpath_len = snprintf(NULL, 0, XPATH_DRIVER_OPTIONS_EXPRESSION, driver_name);
491 xpath = malloc(xpath_len);
492 if (xpath == NULL)
494 jack_error("Out of memory.");
495 goto exit;
498 snprintf(xpath, xpath_len, XPATH_DRIVER_OPTIONS_EXPRESSION, driver_name);
500 //jack_info("xpath = \"%s\"", xpath);
502 /* Evaluate xpath expression */
503 xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_ctx_ptr);
504 if (xpath_obj_ptr == NULL)
506 jack_error("Unable to evaluate XPath expression \"%s\"", xpath);
507 goto free_xpath;
510 if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
512 //jack_info("XPath \"%s\" evaluation returned no data", xpath);
513 goto free_xpath_obj;
516 content_buffer_ptr = xmlBufferCreate();
517 if (content_buffer_ptr == NULL)
519 jack_error("xmlBufferCreate() failed.");
520 goto free_xpath_obj;
523 for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
525 //jack_info("driver option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
527 if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
529 jack_error("xmlNodeBufGetContent() failed.");
530 goto next_option;
533 option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
534 option_value = (const char *)xmlBufferContent(content_buffer_ptr);
536 jack_controller_settings_set_driver_option(driver, option_name, option_value);
538 next_option:
539 xmlBufferEmpty(content_buffer_ptr);
542 //free_buffer:
543 xmlBufferFree(content_buffer_ptr);
545 free_xpath_obj:
546 xmlXPathFreeObject(xpath_obj_ptr);
548 free_xpath:
549 free(xpath);
551 exit:
552 return;
555 void
556 jack_controller_settings_read_internal(
557 struct jack_controller * controller_ptr,
558 xmlXPathContextPtr xpath_ctx_ptr,
559 jackctl_internal internal)
561 char *xpath;
562 size_t xpath_len;
563 xmlXPathObjectPtr xpath_obj_ptr;
564 xmlBufferPtr content_buffer_ptr;
565 int i;
566 const char *option_name;
567 const char *option_value;
568 const char *internal_name;
570 internal_name = jackctl_internal_get_name(internal);
572 jack_info("reading options for internal \"%s\"", internal_name);
574 xpath_len = snprintf(NULL, 0, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
576 xpath = malloc(xpath_len);
577 if (xpath == NULL)
579 jack_error("Out of memory.");
580 goto exit;
583 snprintf(xpath, xpath_len, XPATH_DRIVER_OPTIONS_EXPRESSION, internal_name);
585 //jack_info("xpath = \"%s\"", xpath);
587 /* Evaluate xpath expression */
588 xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_ctx_ptr);
589 if (xpath_obj_ptr == NULL)
591 jack_error("Unable to evaluate XPath expression \"%s\"", xpath);
592 goto free_xpath;
595 if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
597 //jack_info("XPath \"%s\" evaluation returned no data", xpath);
598 goto free_xpath_obj;
601 content_buffer_ptr = xmlBufferCreate();
602 if (content_buffer_ptr == NULL)
604 jack_error("xmlBufferCreate() failed.");
605 goto free_xpath_obj;
608 for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
610 //jack_info("driver option \"%s\" at index %d", xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name"), i);
612 if (xmlNodeBufGetContent(content_buffer_ptr, xpath_obj_ptr->nodesetval->nodeTab[i]) == -1)
614 jack_error("xmlNodeBufGetContent() failed.");
615 goto next_option;
618 option_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
619 option_value = (const char *)xmlBufferContent(content_buffer_ptr);
621 jack_controller_settings_set_internal_option(internal, option_name, option_value);
623 next_option:
624 xmlBufferEmpty(content_buffer_ptr);
627 //free_buffer:
628 xmlBufferFree(content_buffer_ptr);
630 free_xpath_obj:
631 xmlXPathFreeObject(xpath_obj_ptr);
633 free_xpath:
634 free(xpath);
636 exit:
637 return;
640 void
641 jack_controller_settings_read_drivers(
642 struct jack_controller * controller_ptr,
643 xmlXPathContextPtr xpath_ctx_ptr)
645 xmlXPathObjectPtr xpath_obj_ptr;
646 int i;
647 const char *driver_name;
648 jackctl_driver driver;
650 /* Evaluate xpath expression */
651 xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_DRIVERS_EXPRESSION, xpath_ctx_ptr);
652 if (xpath_obj_ptr == NULL)
654 jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_DRIVERS_EXPRESSION);
655 goto exit;
658 if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
660 jack_error("XPath \"%s\" evaluation returned no data", XPATH_DRIVERS_EXPRESSION);
661 goto free_xpath_obj;
664 for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
666 driver_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
668 driver = jack_controller_find_driver(controller_ptr->server, driver_name);
669 if (driver == NULL)
671 jack_error("ignoring settings for unknown driver \"%s\"", driver_name);
673 else
675 jack_info("setting for driver \"%s\" found", driver_name);
677 jack_controller_settings_read_driver(controller_ptr, xpath_ctx_ptr, driver);
681 free_xpath_obj:
682 xmlXPathFreeObject(xpath_obj_ptr);
684 exit:
685 return;
688 void
689 jack_controller_settings_read_internals(
690 struct jack_controller * controller_ptr,
691 xmlXPathContextPtr xpath_ctx_ptr)
693 xmlXPathObjectPtr xpath_obj_ptr;
694 int i;
695 const char *internal_name;
696 jackctl_internal internal;
698 /* Evaluate xpath expression */
699 xpath_obj_ptr = xmlXPathEvalExpression((const xmlChar *)XPATH_DRIVERS_EXPRESSION, xpath_ctx_ptr);
700 if (xpath_obj_ptr == NULL)
702 jack_error("Unable to evaluate XPath expression \"%s\"", XPATH_DRIVERS_EXPRESSION);
703 goto exit;
706 if (xpath_obj_ptr->nodesetval == NULL || xpath_obj_ptr->nodesetval->nodeNr == 0)
708 jack_error("XPath \"%s\" evaluation returned no data", XPATH_DRIVERS_EXPRESSION);
709 goto free_xpath_obj;
712 for (i = 0 ; i < xpath_obj_ptr->nodesetval->nodeNr ; i++)
714 internal_name = (const char *)xmlGetProp(xpath_obj_ptr->nodesetval->nodeTab[i], BAD_CAST "name");
716 driver = jack_controller_find_internal(controller_ptr->server, driver_name);
717 if (driver == NULL)
719 jack_error("ignoring settings for unknown internal \"%s\"", internal_name);
721 else
723 jack_info("setting for internal \"%s\" found", internal_name);
725 jack_controller_settings_read_internal(controller_ptr, xpath_ctx_ptr, driver);
729 free_xpath_obj:
730 xmlXPathFreeObject(xpath_obj_ptr);
732 exit:
733 return;
737 void
738 jack_controller_settings_load(
739 struct jack_controller * controller_ptr)
741 char *filename;
742 size_t conf_len;
743 xmlDocPtr doc_ptr;
744 xmlXPathContextPtr xpath_ctx_ptr;
746 conf_len = strlen(JACKDBUS_CONF);
748 filename = malloc(g_jackdbus_dir_len + conf_len + 1);
749 if (filename == NULL)
751 jack_error("Out of memory.");
752 goto exit;
755 memcpy(filename, g_jackdbus_dir, g_jackdbus_dir_len);
756 memcpy(filename + g_jackdbus_dir_len, JACKDBUS_CONF, conf_len);
757 filename[g_jackdbus_dir_len + conf_len] = 0;
759 jack_info("loading settings from \"%s\"", filename);
761 doc_ptr = xmlParseFile(filename);
762 if (doc_ptr == NULL)
764 jack_error("Failed to parse \"%s\"", filename);
765 goto free_filename;
768 /* Create xpath evaluation context */
769 xpath_ctx_ptr = xmlXPathNewContext(doc_ptr);
770 if (xpath_ctx_ptr == NULL)
772 jack_error("Unable to create new XPath context");
773 goto free_doc;
776 jack_controller_settings_read_engine(controller_ptr, xpath_ctx_ptr);
777 jack_controller_settings_read_drivers(controller_ptr, xpath_ctx_ptr);
778 jack_controller_settings_read_internals(controller_ptr, xpath_ctx_ptr);
780 xmlXPathFreeContext(xpath_ctx_ptr);
782 free_doc:
783 xmlFreeDoc(doc_ptr);
785 free_filename:
786 free(filename);
788 exit:
789 return;
792 void
793 jack_controller_settings_save_auto(
794 struct jack_controller * controller_ptr)
796 jack_controller_settings_save(controller_ptr, NULL);