clean code and changed version nro.
[irreco.git] / irreco / src / core / irreco_config.c
blobb1161095efb4244e7b23120337246320a74fe8f3
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi),
4 * Harri Vattulainen (t5vaha01@students.oamk.fi)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "irreco_config.h"
22 #include "irreco_button.h"
23 #include "irreco_theme_button.h"
25 /**
26 * @addtogroup IrrecoConfig
27 * @ingroup Irreco
29 * Configuration saving and reading.
31 * @{
34 /**
35 * @file
36 * Source file of @ref IrrecoConfig.
40 #define IRRECO_CONFIG_GROUP_LEN 20
42 gchar* irreco_config_layout_file = "layouts.conf";
43 gchar* irreco_config_active_layout_file = "active-layout.conf";
44 gchar* irreco_config_backend_file = "backends.conf";
45 gchar* irreco_config_cmd_chain_file = "command-chains.conf";
49 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
50 /* Prototypes */
51 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
53 void irreco_config_read_button_from_keyfile(IrrecoData * irreco_data,
54 IrrecoKeyFile * keyfile);
55 void irreco_config_read_hardkey_from_keyfile(IrrecoData * irreco_data,
56 IrrecoKeyFile * keyfile);
57 void irreco_config_read_layout_from_keyfile(IrrecoData * irreco_data,
58 IrrecoKeyFile * keyfile);
59 void irreco_config_save_layout_to_keyfile(GKeyFile * keyfile,
60 IrrecoButtonLayout * layout,
61 gint * layout_index,
62 gint * button_index,
63 gint * command_index,
64 gint * hardkey_index);
65 void irreco_config_save_hardkey_to_file(IrrecoHardkeyMap *hardkey_map,
66 guint keyval,
67 IrrecoCmdChainId chain_id,
68 IrrecoCmdChain *chain,
69 gpointer user_data);
70 void irreco_config_save_button_to_keyfile(GKeyFile * keyfile,
71 IrrecoButton * button,
72 gint * button_index,
73 gint * command_index);
74 void irreco_config_save_cmd_chain_to_keyfile(GKeyFile * keyfile,
75 IrrecoButton * button,
76 gint * command_index);
77 void irreco_config_read_backend_from_keyfile(
78 IrrecoBackendManager * backend_manager,
79 IrrecoKeyFile * keyfile);
83 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
84 /* Layout reading. */
85 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
87 /**
88 * @name Layout reading
89 * @{
92 gboolean irreco_config_read_layouts(IrrecoData * irreco_data)
94 guint i;
95 IrrecoKeyFile *keyfile = NULL;
96 gchar *config_dir = NULL;
97 gchar *config_file = NULL;
98 gchar** groups = NULL;
99 gsize group_count = 0;
100 IRRECO_ENTER
102 config_dir = irreco_get_config_dir("irreco");
103 config_file = irreco_get_config_file("irreco",
104 irreco_config_layout_file);
105 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
106 if (config_dir == NULL || config_file == NULL || keyfile == NULL) {
107 g_free(config_dir);
108 g_free(config_file);
109 irreco_keyfile_destroy(keyfile);
110 IRRECO_RETURN_BOOL(FALSE);
113 IRRECO_PRINTF("Reading layout configuration file \"%s\"\n",
114 config_file);
115 groups = g_key_file_get_groups(keyfile->keyfile, &group_count);
117 /* Read layouts. */
118 for (i = 0; i < group_count; i++) {
119 gchar *group = groups[i];
120 if (g_str_has_prefix(group, "layout")) {
121 IRRECO_PRINTF("Reading layout group \"%s\"\n", group);
122 irreco_keyfile_set_group(keyfile, group);
123 irreco_config_read_layout_from_keyfile(irreco_data,
124 keyfile);
128 /* Read Buttons. */
129 for (i = 0; i < group_count; i++) {
130 gchar *group = groups[i];
131 if (g_str_has_prefix(group, "button")) {
132 IRRECO_PRINTF("Reading button group \"%s\"\n", group);
133 irreco_keyfile_set_group(keyfile, group);
134 irreco_config_read_button_from_keyfile(irreco_data,
135 keyfile);
139 /* Read Hardkeys. */
140 for (i = 0; i < group_count; i++) {
141 gchar *group = groups[i];
142 if (g_str_has_prefix(group, "hardkey")) {
143 IRRECO_PRINTF("Reading hardkey group \"%s\"\n", group);
144 irreco_keyfile_set_group(keyfile, group);
145 irreco_config_read_hardkey_from_keyfile(irreco_data,
146 keyfile);
150 /* Read command chains. */
151 irreco_cmd_chain_manager_from_config(irreco_data);
153 g_strfreev(groups);
154 irreco_keyfile_destroy(keyfile);
155 g_free(config_dir);
156 g_free(config_file);
157 IRRECO_RETURN_BOOL(TRUE);
160 void irreco_config_read_layout_from_keyfile(IrrecoData * irreco_data,
161 IrrecoKeyFile * keyfile)
163 gchar *name = NULL;
164 IrrecoButtonLayout *layout = NULL;
165 GdkColor color;
166 gint type;
167 gchar *image = NULL;
168 IRRECO_ENTER
170 /* Required fields. */
171 if (!irreco_keyfile_get_str(keyfile, "name", &name)) IRRECO_RETURN
172 layout = irreco_button_layout_create(NULL,
173 irreco_data->cmd_chain_manager);
174 irreco_button_layout_set_name(layout, name);
175 g_free(name);
176 name = NULL;
178 if (irreco_keyfile_get_int(keyfile, "bg-type", &type)) {
179 switch (type) {
180 case IRRECO_BACKGROUND_DEFAULT:
181 case IRRECO_BACKGROUND_COLOR:
182 case IRRECO_BACKGROUND_IMAGE:
183 irreco_button_layout_set_bg_type(layout, type);
184 break;
186 default:
187 IRRECO_ERROR("Unknown background type \"%i\".\n",
188 type);
189 break;
193 if (irreco_keyfile_get_str(keyfile, "bg-image", &image)) {
194 irreco_button_layout_set_bg_image(layout, image);
195 g_free(image);
196 image = NULL;
199 color.pixel = 0;
200 if (irreco_keyfile_get_uint16(keyfile, "bg-color-red", &color.red) &&
201 irreco_keyfile_get_uint16(keyfile, "bg-color-green", &color.green)&&
202 irreco_keyfile_get_uint16(keyfile, "bg-color-blue", &color.blue)) {
203 irreco_button_layout_set_bg_color(layout, &color);
206 if (!irreco_string_table_add(irreco_data->irreco_layout_array,
207 irreco_button_layout_get_name(layout),
208 layout)) {
209 IRRECO_ERROR("Layout \"%s\" already exists.",
210 irreco_button_layout_get_name(layout));
211 irreco_button_layout_destroy(layout);
214 IRRECO_RETURN
217 void irreco_config_read_button_from_keyfile(IrrecoData * irreco_data,
218 IrrecoKeyFile * keyfile)
220 gchar *layout_name = NULL;
221 gchar *style_name = NULL;
222 gchar *title = NULL;
223 gchar *command = NULL;
224 IrrecoCmdChainId chain_id;
225 gint x;
226 gint y;
228 IrrecoButton *button = NULL;
229 IrrecoButtonLayout *layout = NULL;
230 IrrecoThemeButton *style = NULL;
231 IRRECO_ENTER
233 /* Required fields. */
234 if (!irreco_keyfile_get_int(keyfile, "x", &x) ||
235 !irreco_keyfile_get_int(keyfile, "y", &y) ||
236 !irreco_keyfile_get_str(keyfile, "layout", &layout_name)) {
237 IRRECO_RETURN
239 IRRECO_PRINTF("Position: x%i y%i\n", x, y);
241 /* Find layout. */
242 if (!irreco_string_table_get(irreco_data->irreco_layout_array,
243 layout_name, (gpointer *) &layout)) {
244 IRRECO_ERROR("Button uses unknown layout \"%s\"\n",
245 layout_name);
246 g_free(layout_name);
247 IRRECO_RETURN
249 g_free(layout_name);
250 IRRECO_PRINTF("Style: \"%s\"\n",
251 irreco_button_layout_get_name(layout));
253 /* Find style. */
254 irreco_keyfile_get_str(keyfile, "style", &style_name);
255 if (style_name != NULL) {
256 if (irreco_theme_manager_get_button_style(
257 irreco_data->theme_manager,
258 style_name, &style)) {
259 IRRECO_LINE
260 IRRECO_PRINTF("Style: \"%s\"\n", style->name->str);
261 } else {
262 IRRECO_ERROR("Button uses unknown style \"%s\"\n",
263 style_name);
266 g_free(style_name);
269 /* Get title and command. */
270 irreco_keyfile_get_str(keyfile, "title", &title);
271 IRRECO_PRINTF("title: \"%s\"\n", title);
273 button = irreco_button_create(layout, x, y, title, style,
274 irreco_data->cmd_chain_manager);
276 if (irreco_keyfile_get_int(keyfile, "command-chain-id", &chain_id)) {
277 irreco_button_set_cmd_chain_id(button, chain_id);
280 g_free(title);
281 g_free(command);
282 IRRECO_RETURN
285 void irreco_config_read_hardkey_from_keyfile(IrrecoData * irreco_data,
286 IrrecoKeyFile * keyfile)
288 IrrecoButtonLayout *layout = NULL;
289 gchar *layout_name = NULL;
290 IrrecoCmdChainId id;
291 guint keyval;
292 gchar *hardkey_str = NULL;
293 IRRECO_ENTER
295 /* Required fields. */
296 if (!irreco_keyfile_get_str(keyfile, "layout", &layout_name) ||
297 !irreco_keyfile_get_int(keyfile, "chain-id", &id) ||
298 !irreco_keyfile_get_uint(keyfile, "key-value", &keyval)) {
299 g_free(layout_name);
300 IRRECO_RETURN
303 /* Find layout. */
304 if (!irreco_string_table_get(irreco_data->irreco_layout_array,
305 layout_name, (gpointer *) &layout)) {
306 IRRECO_ERROR("Hardkey uses unknown layout \"%s\"\n",
307 layout_name);
308 g_free(layout_name);
309 IRRECO_RETURN
311 g_free(layout_name);
313 hardkey_str = irreco_hardkey_to_str(keyval);
314 IRRECO_PRINTF("Associating layout \"%s\" hardkey \"%s\" with "
315 "command chain \"%i\".\n",
316 irreco_button_layout_get_name(layout),
317 hardkey_str, id);
318 g_free(hardkey_str);
320 irreco_hardkey_map_assosiate_chain_with_id(layout->hardkey_map,
321 keyval, id);
322 IRRECO_RETURN
325 /** @} */
329 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
330 /* Layout saving. */
331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
334 * @name Layout saving
335 * @{
339 * Save layout.
341 * Since GKeyFile does not allow two groups with the same name,
342 * layout_index and button_index variables are used to make sure that each
343 * button and layout group has unique name. The index is ignored when reading
344 * the layout config.
346 gboolean irreco_config_save_layouts(IrrecoData * irreco_data)
348 gint layout_index = 1;
349 gint button_index = 1;
350 gint command_index = 1;
351 gint hardkey_index = 1;
352 GKeyFile *keyfile;
353 IrrecoStringTable *table;
354 gboolean success;
355 IRRECO_ENTER
357 irreco_cmd_chain_manager_to_config(irreco_data->cmd_chain_manager);
359 keyfile = g_key_file_new();
360 table = irreco_data->irreco_layout_array;
361 IRRECO_STRING_TABLE_FOREACH(table, key, IrrecoButtonLayout *, layout)
362 irreco_config_save_layout_to_keyfile(keyfile,
363 layout,
364 &layout_index,
365 &button_index,
366 &command_index,
367 &hardkey_index);
368 layout_index++;
369 IRRECO_STRING_TABLE_FOREACH_END
371 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
372 irreco_config_layout_file);
373 g_key_file_free(keyfile);
374 IRRECO_RETURN_BOOL(success);
377 typedef struct _IrrecoConfigSaveHardkeyData IrrecoConfigSaveHardkeyData;
378 struct _IrrecoConfigSaveHardkeyData {
379 GKeyFile *keyfile;
380 gint *hardkey_index;
381 IrrecoButtonLayout *layout;
384 void irreco_config_save_layout_to_keyfile(GKeyFile * keyfile,
385 IrrecoButtonLayout * layout,
386 gint * layout_index,
387 gint * button_index,
388 gint * command_index,
389 gint * hardkey_index)
391 GdkColor *color;
392 gchar group[IRRECO_CONFIG_GROUP_LEN];
393 IrrecoConfigSaveHardkeyData hardkey_data;
394 IRRECO_ENTER
396 /* Save layout. */
397 g_assert(irreco_button_layout_get_name(layout) != NULL);
398 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "layout-%i", *layout_index);
399 irreco_gkeyfile_set_string(keyfile, group, "name",
400 irreco_button_layout_get_name(layout));
401 g_key_file_set_integer(keyfile, group, "bg-type",
402 irreco_button_layout_get_bg_type(layout));
403 irreco_gkeyfile_set_string(keyfile, group, "bg-image",
404 irreco_button_layout_get_bg_image(layout));
405 color = irreco_button_layout_get_bg_color(layout);
406 g_key_file_set_integer(keyfile, group, "bg-color-red", color->red);
407 g_key_file_set_integer(keyfile, group, "bg-color-green", color->green);
408 g_key_file_set_integer(keyfile, group, "bg-color-blue", color->blue);
410 /* Save buttons. */
411 irreco_button_layout_reindex(layout);
412 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array, IrrecoButton *, button)
413 irreco_config_save_button_to_keyfile(keyfile,
414 button,
415 button_index,
416 command_index);
417 *button_index = *button_index + 1;
418 IRRECO_PTR_ARRAY_FORWARDS_END
420 /* Save Hardkeys. */
421 hardkey_data.keyfile = keyfile;
422 hardkey_data.hardkey_index = hardkey_index;
423 hardkey_data.layout = layout;
424 irreco_hardkey_map_chain_foreach(layout->hardkey_map,
425 irreco_config_save_hardkey_to_file,
426 &hardkey_data);
427 IRRECO_RETURN
430 void irreco_config_save_hardkey_to_file(IrrecoHardkeyMap *hardkey_map,
431 guint keyval,
432 IrrecoCmdChainId chain_id,
433 IrrecoCmdChain *chain,
434 gpointer user_data)
436 gchar group[IRRECO_CONFIG_GROUP_LEN];
437 IrrecoConfigSaveHardkeyData *hardkey_data;
438 IRRECO_ENTER
440 hardkey_data = (IrrecoConfigSaveHardkeyData*) user_data;
442 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "hardkey-%i",
443 *hardkey_data->hardkey_index);
444 irreco_gkeyfile_set_string(hardkey_data->keyfile, group, "layout",
445 irreco_button_layout_get_name(hardkey_data->layout));
446 g_key_file_set_integer(hardkey_data->keyfile, group,
447 "chain-id", chain_id);
448 irreco_gkeyfile_set_guint(hardkey_data->keyfile, group,
449 "key-value", keyval);
451 *hardkey_data->hardkey_index = *hardkey_data->hardkey_index + 1;
452 IRRECO_RETURN
455 void irreco_config_save_button_to_keyfile(GKeyFile * keyfile,
456 IrrecoButton * button,
457 gint * button_index,
458 gint * command_index)
460 gchar group[IRRECO_CONFIG_GROUP_LEN];
461 IRRECO_ENTER
463 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "button-%i", *button_index);
464 irreco_gkeyfile_set_string(keyfile, group, "layout",
465 irreco_button_layout_get_name(button->irreco_layout));
466 irreco_gkeyfile_set_string(keyfile, group, "title", button->title);
467 g_key_file_set_integer(keyfile, group, "index", button->index);
468 g_key_file_set_integer(keyfile, group, "command-chain-id",
469 button->cmd_chain_id);
470 g_key_file_set_integer(keyfile, group, "x", button->x);
471 g_key_file_set_integer(keyfile, group, "y", button->y);
473 /* It is valid for a button to have NULL style. */
474 if (button->style != NULL) {
475 irreco_gkeyfile_set_string(keyfile, group, "style",
476 button->style->style_name->str);
479 IRRECO_RETURN
482 /** @} */
486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
487 /* Save / Read active layout. */
488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
491 * @name Save / Read active layout
492 * @{
495 gboolean irreco_config_save_active_layout(IrrecoButtonLayout * irreco_layout)
497 GKeyFile *keyfile;
498 gboolean success;
499 IRRECO_ENTER
501 keyfile = g_key_file_new();
502 if (irreco_layout != NULL) {
503 irreco_gkeyfile_set_string(keyfile, "active-layout", "name",
504 irreco_button_layout_get_name(irreco_layout));
506 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
507 irreco_config_active_layout_file);
508 g_key_file_free(keyfile);
509 IRRECO_RETURN_BOOL(success);
512 IrrecoButtonLayout *irreco_config_read_active_layout(IrrecoData * irreco_data)
514 IrrecoKeyFile *keyfile = NULL;
515 gchar *config_dir = NULL;
516 gchar *config_file = NULL;
517 gchar *name = NULL;
518 IrrecoButtonLayout *irreco_layout = NULL;
519 IRRECO_ENTER
521 /* Attempt to read layout name, and find layout with the same name. */
522 config_dir = irreco_get_config_dir("irreco");
523 config_file = irreco_get_config_file("irreco",
524 irreco_config_active_layout_file);
525 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
526 if (config_dir != NULL && config_file != NULL && keyfile != NULL
527 && irreco_keyfile_set_group(keyfile, "active-layout")
528 && irreco_keyfile_get_str(keyfile, "name", &name)) {
530 IRRECO_DEBUG("Read active layout name \"%s\" from \"%s\".\n",
531 name, irreco_config_active_layout_file);
533 if (irreco_string_table_get(irreco_data->irreco_layout_array,
534 name, (gpointer *) &irreco_layout)){
535 IRRECO_DEBUG("Found matching layout.\n");
536 } else {
537 IRRECO_DEBUG("No matching layout found.\n");
541 irreco_keyfile_destroy(keyfile);
542 g_free(name);
543 g_free(config_dir);
544 g_free(config_file);
546 /* If we could not find correct active layout,
547 attempt to get some layout.*/
548 if (irreco_layout == NULL) {
549 irreco_string_table_index(irreco_data->irreco_layout_array, 0,
550 NULL, (gpointer *) &irreco_layout);
552 IRRECO_RETURN_PTR(irreco_layout);
555 /** @} */
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
560 /* Save / Read backend configuration. */
561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
564 * @name Save / Read backend configuration
565 * @{
568 gboolean irreco_config_save_backends(IrrecoBackendManager * backend_manager)
570 gint i = 0;
571 GKeyFile *keyfile;
572 gboolean success;
573 gchar group[IRRECO_CONFIG_GROUP_LEN];
574 IRRECO_ENTER
576 keyfile = g_key_file_new();
577 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(backend_manager, instance)
578 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "instance-%i", ++i);
579 irreco_gkeyfile_set_string(keyfile, group, "library",
580 instance->lib->filename);
581 irreco_gkeyfile_set_string(keyfile, group, "config",
582 instance->config);
583 irreco_gkeyfile_set_string(keyfile, group, "name",
584 irreco_backend_instance_get_name(instance));
585 IRRECO_BACKEND_MANAGER_FOREACH_END
587 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
588 irreco_config_backend_file);
589 g_key_file_free(keyfile);
590 IRRECO_RETURN_BOOL(success);
593 gboolean irreco_config_read_backends(IrrecoBackendManager * manager)
595 guint i;
596 IrrecoKeyFile *keyfile = NULL;
597 gchar *config_dir = NULL;
598 gchar *config_file = NULL;
599 gchar** groups = NULL;
600 gsize group_count = 0;
601 IRRECO_ENTER
603 config_dir = irreco_get_config_dir("irreco");
604 config_file = irreco_get_config_file("irreco",
605 irreco_config_backend_file);
606 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
607 if (config_dir == NULL || config_file == NULL || keyfile == NULL) {
608 g_free(config_dir);
609 g_free(config_file);
610 irreco_keyfile_destroy(keyfile);
611 IRRECO_RETURN_BOOL(FALSE);
614 IRRECO_PRINTF("Reading backend configuration file \"%s\"\n",
615 config_file);
616 groups = g_key_file_get_groups(keyfile->keyfile, &group_count);
618 /* Read instances. */
619 for (i = 0; i < group_count; i++) {
620 gchar *group = groups[i];
621 if (g_str_has_prefix(group, "instance")) {
622 IRRECO_PRINTF("Reading instance group \"%s\"\n", group);
623 irreco_keyfile_set_group(keyfile, group);
624 irreco_config_read_backend_from_keyfile(manager,
625 keyfile);
629 g_strfreev(groups);
630 irreco_keyfile_destroy(keyfile);
631 g_free(config_dir);
632 g_free(config_file);
633 IRRECO_RETURN_BOOL(TRUE);
636 void irreco_config_read_backend_from_keyfile(IrrecoBackendManager * manager,
637 IrrecoKeyFile * keyfile)
639 gchar *library = NULL;
640 gchar *config = NULL;
641 gchar *name = NULL;
642 IrrecoBackendLib *lib;
643 IRRECO_ENTER
645 /* Read variables. */
646 if (!irreco_keyfile_get_str(keyfile, "library", &library) ||
647 !irreco_keyfile_get_str(keyfile, "config", &config) ||
648 !irreco_keyfile_get_str(keyfile, "name", &name)) {
649 g_free(library);
650 g_free(config);
651 g_free(name);
652 IRRECO_RETURN
655 /* Find library. */
656 if (!irreco_backend_manager_find_lib(manager, library, &lib)) {
657 IRRECO_ERROR("Cannot find backend library \"%s\"\n", library);
658 g_free(library);
659 g_free(config);
660 g_free(name);
661 IRRECO_RETURN
663 g_free(library);
665 /* Create instance. */
666 irreco_backend_manager_create_instance(manager, lib, name, config);
667 g_free(name);
668 g_free(config);
670 IRRECO_RETURN
673 /** @} */
674 /** @} */