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"
26 * @addtogroup IrrecoBackendLib
29 * Load backend libraries and stores information about them.
36 * Source file of @ref IrrecoBackendLib.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
56 * @name Function pointer cheking
61 * Check function pointers using a way that does not create errors in GCC -Wall.
63 typedef void (*IrrecoVoidFunction
) (void);
65 IrrecoVoidFunction function
;
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
,
75 IrrecoVoidFunctionUnion function_union
;
78 function_union
.function
= function
;
79 if (function_union
.pointer
== NULL
) {
80 IRRECO_ERROR("Could not get function pointer for \"%s\".\n",
82 IRRECO_RETURN_BOOL(FALSE
);
84 IRRECO_RETURN_BOOL(TRUE
);
91 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
92 /* Backend loading. */
93 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
96 * @name Backend loading
102 * Fix "warning: dereferencing type-punned pointer will break strict-aliasing
103 * rules" warning during g_module_symbol() call the way GCC docs suggest.
106 GetIrrecoBackendFunctionTable function
;
108 } GetFunctionTableUnion
;
111 * Load backend from file.
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
;
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
);
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
);
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
);
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"
157 IRRECO_BACKEND_API_VERSION
,
158 backend_lib
->api
->version
, filepath
);
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
);
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
)
182 IRRECO_ERROR("Backend \"%s\" claims to support "
183 "editable devices, but does not provide "
184 "the needed functions.\n", filepath
);
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
)
193 IRRECO_ERROR("Backend \"%s\" claims to support "
194 "configuration export, but does not provide "
195 "the needed functions.\n", filepath
);
198 if (backend_lib
->api
->name
== NULL
) {
199 IRRECO_ERROR("Backend name is not set in function table.\n");
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",
210 IRRECO_RETURN_PTR(backend_lib
);
213 /* Loading of module failed. Close module and free memory. */
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
)
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
);