Mostly minor fixes up until version 0.8.10.
[irreco.git] / irreco / src / core / irreco_config.c
blob972853ff1ce8edf17962edd008fb420841d82688
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi),
4 * Harri Vattulainen (t5vaha01@students.oamk.fi)
5 * Sami Mäki (kasmra@xob.kapsi.fi)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "irreco_config.h"
23 #include "irreco_button.h"
24 #include "irreco_theme_button.h"
26 /**
27 * @addtogroup IrrecoConfig
28 * @ingroup Irreco
30 * Configuration saving and reading.
32 * @{
35 /**
36 * @file
37 * Source file of @ref IrrecoConfig.
41 #define IRRECO_CONFIG_GROUP_LEN 20
42 #define ENABLE_DEBUGGING 0
44 gchar* irreco_config_layout_file = "layouts.conf";
45 gchar* irreco_config_active_layout_file = "active-layout.conf";
46 gchar* irreco_config_backend_file = "backends.conf";
47 gchar* irreco_config_cmd_chain_file = "command-chains.conf";
51 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 /* Prototypes */
53 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
55 void irreco_config_read_button_from_keyfile(IrrecoData * irreco_data,
56 IrrecoKeyFile * keyfile,
57 IrrecoStringTable *list);
58 void irreco_config_read_hardkey_from_keyfile(IrrecoData * irreco_data,
59 IrrecoKeyFile * keyfile,
60 IrrecoStringTable *list);
61 void irreco_config_read_layout_from_keyfile(IrrecoData * irreco_data,
62 IrrecoKeyFile * keyfile,
63 const gchar *filename);
64 void irreco_config_save_layout_to_keyfile(GKeyFile * keyfile,
65 IrrecoButtonLayout * layout,
66 gint * command_index,
67 gint * hardkey_id);
68 void irreco_config_save_hardkey_to_file(IrrecoHardkeyMap *hardkey_map,
69 guint keyval,
70 IrrecoCmdChainId chain_id,
71 IrrecoCmdChain *chain,
72 gpointer user_data);
73 void irreco_config_save_hardkey_to_keyfile(IrrecoHardkeyMap *hardkey_map,
74 guint keyval,
75 IrrecoCmdChainId chain_id,
76 IrrecoCmdChain *chain,
77 gpointer user_data);
78 void irreco_config_save_button_to_keyfile(GKeyFile * keyfile,
79 IrrecoButton * button,
80 gint button_index,
81 gint * command_index);
82 void irreco_config_save_cmd_chain_to_keyfile(GKeyFile * keyfile,
83 IrrecoButton * button,
84 gint * command_index);
85 void irreco_config_read_backend_from_keyfile(
86 IrrecoBackendManager * backend_manager,
87 IrrecoKeyFile * keyfile);
88 void irreco_config_read_layouts(IrrecoDirForeachData *dir_data);
89 static void irreco_config_cmd_chain_save(gpointer key,
90 gpointer value,
91 gpointer user_data);
94 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
95 /* Layout reading. */
96 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
98 /**
99 * @name Layout reading
100 * @{
103 gboolean irreco_config_read_layouts_from_files(IrrecoData *irreco_data)
105 IrrecoDirForeachData dir_data;
107 IRRECO_ENTER
109 dir_data.directory = irreco_get_config_dir("irreco");
110 dir_data.filesuffix = ".conf";
111 dir_data.user_data_1 = irreco_data;
113 irreco_dir_foreach(&dir_data,
114 irreco_config_read_layouts);
116 IRRECO_RETURN_BOOL(TRUE);
119 void irreco_config_read_layouts(IrrecoDirForeachData *dir_data)
121 guint i;
122 IrrecoKeyFile *keyfile = NULL;
123 gchar *config_dir = NULL;
124 gchar *config_file = NULL;
125 gchar** groups = NULL;
126 gsize group_count = 0;
127 IrrecoData *irreco_data = dir_data->user_data_1;
128 IrrecoStringTable *list = irreco_string_table_new(NULL, NULL);
130 IRRECO_ENTER
132 if(!g_str_has_prefix(dir_data->filename, "layout") &&
133 !g_str_has_prefix(dir_data->filename, "command-chains") /* ||
134 strcmp(dir_data->filename, "layouts.conf") == 0*/ ) {
135 IRRECO_DEBUG("Not layout*.conf file\n");
136 IRRECO_RETURN
139 config_dir = irreco_get_config_dir("irreco");
140 /* g_sprintf(config_dir, "%s", dir_data->directory); */
141 config_file = irreco_get_config_file("irreco", dir_data->filename);
143 g_print("config_dir: %s\n", config_dir);
144 g_print("config_file: %s\n", config_file);
145 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
146 if (config_dir == NULL || config_file == NULL || keyfile == NULL) {
147 g_free(config_dir);
148 g_free(config_file);
149 irreco_keyfile_destroy(keyfile);
150 IRRECO_RETURN
153 IRRECO_PRINTF("Reading layout configuration file \"%s\"\n",
154 config_file);
155 groups = g_key_file_get_groups(keyfile->keyfile, &group_count);
157 /* Read layout. */
158 for (i = 0; i < group_count; i++) {
159 gchar *group = groups[i];
160 if (g_str_has_prefix(group, "layout")) {
161 IRRECO_PRINTF("Reading layout group \"%s\"\n", group);
162 irreco_keyfile_set_group(keyfile, group);
163 irreco_config_read_layout_from_keyfile(irreco_data,
164 keyfile,
165 dir_data->filename);
169 /* Read Buttons. */
170 for (i = 0; i < group_count; i++) {
171 gchar *group = groups[i];
172 if (g_str_has_prefix(group, "button")) {
173 IRRECO_PRINTF("Reading button group \"%s\"\n", group);
174 irreco_keyfile_set_group(keyfile, group);
175 irreco_config_read_button_from_keyfile(irreco_data,
176 keyfile,
177 list);
181 /* Read Hardkeys. */
182 for (i = 0; i < group_count; i++) {
183 gchar *group = groups[i];
184 if (g_str_has_prefix(group, "hardkey")) {
185 IRRECO_PRINTF("Reading hardkey group \"%s\"\n", group);
186 irreco_keyfile_set_group(keyfile, group);
187 irreco_config_read_hardkey_from_keyfile(irreco_data,
188 keyfile,
189 list);
193 /* Read command chains. */
194 irreco_cmd_chain_manager_from_config(dir_data, list);
196 g_free(config_dir);
197 g_free(config_file);
198 g_strfreev(groups);
199 irreco_keyfile_destroy(keyfile);
201 #if ENABLE_DEBUGGING
202 if(irreco_string_table_lenght(list) > 0)
204 IRRECO_STRING_TABLE_FOREACH(list, key, gchar *, listdata)
205 g_print("old & new id: %s, %s\n", key, listdata);
206 IRRECO_STRING_TABLE_FOREACH_END
207 } else {
208 g_print("No remapped commandchain ids\n");
210 IRRECO_PAUSE
211 #endif
213 irreco_string_table_free(list);
215 IRRECO_RETURN
218 void irreco_config_read_layout_from_keyfile(IrrecoData * irreco_data,
219 IrrecoKeyFile * keyfile,
220 const gchar *filename)
222 gchar *name = NULL;
223 IrrecoButtonLayout *layout = NULL;
224 GdkColor color;
225 gint type;
226 gchar *image = NULL;
227 IRRECO_ENTER
229 /* Required fields. */
230 if (!irreco_keyfile_get_str(keyfile, "name", &name)) IRRECO_RETURN
231 layout = irreco_button_layout_create(NULL,
232 irreco_data->cmd_chain_manager);
233 irreco_button_layout_set_name(layout, name);
234 g_free(name);
235 name = NULL;
237 /* Don't save old type filename, so it get renamed */
238 if(!strcmp(filename, "layouts.conf") == 0) {
239 irreco_button_layout_set_filename(layout, filename);
242 if (irreco_keyfile_get_int(keyfile, "bg-type", &type)) {
243 switch (type) {
244 case IRRECO_BACKGROUND_DEFAULT:
245 case IRRECO_BACKGROUND_COLOR:
246 case IRRECO_BACKGROUND_IMAGE:
247 irreco_button_layout_set_bg_type(layout, type);
248 break;
250 default:
251 IRRECO_ERROR("Unknown background type \"%i\".\n",
252 type);
253 break;
257 if (irreco_keyfile_get_str(keyfile, "bg-image", &image)) {
258 irreco_button_layout_set_bg_image(layout, image);
259 g_free(image);
260 image = NULL;
263 color.pixel = 0;
264 if (irreco_keyfile_get_uint16(keyfile, "bg-color-red", &color.red) &&
265 irreco_keyfile_get_uint16(keyfile, "bg-color-green", &color.green)&&
266 irreco_keyfile_get_uint16(keyfile, "bg-color-blue", &color.blue)) {
267 irreco_button_layout_set_bg_color(layout, &color);
270 if (!irreco_string_table_add(irreco_data->irreco_layout_array,
271 irreco_button_layout_get_name(layout),
272 layout)) {
273 IRRECO_ERROR("Layout \"%s\" already exists.",
274 irreco_button_layout_get_name(layout));
275 irreco_button_layout_destroy(layout);
278 IRRECO_RETURN
281 typedef struct _IrrecoConfigHardkeyId IrrecoConfigHardkeyId;
282 struct _IrrecoConfigHardkeyId {
283 IrrecoStringTable *ids_in_use;
284 gboolean command_clash;
285 gint command_clash2;
286 IrrecoCmdChainId chain_id;
289 void irreco_config_foreach_hardkey_id(gpointer key,
290 gpointer value,
291 gpointer user_data)
293 IrrecoConfigHardkeyId *hardkeyid;
294 gchar *id_as_gchar = g_malloc0(10);
296 IRRECO_ENTER
298 hardkeyid = (IrrecoConfigHardkeyId *) user_data;
300 if(hardkeyid->chain_id == (gint) value) {
301 hardkeyid->command_clash = TRUE;
302 hardkeyid->command_clash2 = 1;
303 g_print("clash asetettu true\n");
306 g_sprintf(id_as_gchar, "%d\n", (gint) value);
307 irreco_string_table_add(hardkeyid->ids_in_use,
308 id_as_gchar,
309 NULL);
311 g_free(id_as_gchar);
313 IRRECO_RETURN
316 void irreco_config_read_button_from_keyfile(IrrecoData * irreco_data,
317 IrrecoKeyFile * keyfile,
318 IrrecoStringTable *list)
320 gchar *layout_name = NULL;
321 gchar *style_name = NULL;
322 gchar *title = NULL;
323 gchar *command = NULL;
324 IrrecoCmdChainId chain_id;
325 gint x;
326 gint y;
328 IrrecoButton *button = NULL;
329 IrrecoButtonLayout *layout = NULL;
330 IrrecoThemeButton *style = NULL;
332 IrrecoConfigHardkeyId hardkeyid;
334 IRRECO_ENTER
336 hardkeyid.command_clash2 = 0;
338 /* Required fields. */
339 if (!irreco_keyfile_get_int(keyfile, "x", &x) ||
340 !irreco_keyfile_get_int(keyfile, "y", &y) ||
341 !irreco_keyfile_get_str(keyfile, "layout", &layout_name)) {
342 IRRECO_RETURN
344 IRRECO_PRINTF("Position: x%i y%i\n", x, y);
346 /* Find layout. */
347 if (!irreco_string_table_get(irreco_data->irreco_layout_array,
348 layout_name, (gpointer *) &layout)) {
349 IRRECO_ERROR("Button uses unknown layout \"%s\"\n",
350 layout_name);
351 g_free(layout_name);
352 IRRECO_RETURN
354 g_free(layout_name);
355 IRRECO_PRINTF("Style: \"%s\"\n",
356 irreco_button_layout_get_name(layout));
358 /* Find style. */
359 irreco_keyfile_get_str(keyfile, "style", &style_name);
360 if (style_name != NULL) {
361 if (irreco_theme_manager_get_button_style(
362 irreco_data->theme_manager,
363 style_name, &style)) {
364 IRRECO_PRINTF("Style: \"%s\"\n", style->name->str);
365 } else {
366 IRRECO_ERROR("Button uses unknown style \"%s\"\n",
367 style_name);
370 g_free(style_name);
373 /* Get title and command. */
374 irreco_keyfile_get_str(keyfile, "title", &title);
375 IRRECO_PRINTF("title: \"%s\"\n", title);
377 button = irreco_button_create(layout, x, y, title, style,
378 irreco_data->cmd_chain_manager);
380 if (irreco_keyfile_get_int(keyfile, "command-chain-id", &chain_id)) {
381 gboolean command_clash = FALSE;
382 IrrecoStringTable *ids_in_use = irreco_string_table_new(NULL,
383 NULL);
385 IRRECO_STRING_TABLE_FOREACH(irreco_data->irreco_layout_array, key,
386 IrrecoButtonLayout *, layout)
387 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array,
388 IrrecoButton *,
389 irreco_button)
390 gchar *id_as_gchar = g_malloc0(10);
391 g_sprintf(id_as_gchar, "%d\n", irreco_button->cmd_chain_id);
392 if(chain_id == irreco_button->cmd_chain_id) {
393 g_print("cid: %d\n", irreco_button->cmd_chain_id);
394 command_clash = TRUE;
396 irreco_string_table_add(ids_in_use,
397 id_as_gchar,
398 NULL);
399 g_free(id_as_gchar);
400 IRRECO_PTR_ARRAY_FORWARDS_END /* End of button loop */
402 /* Handle hardkey commandchain ids */
403 hardkeyid.ids_in_use = ids_in_use;
404 hardkeyid.command_clash = command_clash;
405 hardkeyid.chain_id = chain_id;
406 g_hash_table_foreach(layout->hardkey_map->table,
407 irreco_config_foreach_hardkey_id,
408 &hardkeyid);
410 IRRECO_STRING_TABLE_FOREACH_END /* End of layout loop */
412 #if ENABLE_DEBUGGING
413 g_print("button clashes %d, %d\n", command_clash, hardkeyid.command_clash2);
414 #endif
416 if(command_clash || hardkeyid.command_clash2 == 1) { /* commandchain id in use */
417 const gchar *key;
418 gint tmp;
419 gchar *id_as_gchar = g_malloc0(10);
420 gchar *new_id_as_gchar = g_malloc0(10);
422 g_sprintf(id_as_gchar, "%d", chain_id);
423 irreco_string_table_sort_123(ids_in_use);
424 irreco_string_table_index(ids_in_use,
425 irreco_string_table_lenght(ids_in_use)-1,
426 &key,
427 NULL);
428 tmp = atoi(key)+1;
429 g_sprintf(new_id_as_gchar, "%d", tmp);
430 irreco_button_set_cmd_chain_id(button, atoi(key)+1);
431 irreco_string_table_add(list, id_as_gchar, new_id_as_gchar);
432 IRRECO_DEBUG("Clashing button ID\n");
433 IRRECO_DEBUG("Trying to use ID: %s\n", id_as_gchar);
434 IRRECO_DEBUG("New assosiated ID %s\n", new_id_as_gchar);
435 g_free(id_as_gchar);
436 } else { /* commandchain id not in use */
437 irreco_button_set_cmd_chain_id(button, chain_id);
438 IRRECO_DEBUG("Uniq button ID: %d\n", chain_id);
441 #if ENABLE_DEBUGGING
442 IRRECO_PAUSE
443 #endif
444 g_free(title);
445 g_free(command);
446 IRRECO_RETURN
449 void irreco_config_read_hardkey_from_keyfile(IrrecoData * irreco_data,
450 IrrecoKeyFile * keyfile,
451 IrrecoStringTable *list)
453 IrrecoButtonLayout *layout = NULL;
454 gchar *layout_name = NULL;
455 IrrecoCmdChainId id;
456 guint keyval;
457 gchar *hardkey_str = NULL;
459 gboolean command_clash = FALSE;
460 IrrecoConfigHardkeyId hardkeyid;
461 IrrecoStringTable *ids_in_use = irreco_string_table_new(NULL, NULL);
463 IRRECO_ENTER
465 hardkeyid.command_clash2 = 0;
467 /* Required fields. */
468 if (!irreco_keyfile_get_str(keyfile, "layout", &layout_name) ||
469 !irreco_keyfile_get_int(keyfile, "chain-id", &id) ||
470 !irreco_keyfile_get_uint(keyfile, "key-value", &keyval)) {
471 g_free(layout_name);
472 IRRECO_RETURN
475 /* Find layout. */
476 if (!irreco_string_table_get(irreco_data->irreco_layout_array,
477 layout_name, (gpointer *) &layout)) {
478 IRRECO_ERROR("Hardkey uses unknown layout \"%s\"\n",
479 layout_name);
480 g_free(layout_name);
481 IRRECO_RETURN
483 g_free(layout_name);
485 /* Prevent use of clashing commandchain ids */
486 IRRECO_STRING_TABLE_FOREACH(irreco_data->irreco_layout_array, key,
487 IrrecoButtonLayout *, layout)
488 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array,
489 IrrecoButton *,
490 irreco_button)
491 gchar *id_as_gchar = g_malloc0(10);
492 g_sprintf(id_as_gchar, "%d\n", irreco_button->cmd_chain_id);
493 if(id == irreco_button->cmd_chain_id) {
494 g_print("cid: %d\n", irreco_button->cmd_chain_id);
495 command_clash = TRUE;
497 irreco_string_table_add(ids_in_use,
498 id_as_gchar,
499 NULL);
500 g_free(id_as_gchar);
501 IRRECO_PTR_ARRAY_FORWARDS_END /* End of button loop */
503 /* Handle hardkey commandchain ids */
504 hardkeyid.ids_in_use = ids_in_use;
505 hardkeyid.command_clash = command_clash;
506 hardkeyid.chain_id = id;
507 g_hash_table_foreach(layout->hardkey_map->table,
508 irreco_config_foreach_hardkey_id,
509 &hardkeyid);
511 IRRECO_STRING_TABLE_FOREACH_END /* End of layout loop */
513 #if ENABLE_DEBUGGING
514 g_print("hardkey clashes %d, %d\n", command_clash, hardkeyid.command_clash2);
515 #endif
517 if(command_clash || hardkeyid.command_clash2 == 1) { /* commandchain id in use */
518 const gchar *key;
519 gint tmp;
520 gchar *id_as_gchar = g_malloc0(10);
521 gchar *new_id_as_gchar = g_malloc0(10);
523 g_sprintf(id_as_gchar, "%d", id);
524 irreco_string_table_sort_123(ids_in_use);
525 irreco_string_table_index(ids_in_use,
526 irreco_string_table_lenght(ids_in_use)-1,
527 &key,
528 NULL);
529 tmp = atoi(key)+1;
530 id = tmp;
531 g_sprintf(new_id_as_gchar, "%d", tmp);
532 irreco_string_table_add(list, id_as_gchar, new_id_as_gchar);
533 IRRECO_DEBUG("Clashing hk ID\n");
534 IRRECO_DEBUG("Trying to use ID: %s\n", id_as_gchar);
535 IRRECO_DEBUG("New assosiated ID %s\n", new_id_as_gchar);
537 g_free(id_as_gchar);
538 } else { /* commandchain id not in use */
539 IRRECO_DEBUG("Uniq hk ID: %d\n", id);
542 #if ENABLE_DEBUGGING
543 IRRECO_PAUSE
544 #endif
547 hardkey_str = irreco_hardkey_to_str(keyval);
548 IRRECO_PRINTF("Associating layout \"%s\" hardkey \"%s\" with "
549 "command chain \"%i\".\n",
550 irreco_button_layout_get_name(layout),
551 hardkey_str, id);
552 g_free(hardkey_str);
554 irreco_hardkey_map_assosiate_chain_with_id(layout->hardkey_map,
555 keyval, id);
556 IRRECO_RETURN
559 /** @} */
563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
564 /* Layout saving. */
565 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
568 * @name Layout saving
569 * @{
572 typedef struct _IrrecoConfigCmdAndButton IrrecoConfigCmdAndButton;
573 struct _IrrecoConfigCmdAndButton {
574 IrrecoButton *button;
575 GKeyFile *keyfile;
577 typedef struct _IrrecoConfigSaveHardkeyData IrrecoConfigSaveHardkeyData;
578 struct _IrrecoConfigSaveHardkeyData {
579 GKeyFile *keyfile;
580 gint hardkey_index;
581 IrrecoButtonLayout *layout;
582 gint *hardkey_id;
586 * Save layout.
588 * Since GKeyFile does not allow two groups with the same name,
589 * layout_index and button_index variables are used to make sure that each
590 * button and layout group has unique name. The index is ignored when reading
591 * the layout config.
593 gboolean irreco_config_save_layouts(IrrecoData * irreco_data)
595 gint command_index = 1;
596 gint hardkey_id = 1;
597 GKeyFile *keyfile;
598 IrrecoStringTable *table;
599 gboolean success;
600 GList *list = NULL;
601 IrrecoConfigCmdAndButton kf_and_btn;
602 gchar *old_cmd_chain_conf_file;
604 IRRECO_ENTER
606 table = irreco_data->irreco_layout_array;
607 IRRECO_STRING_TABLE_FOREACH(table, key, IrrecoButtonLayout *, layout)
608 gchar *filename;
609 keyfile = g_key_file_new();
610 irreco_config_save_layout_to_keyfile(keyfile,
611 layout,
612 &command_index,
613 &hardkey_id);
615 filename = irreco_create_uniq_layout_filename(
616 layout->filename->str);
617 g_string_assign(layout->filename, filename);
619 list = g_list_prepend(list, g_strdup(filename));
621 IRRECO_DEBUG("Layout %s in file: %s\n",
622 layout->name->str,
623 layout->filename->str);
625 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array,
626 IrrecoButton *,
627 irreco_button)
628 kf_and_btn.button = irreco_button;
629 kf_and_btn.keyfile = keyfile;
630 g_hash_table_foreach(
631 irreco_data->cmd_chain_manager->table,
632 irreco_config_cmd_chain_save,
633 &kf_and_btn);
634 IRRECO_PTR_ARRAY_BACKWARDS_END
636 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
637 filename);
638 g_key_file_free(keyfile);
639 g_free(filename);
640 IRRECO_STRING_TABLE_FOREACH_END
642 /* Remove unused layouts afterwards */
643 irreco_remove_layouts_exept_glist(list);
644 g_list_free(list);
646 old_cmd_chain_conf_file = irreco_get_config_file("irreco",
647 "command-chains.conf");
649 /* Remove old command-chains.conf */
650 if(irreco_file_exists(old_cmd_chain_conf_file)) {
651 gchar *rm_cmd;
652 rm_cmd = g_strconcat("rm ", old_cmd_chain_conf_file, NULL);
653 system(rm_cmd);
654 g_free(rm_cmd);
657 g_free(old_cmd_chain_conf_file);
659 IRRECO_RETURN_BOOL(success);
662 /* Saves hardkey command to keyfile */
663 void irreco_config_save_hardkey_to_keyfile(IrrecoHardkeyMap *hardkey_map,
664 guint keyval,
665 IrrecoCmdChainId chain_id,
666 IrrecoCmdChain *chain,
667 gpointer user_data)
669 IrrecoConfigSaveHardkeyData *hardkey_data;
671 IRRECO_ENTER
673 hardkey_data = (IrrecoConfigSaveHardkeyData*) user_data;
675 /* Save command chain for matching hard key */
676 if(chain_id == *hardkey_data->hardkey_id) {
677 irreco_cmd_chain_to_config(chain, hardkey_data->keyfile);
680 IRRECO_RETURN
683 static void irreco_config_cmd_chain_save(gpointer key,
684 gpointer value,
685 gpointer user_data)
687 IrrecoConfigCmdAndButton *iccab_struct =
688 (IrrecoConfigCmdAndButton *) user_data;
689 GKeyFile *keyfile = iccab_struct->keyfile;
690 IrrecoButton *button = iccab_struct->button;
691 IrrecoCmdChain *chain = (IrrecoCmdChain *) value;
692 IrrecoCmdChainId id = (IrrecoCmdChainId) key;
693 IRRECO_ENTER
695 if(button->cmd_chain_id == id) {
696 irreco_cmd_chain_to_config(chain, keyfile);
699 IRRECO_RETURN
702 void irreco_config_save_layout_to_keyfile(GKeyFile * keyfile,
703 IrrecoButtonLayout * layout,
704 gint * command_index,
705 gint * hardkey_id)
707 GdkColor *color;
708 gint button_index = 1;
709 gchar group[IRRECO_CONFIG_GROUP_LEN];
710 IrrecoConfigSaveHardkeyData hardkey_data;
711 IRRECO_ENTER
713 /* Save layout. */
714 g_assert(irreco_button_layout_get_name(layout) != NULL);
715 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "layout");
716 irreco_gkeyfile_set_string(keyfile, group, "name",
717 irreco_button_layout_get_name(layout));
718 g_key_file_set_integer(keyfile, group, "bg-type",
719 irreco_button_layout_get_bg_type(layout));
720 irreco_gkeyfile_set_string(keyfile, group, "bg-image",
721 irreco_button_layout_get_bg_image(layout));
722 color = irreco_button_layout_get_bg_color(layout);
723 g_key_file_set_integer(keyfile, group, "bg-color-red", color->red);
724 g_key_file_set_integer(keyfile, group, "bg-color-green", color->green);
725 g_key_file_set_integer(keyfile, group, "bg-color-blue", color->blue);
727 /* Save buttons. */
728 irreco_button_layout_reindex(layout);
729 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array, IrrecoButton *, button)
730 irreco_config_save_button_to_keyfile(keyfile,
731 button,
732 button_index,
733 command_index);
734 button_index = button_index + 1;
735 IRRECO_PTR_ARRAY_FORWARDS_END
737 /* Save Hardkeys. */
738 hardkey_data.keyfile = keyfile;
739 hardkey_data.hardkey_index = 1;
740 hardkey_data.layout = layout;
741 hardkey_data.hardkey_id = hardkey_id;
742 irreco_hardkey_map_chain_foreach(layout->hardkey_map,
743 irreco_config_save_hardkey_to_file,
744 &hardkey_data);
745 IRRECO_RETURN
748 void irreco_config_save_hardkey_to_file(IrrecoHardkeyMap *hardkey_map,
749 guint keyval,
750 IrrecoCmdChainId chain_id,
751 IrrecoCmdChain *chain,
752 gpointer user_data)
754 gchar group[IRRECO_CONFIG_GROUP_LEN];
755 IrrecoConfigSaveHardkeyData *hardkey_data;
757 IRRECO_ENTER
759 hardkey_data = (IrrecoConfigSaveHardkeyData*) user_data;
761 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "hardkey-%i",
762 hardkey_data->hardkey_index);
763 irreco_gkeyfile_set_string(hardkey_data->keyfile, group, "layout",
764 irreco_button_layout_get_name(hardkey_data->layout));
765 g_key_file_set_integer(hardkey_data->keyfile, group,
766 "chain-id", chain_id);
767 irreco_gkeyfile_set_guint(hardkey_data->keyfile, group,
768 "key-value", keyval);
770 *hardkey_data->hardkey_id = chain_id;
772 irreco_hardkey_map_chain_foreach(hardkey_data->layout->hardkey_map,
773 irreco_config_save_hardkey_to_keyfile,
774 hardkey_data);
776 hardkey_data->hardkey_index = hardkey_data->hardkey_index + 1;
778 IRRECO_RETURN
781 void irreco_config_save_button_to_keyfile(GKeyFile * keyfile,
782 IrrecoButton * button,
783 gint button_index,
784 gint * command_index)
786 gchar group[IRRECO_CONFIG_GROUP_LEN];
787 IRRECO_ENTER
789 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "button-%i", button_index);
790 irreco_gkeyfile_set_string(keyfile, group, "layout",
791 irreco_button_layout_get_name(button->irreco_layout));
792 irreco_gkeyfile_set_string(keyfile, group, "title", button->title);
793 g_key_file_set_integer(keyfile, group, "index", button->index);
794 g_key_file_set_integer(keyfile, group, "command-chain-id",
795 button->cmd_chain_id);
796 g_key_file_set_integer(keyfile, group, "x", button->x);
797 g_key_file_set_integer(keyfile, group, "y", button->y);
799 /* It is valid for a button to have NULL style. */
800 if (button->style != NULL) {
801 irreco_gkeyfile_set_string(keyfile, group, "style",
802 button->style->style_name->str);
805 IRRECO_RETURN
808 /** @} */
812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
813 /* Save / Read active layout. */
814 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
817 * @name Save / Read active layout
818 * @{
821 gboolean irreco_config_save_active_layout(IrrecoButtonLayout * irreco_layout)
823 GKeyFile *keyfile;
824 gboolean success;
825 IRRECO_ENTER
827 keyfile = g_key_file_new();
828 if (irreco_layout != NULL) {
829 irreco_gkeyfile_set_string(keyfile, "active-layout", "name",
830 irreco_button_layout_get_name(irreco_layout));
832 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
833 irreco_config_active_layout_file);
834 g_key_file_free(keyfile);
835 IRRECO_RETURN_BOOL(success);
838 IrrecoButtonLayout *irreco_config_read_active_layout(IrrecoData * irreco_data)
840 IrrecoKeyFile *keyfile = NULL;
841 gchar *config_dir = NULL;
842 gchar *config_file = NULL;
843 gchar *name = NULL;
844 IrrecoButtonLayout *irreco_layout = NULL;
845 IRRECO_ENTER
847 /* Attempt to read layout name, and find layout with the same name. */
848 config_dir = irreco_get_config_dir("irreco");
849 config_file = irreco_get_config_file("irreco",
850 irreco_config_active_layout_file);
851 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
852 if (config_dir != NULL && config_file != NULL && keyfile != NULL
853 && irreco_keyfile_set_group(keyfile, "active-layout")
854 && irreco_keyfile_get_str(keyfile, "name", &name)) {
856 IRRECO_DEBUG("Read active layout name \"%s\" from \"%s\".\n",
857 name, irreco_config_active_layout_file);
859 if (irreco_string_table_get(irreco_data->irreco_layout_array,
860 name, (gpointer *) &irreco_layout)){
861 IRRECO_DEBUG("Found matching layout.\n");
862 } else {
863 IRRECO_DEBUG("No matching layout found.\n");
867 irreco_keyfile_destroy(keyfile);
868 g_free(name);
869 g_free(config_dir);
870 g_free(config_file);
872 /* If we could not find correct active layout,
873 attempt to get some layout.*/
874 if (irreco_layout == NULL) {
875 irreco_string_table_index(irreco_data->irreco_layout_array, 0,
876 NULL, (gpointer *) &irreco_layout);
878 IRRECO_RETURN_PTR(irreco_layout);
881 /** @} */
885 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
886 /* Save / Read backend configuration. */
887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
890 * @name Save / Read backend configuration
891 * @{
894 gboolean irreco_config_save_backends(IrrecoBackendManager * backend_manager)
896 gint i = 0;
897 GKeyFile *keyfile;
898 gboolean success;
899 gchar group[IRRECO_CONFIG_GROUP_LEN];
900 IRRECO_ENTER
902 keyfile = g_key_file_new();
903 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(backend_manager, instance)
904 g_snprintf(group, IRRECO_CONFIG_GROUP_LEN, "instance-%i", ++i);
905 irreco_gkeyfile_set_string(keyfile, group, "library",
906 instance->lib->filename);
907 irreco_gkeyfile_set_string(keyfile, group, "config",
908 instance->config);
909 irreco_gkeyfile_set_string(keyfile, group, "name",
910 irreco_backend_instance_get_name(instance));
911 IRRECO_BACKEND_MANAGER_FOREACH_END
913 success = irreco_gkeyfile_write_to_config_file(keyfile, "irreco",
914 irreco_config_backend_file);
915 g_key_file_free(keyfile);
916 IRRECO_RETURN_BOOL(success);
919 gboolean irreco_config_read_backends(IrrecoBackendManager * manager)
921 guint i;
922 IrrecoKeyFile *keyfile = NULL;
923 gchar *config_dir = NULL;
924 gchar *config_file = NULL;
925 gchar** groups = NULL;
926 gsize group_count = 0;
927 IRRECO_ENTER
929 config_dir = irreco_get_config_dir("irreco");
930 config_file = irreco_get_config_file("irreco",
931 irreco_config_backend_file);
932 keyfile = irreco_keyfile_create(config_dir, config_file, NULL);
933 if (config_dir == NULL || config_file == NULL || keyfile == NULL) {
934 g_free(config_dir);
935 g_free(config_file);
936 irreco_keyfile_destroy(keyfile);
937 IRRECO_RETURN_BOOL(FALSE);
940 IRRECO_PRINTF("Reading backend configuration file \"%s\"\n",
941 config_file);
942 groups = g_key_file_get_groups(keyfile->keyfile, &group_count);
944 /* Read instances. */
945 for (i = 0; i < group_count; i++) {
946 gchar *group = groups[i];
947 if (g_str_has_prefix(group, "instance")) {
948 IRRECO_PRINTF("Reading instance group \"%s\"\n", group);
949 irreco_keyfile_set_group(keyfile, group);
950 irreco_config_read_backend_from_keyfile(manager,
951 keyfile);
955 g_strfreev(groups);
956 irreco_keyfile_destroy(keyfile);
957 g_free(config_dir);
958 g_free(config_file);
959 IRRECO_RETURN_BOOL(TRUE);
962 void irreco_config_read_backend_from_keyfile(IrrecoBackendManager * manager,
963 IrrecoKeyFile * keyfile)
965 gchar *library = NULL;
966 gchar *config = NULL;
967 gchar *name = NULL;
968 IrrecoBackendLib *lib;
969 IRRECO_ENTER
971 /* Read variables. */
972 if (!irreco_keyfile_get_str(keyfile, "library", &library) ||
973 !irreco_keyfile_get_str(keyfile, "config", &config) ||
974 !irreco_keyfile_get_str(keyfile, "name", &name)) {
975 g_free(library);
976 g_free(config);
977 g_free(name);
978 IRRECO_RETURN
981 /* Find library. */
982 if (!irreco_backend_manager_find_lib(manager, library, &lib)) {
983 IRRECO_ERROR("Cannot find backend library \"%s\"\n", library);
984 g_free(library);
985 g_free(config);
986 g_free(name);
987 IRRECO_RETURN
989 g_free(library);
991 /* Create instance. */
992 irreco_backend_manager_create_instance(manager, lib, name, config);
993 g_free(name);
994 g_free(config);
996 IRRECO_RETURN
1000 /** @} */
1003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1004 /* Misc layout functions */
1005 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
1008 * @name Misc layout functions
1009 * @{
1013 * Get list of themes used by layout
1015 * @param data IrrecoData
1016 * @param layoutname name of layout
1017 * @param list StringTable that'll contain theme names (key) and versions (data)
1018 * @returns TRUE in case of success, FALSE otherwise
1020 gboolean irreco_layout_get_themes(IrrecoData *data,
1021 gchar *layoutname,
1022 IrrecoStringTable **list)
1024 IrrecoStringTable *themelist = NULL;
1025 gchar *bgpath = NULL;
1027 IRRECO_ENTER
1029 /* List of theme names used by layout, stored as keys */
1030 *list = irreco_string_table_new(NULL, NULL);
1031 /* List of all themes */
1032 themelist = irreco_theme_manager_get_themes(data->theme_manager);
1034 if(irreco_string_table_lenght(data->irreco_layout_array) == 0) {
1035 IRRECO_RETURN_BOOL(FALSE);
1038 /* Loop through layout buttons and store used themes to list */
1039 IRRECO_STRING_TABLE_FOREACH(data->irreco_layout_array,
1040 key,
1041 IrrecoButtonLayout *,
1042 layout)
1043 /* Skip layouts with wrong name */
1044 if(g_str_equal(layoutname, layout->name->str)) {
1045 if(layout->background_type == 2) {
1046 bgpath = g_strdup(layout->background_image->str);
1048 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array,
1049 IrrecoButton *,
1050 irreco_button)
1051 /* Block buttons without theme */
1052 if(irreco_button->style != NULL) {
1053 gboolean match = FALSE;
1054 IRRECO_STRING_TABLE_FOREACH_KEY(*list, themename)
1055 if(g_str_equal(
1056 irreco_button->style->theme_name->str,
1057 themename)) {
1058 match = TRUE;
1060 IRRECO_STRING_TABLE_FOREACH_END
1061 if(!match) {
1062 irreco_string_table_add(*list,
1063 irreco_button->style->theme_name->str,
1064 NULL);
1067 IRRECO_PTR_ARRAY_BACKWARDS_END
1069 IRRECO_STRING_TABLE_FOREACH_END
1071 /* Loop through themes and get versions of wanted themes */
1072 IRRECO_STRING_TABLE_FOREACH(themelist, key, IrrecoTheme*, theme)
1073 IRRECO_STRING_TABLE_FOREACH(theme->backgrounds,
1074 bgkey,
1075 IrrecoThemeBg*,
1076 bgtheme)
1077 if(bgpath != NULL)
1078 if(g_str_equal(bgtheme->image_path->str, bgpath)) {
1079 gboolean match = FALSE;
1080 /* Matching theme found for bg */
1081 IRRECO_STRING_TABLE_FOREACH_KEY(*list, themename)
1082 if(g_str_equal(theme->name->str,
1083 themename)) {
1084 match = TRUE;
1086 IRRECO_STRING_TABLE_FOREACH_END
1087 if(!match) {
1088 irreco_string_table_add(*list,
1089 theme->name->str,
1090 NULL);
1093 IRRECO_STRING_TABLE_FOREACH_END
1094 IRRECO_STRING_TABLE_FOREACH_KEY(*list, themename)
1095 if(g_str_equal(themename, theme->name->str)) {
1096 irreco_string_table_change_data(*list, themename, theme->version->str);
1098 IRRECO_STRING_TABLE_FOREACH_END
1099 IRRECO_STRING_TABLE_FOREACH_END
1101 g_free(bgpath);
1103 IRRECO_RETURN_BOOL(TRUE);
1106 typedef struct _IrrecoConfigHardkeyInstance IrrecoConfigHardkeyInstance;
1107 struct _IrrecoConfigHardkeyInstance {
1108 IrrecoStringTable *list;
1109 IrrecoData *data;
1112 /* Private func for irreco_layout_get_backends that handles hardkeys */
1113 static void irreco_layout_get_backends_of_hardkeys(gpointer key,
1114 gpointer value,
1115 gpointer user_data)
1117 IrrecoConfigHardkeyInstance *data;
1118 IrrecoCmdChain* cmd_chain;
1120 IRRECO_ENTER
1122 data = (IrrecoConfigHardkeyInstance *) user_data;
1124 /* Get commandchain */
1125 cmd_chain = irreco_cmd_chain_manager_get_chain(
1126 data->data->cmd_chain_manager,
1127 (gint)value);
1128 /* Loop through commandchain */
1129 IRRECO_CMD_CHAIN_FOREACH(cmd_chain, cmd)
1130 gboolean match = FALSE;
1131 if(cmd->type == IRRECO_COMMAND_BACKEND) {
1132 /* Check list doesn't already contain backend name */
1133 IRRECO_STRING_TABLE_FOREACH_KEY(data->list, device_name)
1134 if(g_str_equal(cmd->backend.device_name,
1135 device_name)) {
1136 match = TRUE;
1138 IRRECO_STRING_TABLE_FOREACH_END
1139 /* Add backend instance name to list */
1140 if(!match) {
1141 irreco_string_table_add(data->list,
1142 cmd->backend.device_name,
1143 cmd->backend.instance);
1146 IRRECO_CMD_CHAIN_FOREACH_END
1148 IRRECO_RETURN
1152 * Get list of backends used by layout
1154 * @param data IrrecoData
1155 * @param layoutname gchar name of layout
1156 * @param list StringTable that'll contain backend names as key
1157 * @returns TRUE in case of success, FALSE otherwise
1158 * TODO When changing to less insane indenting style, fix indentation
1160 gboolean irreco_layout_get_backends(IrrecoData *data,
1161 gchar *layoutname,
1162 IrrecoStringTable **list)
1164 IrrecoCmdChain* cmd_chain;
1165 IrrecoConfigHardkeyInstance user_data;
1167 IRRECO_ENTER
1169 *list = irreco_string_table_new(NULL, NULL);
1171 user_data.list = *list;
1172 user_data.data = data;
1174 /* Loop through layouts */
1175 IRRECO_STRING_TABLE_FOREACH(data->irreco_layout_array, key,
1176 IrrecoButtonLayout *, layout)
1177 if(g_str_equal(layout->name->str, layoutname)) {
1178 /* Loop through buttons */
1179 IRRECO_PTR_ARRAY_FORWARDS(layout->button_array,
1180 IrrecoButton *,
1181 irreco_button)
1182 /* Get commandchain */
1183 cmd_chain = irreco_cmd_chain_manager_get_chain(
1184 data->cmd_chain_manager,
1185 irreco_button->cmd_chain_id);
1186 /* Loop through commandchain */
1187 IRRECO_CMD_CHAIN_FOREACH(cmd_chain, cmd)
1188 gboolean match = FALSE;
1189 if(cmd->type == IRRECO_COMMAND_BACKEND) {
1190 IRRECO_DEBUG("%s\n",cmd->backend.device_name);
1191 /* Check list doesn't already contain backend name */
1192 IRRECO_STRING_TABLE_FOREACH_KEY(*list, device_name)
1193 if(g_str_equal(cmd->backend.device_name,
1194 device_name)) {
1195 match = TRUE;
1197 IRRECO_STRING_TABLE_FOREACH_END
1198 /* Add backend instance name to list */
1199 if(!match) {
1200 irreco_string_table_add(*list,
1201 cmd->backend.device_name,
1202 cmd->backend.instance);
1205 IRRECO_CMD_CHAIN_FOREACH_END /* End of commandchain loop */
1206 IRRECO_PTR_ARRAY_FORWARDS_END /* End of button loop */
1208 /* Get cmd_chain_id's from hardkeys */
1209 g_hash_table_foreach(layout->hardkey_map->table,
1210 irreco_layout_get_backends_of_hardkeys,
1211 &user_data);
1214 IRRECO_STRING_TABLE_FOREACH_END /* End of layout loop */
1216 IRRECO_RETURN_BOOL(TRUE);
1219 /** @} */
1220 /** @} */