2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_cmd_chain_manager.h"
21 #include "irreco_config.h"
24 * @addtogroup IrrecoCmdChainManager
27 * A class for storing IrrecoCmdChains assosiated with buttons and hardkeys.
29 * - Stores an array of IrrecoCmdChains
30 * - Can save command chains to file.
31 * - Can read command chains from file.
38 * Source file of @ref IrrecoCmdChainManager.
43 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 typedef struct _IrrecoChainFindData IrrecoChainFindData
;
48 struct _IrrecoChainFindData
{
53 static gboolean
irreco_cmd_chain_manager_free_foreach(gpointer key
,
56 static gboolean
irreco_cmd_chain_manager_find_chain_foreach(gpointer key
,
59 static void irreco_cmd_chain_manager_to_config_foreach(gpointer key
,
65 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
66 /* Construction & Destruction */
67 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
70 * @name Construction & Destruction
74 IrrecoCmdChainManager
*irreco_cmd_chain_manager_new()
76 IrrecoCmdChainManager
*self
;
79 self
= g_slice_new0(IrrecoCmdChainManager
);
80 self
->table
= g_hash_table_new(NULL
, NULL
);
81 IRRECO_RETURN_PTR(self
);
84 void irreco_cmd_chain_manager_free(IrrecoCmdChainManager
*self
)
87 if (g_hash_table_size(self
->table
)) {
88 IRRECO_DEBUG("Hashtable is not empty. Something does not "
89 "properly free IrrecoCmdChains.\n");
92 g_hash_table_foreach_remove(self
->table
,
93 irreco_cmd_chain_manager_free_foreach
,
95 g_hash_table_destroy(self
->table
);
96 g_slice_free(IrrecoCmdChainManager
, self
);
99 static gboolean
irreco_cmd_chain_manager_free_foreach(gpointer key
,
103 IRRECO_PRINTF("Destroying command chain with id \"%i\".\n",
104 (IrrecoCmdChainId
) key
);
105 irreco_cmd_chain_destroy((IrrecoCmdChain
*) value
);
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
114 /* Private Functions */
115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
118 * @name Private Functions
122 static IrrecoCmdChainId
123 irreco_cmd_chain_manager_find_empty_index(IrrecoCmdChainManager
*self
)
125 IrrecoCmdChainId i
= 1;
128 while (g_hash_table_lookup(self
->table
, (gconstpointer
) i
)) i
++;
129 IRRECO_RETURN_INT(i
);
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
135 /* Public Functions */
136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
139 * @name Public Functions
144 * Create a new IrrecoCmdChain and assign an id for it.
146 IrrecoCmdChainId
irreco_cmd_chain_manager_new_chain(IrrecoCmdChainManager
*self
)
149 IrrecoCmdChain
*chain
;
152 id
= irreco_cmd_chain_manager_find_empty_index(self
);
153 chain
= irreco_cmd_chain_create();
154 irreco_cmd_chain_set_id(chain
, id
);
155 g_hash_table_insert(self
->table
, (gpointer
) id
, chain
);
156 IRRECO_RETURN_INT(id
);
160 * Create a new command chain and assosiate it with the given id, if it does
161 * not already exists.
163 * @return TRUE if created, FALSE if already exists.
165 gboolean
irreco_cmd_chain_manager_new_chain_with_id(IrrecoCmdChainManager
*self
,
168 IrrecoCmdChain
*chain
;
171 if (g_hash_table_lookup(self
->table
, (gpointer
) id
)) {
172 IRRECO_DEBUG("Comman chain with id \"%i\" "
173 "already exists.\n", id
);
174 IRRECO_RETURN_BOOL(FALSE
);
177 chain
= irreco_cmd_chain_create();
178 irreco_cmd_chain_set_id(chain
, id
);
179 g_hash_table_insert(self
->table
, (gpointer
) id
, chain
);
180 IRRECO_RETURN_BOOL(TRUE
);
183 void irreco_cmd_chain_manager_free_chain(IrrecoCmdChainManager
*self
,
187 g_hash_table_remove(self
->table
, (gpointer
) id
);
194 * Returns: IrrecoCmdChain pointer or NULL.
196 IrrecoCmdChain
*irreco_cmd_chain_manager_get_chain(IrrecoCmdChainManager
*self
,
200 IRRECO_RETURN_PTR(g_hash_table_lookup(self
->table
, (gpointer
) id
));
204 * Find IrrecoCmdChainId that corresponds to IrrecoCmdChain pointer.
206 IrrecoCmdChainId
irreco_cmd_chain_manager_find_chain(IrrecoCmdChainManager
*self
,
207 IrrecoCmdChain
*chain
)
209 IrrecoChainFindData find_data
;
212 if (g_hash_table_find(self
->table
,
213 irreco_cmd_chain_manager_find_chain_foreach
,
215 IRRECO_RETURN_INT((IrrecoCmdChainId
) find_data
.key
);
217 IRRECO_RETURN_INT(0);
219 static gboolean
irreco_cmd_chain_manager_find_chain_foreach(gpointer key
,
223 IrrecoChainFindData
*find_data
= (IrrecoChainFindData
*) user_data
;
224 if (find_data
->value
!= value
) return FALSE
;
225 find_data
->key
= key
;
230 * Save command chains to disk.
232 gboolean
irreco_cmd_chain_manager_to_config(IrrecoCmdChainManager
*self
)
238 keyfile
= g_key_file_new();
239 g_hash_table_foreach(self
->table
,
240 irreco_cmd_chain_manager_to_config_foreach
,
242 success
= irreco_gkeyfile_write_to_config_file(
243 keyfile
, "irreco", irreco_config_cmd_chain_file
);
244 g_key_file_free(keyfile
);
245 IRRECO_RETURN_BOOL(success
);
247 static void irreco_cmd_chain_manager_to_config_foreach(gpointer key
,
251 GKeyFile
*keyfile
= (GKeyFile
*) user_data
;
252 IrrecoCmdChain
*chain
= (IrrecoCmdChain
*) value
;
253 IrrecoCmdChainId id
= (IrrecoCmdChainId
) key
;
256 irreco_cmd_chain_set_id(chain
, id
);
257 irreco_cmd_chain_to_config(chain
, keyfile
);
262 * Read command chains from disk.
264 gboolean
irreco_cmd_chain_manager_from_config(IrrecoData
*irreco_data
)
266 IrrecoCmdChainManager
*self
= irreco_data
->cmd_chain_manager
;
268 IrrecoKeyFile
*keyfile
= NULL
;
269 gchar
*config_dir
= NULL
;
270 gchar
*config_file
= NULL
;
271 gchar
** groups
= NULL
;
272 gsize group_count
= 0;
275 /* Read config file into IrrecoKeyFile. */
276 config_dir
= irreco_get_config_dir("irreco");
277 config_file
= irreco_get_config_file(
278 "irreco", irreco_config_cmd_chain_file
);
279 keyfile
= irreco_keyfile_create(config_dir
, config_file
, NULL
);
280 if (config_dir
== NULL
|| config_file
== NULL
|| keyfile
== NULL
) {
283 irreco_keyfile_destroy(keyfile
);
284 IRRECO_RETURN_BOOL(FALSE
);
287 /* Get list of groups from. */
288 IRRECO_PRINTF("Reading layout configuration file \"%s\"\n",
290 groups
= g_key_file_get_groups(keyfile
->keyfile
, &group_count
);
293 for (i
= 0; i
< group_count
; i
++) {
294 const gchar
*group
= groups
[i
];
295 IrrecoCmdChain
*chain
= NULL
;
296 IrrecoCmdChain
*id_chain
= NULL
;
298 /* Read only command chain groups. */
299 if (!g_str_has_prefix(group
, "chain-") ||
300 g_strrstr(group
, ":") != NULL
) continue;
302 /* Read command chain from keyfile. */
303 irreco_keyfile_set_group(keyfile
, group
);
304 chain
= irreco_cmd_chain_new_from_config(keyfile
, irreco_data
);
307 * Copy chain into ID-mapped chain.
308 * @todo Rework this so that there is no need to copy chains.
310 irreco_cmd_chain_manager_new_chain_with_id(
311 self
, irreco_cmd_chain_get_id(chain
));
312 id_chain
= irreco_cmd_chain_manager_get_chain(
313 self
, irreco_cmd_chain_get_id(chain
));
314 irreco_cmd_chain_copy(chain
, id_chain
);
315 irreco_cmd_chain_free(chain
);
319 irreco_keyfile_destroy(keyfile
);
322 IRRECO_RETURN_BOOL(TRUE
);