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_backend_manager.h"
21 #include "irreco_config.h"
24 * @addtogroup IrrecoBackendManager
27 * Maintains tables of backend libraries and backend instances.
34 * Source file of @ref IrrecoBackendManager.
38 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
43 irreco_backend_manager_open_lib_dir_foreach(IrrecoDirForeachData
* dir_data
);
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
48 /* Construction & Destruction. */
49 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 * @name Construction & Destruction
57 IrrecoBackendManager
* irreco_backend_manager_create(IrrecoData
*irreco_data
)
59 IrrecoBackendManager
* manager
;
62 manager
= g_slice_new0(IrrecoBackendManager
);
63 manager
->irreco_data
= irreco_data
;
64 manager
->lib_table
= irreco_string_table_new(
65 G_DESTROYNOTIFY(irreco_backend_lib_close
), NULL
);
66 manager
->instance_table
= irreco_string_table_new(
67 G_DESTROYNOTIFY(irreco_backend_instance_destroy
),
68 IRRECO_KEY_SET_NOTIFY(irreco_backend_instance_set_name
));
69 manager
->config_map
= irreco_string_table_new(NULL
,
70 IRRECO_KEY_SET_NOTIFY(irreco_backend_instance_set_config
));
71 IRRECO_RETURN_PTR(manager
);
74 void irreco_backend_manager_destroy(IrrecoBackendManager
* manager
)
77 if (manager
== NULL
) IRRECO_RETURN
78 irreco_string_table_free(manager
->config_map
);
79 irreco_string_table_free(manager
->instance_table
);
80 irreco_string_table_free(manager
->lib_table
);
81 g_slice_free(IrrecoBackendManager
, manager
);
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
92 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
99 void irreco_backend_manager_get_devcmd_lists(IrrecoBackendManager
* manager
)
102 g_assert(manager
!= NULL
);
104 IRRECO_PRINTF("Getting device / command lists.\n");
105 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(manager
, instance
)
106 irreco_backend_instance_get_devcmd_list(instance
);
107 IRRECO_BACKEND_MANAGER_FOREACH_END
112 void irreco_backend_manager_read_from_confs(IrrecoBackendManager
* manager
)
115 g_assert(manager
!= NULL
);
117 IRRECO_PRINTF("Reading instace configurations.\n");
118 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(manager
, instance
)
119 irreco_backend_instance_read_from_conf(instance
);
120 IRRECO_BACKEND_MANAGER_FOREACH_END
125 void irreco_backend_manager_print(IrrecoBackendManager
* manager
)
129 g_assert(manager
!= NULL
);
132 IRRECO_PRINTF("Backend libraries:\n");
133 IRRECO_BACKEND_MANAGER_FOREACH_LIB(manager
, lib
)
134 IRRECO_PRINTF(" %i. \"%s\" \"%s\"\n", i
++,
135 lib
->filename
, lib
->name
);
136 IRRECO_BACKEND_MANAGER_FOREACH_END
139 IRRECO_PRINTF("Backend instances:\n");
140 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(manager
, instance
)
141 IRRECO_PRINTF(" %i. \"%s\" \"%s\" \"%s\"\n", i
++,
142 instance
->lib
->name
, instance
->name
,
144 IRRECO_BACKEND_MANAGER_FOREACH_END
153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
154 /* Library management. */
155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
158 * @name Library management
163 * Load backend from file.
165 * @param filepath Complete path to library.
166 * @return Pointer to new IrrecoBackendLib, or NULL on failure.
169 irreco_backend_manager_load_lib(IrrecoBackendManager
* manager
,
170 const gchar
* filepath
)
173 IrrecoBackendLib
*backend_lib
;
175 g_assert(manager
!= NULL
);
176 g_assert(filepath
!= NULL
);
178 filename
= g_path_get_basename(filepath
);
179 backend_lib
= irreco_backend_manager_load_with_name(
180 manager
, filepath
, filename
);
182 IRRECO_RETURN_PTR(backend_lib
);
186 * Load backend from file.
188 * @param filepath Complete path to library.
189 * @param filename Basename of the library.
190 * @return Pointer to new IrrecoBackendLib, or NULL on failure.
193 irreco_backend_manager_load_with_name(IrrecoBackendManager
* manager
,
194 const gchar
* filepath
,
195 const gchar
* filename
)
197 IrrecoBackendLib
*backend_lib
;
199 g_assert(manager
!= NULL
);
200 g_assert(filepath
!= NULL
);
201 g_assert(filename
!= NULL
);
203 if (irreco_string_table_exists(manager
->lib_table
, filename
)) {
204 IRRECO_ERROR("Backend \"%s\" has already been loaded.",
206 IRRECO_RETURN_PTR(NULL
);
209 backend_lib
= irreco_backend_lib_load_with_name(filepath
, filename
);
210 if (backend_lib
!= NULL
) {
211 irreco_string_table_add(manager
->lib_table
,
212 backend_lib
->filename
,
214 irreco_string_table_sort_abc(manager
->lib_table
);
216 IRRECO_RETURN_PTR(backend_lib
);
220 * Load all backends from directory.
223 irreco_backend_manager_load_lib_dir(IrrecoBackendManager
* manager
,
226 IrrecoDirForeachData dir_data
;
228 g_assert(manager
!= NULL
);
229 g_assert(directory
!= NULL
);
231 dir_data
.directory
= directory
;
232 dir_data
.filesuffix
= ".la";
233 dir_data
.user_data_1
= manager
;
235 IRRECO_RETURN_BOOL(irreco_dir_foreach(
236 &dir_data
, irreco_backend_manager_open_lib_dir_foreach
));
239 irreco_backend_manager_open_lib_dir_foreach(IrrecoDirForeachData
* dir_data
)
241 IrrecoBackendManager
*manager
;
244 manager
= (IrrecoBackendManager
*) dir_data
->user_data_1
;
245 irreco_backend_manager_load_with_name(manager
,
253 * Find library by filename.
255 * Returns: TRUE on success, FALSE otherwise.
257 gboolean
irreco_backend_manager_find_lib(IrrecoBackendManager
* manager
,
258 const gchar
* filename
,
259 IrrecoBackendLib
** lib
)
262 g_assert(manager
!= NULL
);
263 g_assert(filename
!= NULL
);
264 g_assert(lib
!= NULL
);
266 if (irreco_string_table_get(manager
->lib_table
, filename
,
268 IRRECO_RETURN_BOOL(TRUE
);
270 IRRECO_RETURN_BOOL(FALSE
);
277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
278 /* Instance management. */
279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
282 * @name Instance management
288 * Create new IrrecoBackendInstance and add it to the instance_table.
290 * @param name Name of instace. Or NULL for autogeneration.
291 * @param config Config file of instace. Or NULL for autogeneration.
292 * @return New IrrecoBackendInstance, or NULL on failure.
294 IrrecoBackendInstance
*
295 irreco_backend_manager_create_instance(IrrecoBackendManager
* manager
,
296 IrrecoBackendLib
* lib
,
298 const gchar
* config
)
300 IrrecoBackendInstance
*instance
;
302 g_assert(manager
!= NULL
);
303 g_assert(lib
!= NULL
);
305 /* Create instance. */
306 instance
= irreco_backend_instance_create(lib
, manager
->irreco_data
);
307 if (instance
== NULL
) IRRECO_RETURN_PTR(NULL
);
309 /* Set instance name. */
311 if (irreco_backend_manager_set_instance_name(
312 manager
, instance
, name
) == FALSE
) {
313 IRRECO_ERROR("Could not set instace name to \"%s\"",
315 irreco_backend_instance_destroy(instance
);
316 IRRECO_RETURN_PTR(NULL
);
319 irreco_backend_manager_assign_instance_name(manager
, instance
);
322 /* Set instance config. */
323 if (config
!= NULL
) {
324 if (irreco_backend_manager_set_instance_config(
325 manager
, instance
, config
) == FALSE
) {
326 IRRECO_ERROR("Could not set instace config to \"%s\"",
328 irreco_backend_instance_destroy(instance
);
329 IRRECO_RETURN_PTR(NULL
);
332 irreco_backend_manager_assign_instance_config(manager
, instance
);
335 IRRECO_RETURN_PTR(instance
);
339 * Destroy IrrecoBackendInstance and remove it from the instance_table.
341 * @return TRUE on success, FALSE otherwise.
344 irreco_backend_manager_destroy_instance(IrrecoBackendManager
* manager
,
345 IrrecoBackendInstance
* instance
)
350 g_assert(manager
!= NULL
);
351 g_assert(instance
!= NULL
);
353 if (irreco_string_table_steal_by_data(
354 manager
->instance_table
, instance
) == FALSE
) {
355 IRRECO_RETURN_BOOL(FALSE
);
358 config_path
= irreco_get_config_file("irreco", instance
->config
);
359 irreco_string_table_remove(manager
->config_map
, instance
->config
);
360 irreco_backend_instance_destroy_full(instance
, TRUE
);
362 IRRECO_PRINTF("Deleting \"%s\".\n", config_path
);
363 g_unlink(config_path
);
366 IRRECO_RETURN_BOOL(TRUE
);
370 * Find instance by name.
372 * @return TRUE on success, FALSE otherwise.
374 gboolean
irreco_backend_manager_find_instance(
375 IrrecoBackendManager
* manager
,
377 IrrecoBackendInstance
** instance
)
380 g_assert(manager
!= NULL
);
381 g_assert(name
!= NULL
);
382 g_assert(instance
!= NULL
);
384 if (irreco_string_table_get(manager
->instance_table
, name
,
385 (gpointer
*) instance
)) {
386 IRRECO_RETURN_BOOL(TRUE
);
388 IRRECO_RETURN_BOOL(FALSE
);
392 * Set name of the instance.
394 * @return TRUE on success, FALSE otherwise.
397 irreco_backend_manager_set_instance_name(IrrecoBackendManager
* manager
,
398 IrrecoBackendInstance
* instance
,
402 g_assert(manager
!= NULL
);
403 g_assert(instance
!= NULL
);
404 g_assert(name
!= NULL
);
406 if (irreco_string_table_exists(manager
->instance_table
, name
)) {
407 IRRECO_RETURN_BOOL(FALSE
);
410 /* Add instace to the table if it has not been added. */
411 if (instance
->name
== NULL
|| irreco_string_table_exists(
412 manager
->instance_table
, instance
->name
) == FALSE
) {
413 irreco_string_table_add(manager
->instance_table
,
417 /* Else we can just change the key. */
419 irreco_string_table_change_key(manager
->instance_table
,
423 irreco_string_table_sort_abc(manager
->instance_table
);
424 IRRECO_RETURN_BOOL(TRUE
);
428 * Assingn a unique name to the instance.
431 irreco_backend_manager_assign_instance_name(IrrecoBackendManager
* manager
,
432 IrrecoBackendInstance
* instance
)
438 g_assert(manager
!= NULL
);
439 g_assert(instance
!= NULL
);
441 /* Generate a unique name for the instance. */
442 string
= g_string_new(NULL
);
444 g_string_set_size(string
, 0);
445 g_string_append_printf(string
, "%s %i",
446 instance
->lib
->name
, ++i
);
447 } while (irreco_string_table_exists(manager
->instance_table
,
449 irreco_backend_manager_set_instance_name(manager
,
452 g_string_free(string
, TRUE
);
458 * Set configuration filename to the instance, if it is not used by another
462 irreco_backend_manager_set_instance_config(IrrecoBackendManager
* manager
,
463 IrrecoBackendInstance
* instance
,
464 const gchar
* filename
)
467 g_assert(manager
!= NULL
);
468 g_assert(instance
!= NULL
);
469 g_assert(filename
!= NULL
);
471 if (irreco_string_table_exists(manager
->config_map
, filename
)) {
472 IRRECO_RETURN_BOOL(FALSE
);
475 if (instance
->config
== NULL
|| irreco_string_table_exists(
476 manager
->config_map
, instance
->config
) == FALSE
) {
477 irreco_string_table_add(manager
->config_map
,
481 irreco_string_table_change_key(manager
->config_map
,
485 IRRECO_RETURN_BOOL(TRUE
);
489 * Assingn a unique configuration filename to the instance.
492 irreco_backend_manager_assign_instance_config(IrrecoBackendManager
* manager
,
493 IrrecoBackendInstance
* instance
)
499 g_assert(manager
!= NULL
);
500 g_assert(instance
!= NULL
);
502 string
= g_string_new(NULL
);
504 g_string_set_size(string
, 0);
505 g_string_append(string
, "backend_");
506 g_string_append(string
, instance
->lib
->filename
);
507 irreco_char_replace(string
->str
, '.', '_');
508 g_string_append_printf(string
, "_%i.config", ++i
);
509 } while (irreco_string_table_exists(manager
->config_map
,
511 irreco_backend_manager_set_instance_config(manager
,
514 g_string_free(string
, TRUE
);