Added button image data transmission from
[irreco.git] / irreco / src / core / irreco_backend_lib.c
blob49b341e27bbcec4e2b55c25118c72b7b4634f962
1 /*
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.
21 #include "irreco_backend_lib.h"
22 #include <gmodule.h>
25 /**
26 * @addtogroup IrrecoBackendLib
27 * @ingroup Irreco
29 * Load backend libraries and stores information about them.
31 * @{
34 /**
35 * @file
36 * Source file of @ref IrrecoBackendLib.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
41 /* Prototypes */
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 IrrecoBackendLib* irreco_backend_lib_load_with_name(const gchar *filepath,
45 const gchar *filename);
46 void irreco_backend_lib_load_dir_foreach(IrrecoDirForeachData * dir_data);
51 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 /* Function pointer cheking. */
53 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
55 /**
56 * @name Function pointer cheking
57 * @{
61 * Check function pointers using a way that does not create errors in GCC -Wall.
63 typedef void (*IrrecoVoidFunction) (void);
64 typedef union {
65 IrrecoVoidFunction function;
66 gpointer pointer;
67 } IrrecoVoidFunctionUnion;
69 #define HAS_FUNCTION(__lib, __name) irreco_backend_lib_has_function(\
70 (IrrecoVoidFunction) __lib->api->__name, #__name )
72 gboolean irreco_backend_lib_has_function(IrrecoVoidFunction function,
73 const gchar * name)
75 IrrecoVoidFunctionUnion function_union;
76 IRRECO_ENTER
78 function_union.function = function;
79 if (function_union.pointer == NULL) {
80 IRRECO_ERROR("Could not get function pointer for \"%s\".\n",
81 name);
82 IRRECO_RETURN_BOOL(FALSE);
84 IRRECO_RETURN_BOOL(TRUE);
87 /** @} */
91 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
92 /* Backend loading. */
93 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
95 /**
96 * @name Backend loading
97 * @{
102 * Fix "warning: dereferencing type-punned pointer will break strict-aliasing
103 * rules" warning during g_module_symbol() call the way GCC docs suggest.
105 typedef union {
106 GetIrrecoBackendFunctionTable function;
107 gpointer pointer;
108 } GetFunctionTableUnion;
111 * Load backend from file.
113 * Args:
114 * filepath Complete path to library.
115 * filename Basename of the library.
117 IrrecoBackendLib* irreco_backend_lib_load_with_name(const gchar *filepath,
118 const gchar *filename)
120 GetFunctionTableUnion get_irreco_backend_function_table;
121 IrrecoBackendLib* backend_lib;
122 IRRECO_ENTER
124 IRRECO_PRINTF("Loading backend lib: \"%s\"\n", filename);
125 IRRECO_PRINTF("Path: \"%s\"\n", filepath);
126 backend_lib = g_slice_new0(IrrecoBackendLib);
128 backend_lib->module = g_module_open(filepath, G_MODULE_BIND_LOCAL);
129 if (backend_lib->module == NULL) {
130 IRRECO_ERROR("Failed to open library \"%s\" with "
131 "g_module_open().\n", filepath);
132 goto error;
135 if (!g_module_symbol(backend_lib->module,
136 "get_irreco_backend_function_table",
137 &get_irreco_backend_function_table.pointer)) {
138 IRRECO_ERROR("Could not find function "
139 "\"get_irreco_backend_function_table\""
140 "in backend \"%s\"\n", filepath);
141 goto error;
144 IRRECO_PRINTF("Getting function table.\n");
145 backend_lib->api = get_irreco_backend_function_table.function();
146 if (backend_lib->api == NULL) {
147 IRRECO_ERROR("Could not get function table "
148 "from backend \"%s\"\n", filepath);
149 goto error;
152 /* Check api version. */
153 if (backend_lib->api->version < IRRECO_BACKEND_API_VERSION) {
154 IRRECO_ERROR("Backend must implement atleast version %i of "
155 "backend api. Only version %i implemented by"
156 "backend \"%s\"\n",
157 IRRECO_BACKEND_API_VERSION,
158 backend_lib->api->version, filepath);
159 goto error;
162 if (!HAS_FUNCTION(backend_lib, get_error_msg)
163 || !HAS_FUNCTION(backend_lib, create)
164 || !HAS_FUNCTION(backend_lib, destroy)
165 || !HAS_FUNCTION(backend_lib, from_conf)
166 || !HAS_FUNCTION(backend_lib, to_conf)
167 || !HAS_FUNCTION(backend_lib, get_devices)
168 || !HAS_FUNCTION(backend_lib, get_commands)
169 || !HAS_FUNCTION(backend_lib, send_command)
170 || !HAS_FUNCTION(backend_lib, configure)) {
171 IRRECO_ERROR("Could not get complete function table "
172 "from backend \"%s\"\n", filepath);
173 goto error;
176 if ((backend_lib->api->flags & IRRECO_BACKEND_EDITABLE_DEVICES) && (
177 !HAS_FUNCTION(backend_lib, create_device)
178 || !HAS_FUNCTION(backend_lib, is_device_editable)
179 || !HAS_FUNCTION(backend_lib, edit_device)
180 || !HAS_FUNCTION(backend_lib, delete_device)
181 )) {
182 IRRECO_ERROR("Backend \"%s\" claims to support "
183 "editable devices, but does not provide "
184 "the needed functions.\n", filepath);
185 goto error;
188 if ((backend_lib->api->flags & IRRECO_BACKEND_CONFIGURATION_EXPORT) && (
189 !HAS_FUNCTION(backend_lib, export_conf)
190 || !HAS_FUNCTION(backend_lib, import_conf)
191 || !HAS_FUNCTION(backend_lib, check_conf)
192 )) {
193 IRRECO_ERROR("Backend \"%s\" claims to support "
194 "configuration export, but does not provide "
195 "the needed functions.\n", filepath);
196 goto error;
198 if (backend_lib->api->name == NULL) {
199 IRRECO_ERROR("Backend name is not set in function table.\n");
200 goto error;
203 backend_lib->filepath = g_strdup(filepath);
204 backend_lib->filename = g_strdup(filename);
205 backend_lib->name = g_strdup(backend_lib->api->name);
206 g_module_make_resident(backend_lib->module);
208 IRRECO_PRINTF("Backend \"%s\" loaded successfully\n",
209 backend_lib->name);
210 IRRECO_RETURN_PTR(backend_lib);
213 /* Loading of module failed. Close module and free memory. */
214 error:
215 if (backend_lib->module) g_module_close(backend_lib->module);
216 g_slice_free(IrrecoBackendLib, backend_lib);
217 IRRECO_RETURN_PTR(NULL);
220 void irreco_backend_lib_close(IrrecoBackendLib * backend_lib)
222 IRRECO_ENTER
223 if (backend_lib == NULL) IRRECO_RETURN
225 g_module_close(backend_lib->module);
226 backend_lib->module = NULL;
227 g_free(backend_lib->name);
228 backend_lib->name = NULL;
229 g_free(backend_lib->filename);
230 backend_lib->filename = NULL;
231 g_free(backend_lib->filepath);
232 backend_lib->filepath = NULL;
234 g_slice_free(IrrecoBackendLib, backend_lib);
236 IRRECO_RETURN
239 /** @} */
240 /** @} */