1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001 Takuro Ashie
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
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.
16 *
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
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: spi.c,v 1.8 2003/06/13 09:43:02 makeinu Exp $
22 */
23
24 #include "spi.h"
25
26 #ifdef ENABLE_SPI
27
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "fileutil.h"
32 #include "gfileutil.h"
33 #include "prefs_spi.h"
34
35 #ifdef G_PLATFORM_WIN32
36 static
peimage_resolve(PE_image * image,const char * symbol_name)37 void* peimage_resolve (PE_image* image, const char* symbol_name)
38 {
39 void* symbol;
40 if (g_module_symbol (image, symbol_name, &symbol))
41 return symbol;
42 else
43 return NULL;
44 }
45 #endif
46
47 static void spi_clear_search_dir_list (void);
48 static void spi_create_search_dir_list (void);
49 static void spi_search_directory (const gchar *dirname);
50 static gboolean spi_regist (PE_image *pe);
51 static SusiePlugin *spi_regist_import_filter (PE_image *pe);
52 static SusiePlugin *spi_regist_export_filter (PE_image *pe);
53 static SusiePlugin *spi_regist_archive_extractor (PE_image *pe);
54
55
56 const char *spi_errormsg[] = {
57 /* -1: Unimplemented */
58 "Success",
59 "Callback returned non-zero",
60 "Unknown format",
61 "Data broken",
62 "No enough memory",
63 "Memory error",
64 "File read error",
65 "Reserved",
66 "Internal error"
67 };
68 int spi_errormsg_num = sizeof (spi_errormsg) / sizeof (char *);
69
70
71 static gboolean spi_inited = FALSE;
72 static GList *spi_search_dir_list = NULL;
73 static GList *spi_import_filter_list = NULL;
74 static GList *spi_export_filter_list = NULL;
75 static GList *spi_archive_extractor_list = NULL;
76
77
78 /*****************************************************************************
79 *
80 * Private functions.
81 *
82 *****************************************************************************/
83 static void
spi_clear_search_dir_list(void)84 spi_clear_search_dir_list (void)
85 {
86 g_list_foreach (spi_search_dir_list, (GFunc) g_free, NULL);
87 g_list_free (spi_search_dir_list);
88 spi_search_dir_list = NULL;
89 }
90
91
92 static void
spi_create_search_dir_list(void)93 spi_create_search_dir_list (void)
94 {
95 const gchar *dirlist;
96 gchar **dirs;
97 gint i;
98
99 spi_clear_search_dir_list ();
100
101 if (gimv_prefs_spi_get_use_default_dirlist ())
102 dirlist = SPI_DEFAULT_SEARCH_DIR_LIST;
103 else
104 dirlist = gimv_prefs_spi_get_dirconf ();
105
106 if (!dirlist || !*dirlist) return;
107
108 dirs = g_strsplit (dirlist, ",", -1);
109
110 for (i = 0; dirs && dirs[i]; i++) {
111 if (*dirs[i])
112 spi_search_dir_list = g_list_append (spi_search_dir_list,
113 g_strdup (dirs[i]));
114 }
115
116 g_strfreev (dirs);
117 }
118
119
120 static void
spi_search_directory(const gchar * dirname)121 spi_search_directory (const gchar *dirname)
122 {
123 GList *filelist = NULL, *node;
124
125 g_return_if_fail (dirname);
126 if (!isdir (dirname)) return;
127
128 get_dir (dirname, GETDIR_FOLLOW_SYMLINK, &filelist, NULL);
129 if (!filelist) return;
130
131 node = filelist;
132
133 while (node) {
134 gchar *filename = node->data;
135 gboolean success;
136 gint len;
137 PE_image *pe;
138
139 node = g_list_next (node);
140
141 len = strlen (filename);
142 if (len < 4 || strcasecmp (filename + len - 4, ".spi")) continue;
143
144 g_print ("PluginName: %s\n", filename);
145
146 pe = peimage_create ();
147 if (!peimage_load (pe, filename)) {
148 peimage_destroy (pe);
149 g_print ("peimage_load() failed: %s\n", filename);
150 continue;
151 }
152
153 success = spi_regist (pe);
154 if (success) {
155 /* hoge */
156 } else {
157 peimage_destroy(pe);
158 }
159 }
160
161 g_list_foreach (filelist, (GFunc) g_free, NULL);
162 g_list_free (filelist);
163 }
164
165
166 static gboolean
spi_regist(PE_image * pe)167 spi_regist (PE_image *pe)
168 {
169 gchar buf[256];
170 gboolean success;
171 GetPluginInfoFunc get_plugin_info;
172 SusiePlugin *plugin;
173
174 g_return_val_if_fail (pe, FALSE);
175
176 get_plugin_info = peimage_resolve (pe, "GetPluginInfo");
177 if (!get_plugin_info) {
178 g_print ("Cannot resolve GetPluginInfo.\n");
179 goto ERROR;
180 }
181
182 success = get_plugin_info (0, buf, 256);
183 if (!success) {
184 g_print ("GetPluginInfo returns 0\n");
185 goto ERROR;
186 }
187
188 switch (buf[2]) {
189 case 'I':
190 g_print ("Detected as Import filter.\n");
191 plugin = spi_regist_import_filter (pe);
192 break;
193
194 case 'X':
195 g_print ("Export filter is not supported yet.\n");
196 plugin = spi_regist_export_filter (pe);
197 break;
198
199 case 'A':
200 g_print ("Archiver extractor is not supported yet.\n");
201 plugin = spi_regist_archive_extractor (pe);
202 break;
203
204 default:
205 g_print ("Unknown susie plugin type %c.\n", buf[2]);
206 plugin = NULL;
207 break;
208 }
209
210 if (!plugin) goto ERROR;
211
212 plugin->pe = pe;
213 plugin->get_plugin_info = get_plugin_info;
214 success = plugin->get_plugin_info (1, buf, 256);
215 if (success) {
216 plugin->description = g_strdup (buf);
217 g_print ("description: %s\n\n", plugin->description);
218 } else {
219 plugin->description = NULL;
220 }
221
222 /* FIXME */
223 plugin->formats = NULL;
224
225
226 return TRUE;
227
228 ERROR:
229 return FALSE;
230 }
231
232
233 static SusiePlugin *
spi_regist_import_filter(PE_image * pe)234 spi_regist_import_filter (PE_image *pe)
235 {
236 SpiImportFilter *loader;
237
238 g_return_val_if_fail (pe, NULL);
239
240 loader = g_new0 (SpiImportFilter, 1);
241
242 loader->is_supported = peimage_resolve (pe, "IsSupported");
243 if (!loader->is_supported) {
244 g_print ("Cannot resolve IsSupported.\n");
245 goto ERROR;
246 }
247
248 loader->get_pic_info = peimage_resolve (pe, "GetPictureInfo");
249 if (!loader->get_pic_info) {
250 g_print ("Cannot resolve GetPictureInfo.\n");
251 goto ERROR;
252 }
253
254 loader->get_pic = peimage_resolve (pe, "GetPicture");
255 if (!loader->get_pic) {
256 g_print ("Cannot resolve GetPicture.\n");
257 goto ERROR;
258 }
259
260 spi_import_filter_list = g_list_append (spi_import_filter_list, loader);
261
262 return (SusiePlugin *) loader;
263
264 ERROR:
265 g_free (loader);
266 return NULL;
267 }
268
269
270 static SusiePlugin *
spi_regist_export_filter(PE_image * pe)271 spi_regist_export_filter (PE_image *pe)
272 {
273 return NULL;
274 }
275
276
277 static SusiePlugin *
spi_regist_archive_extractor(PE_image * pe)278 spi_regist_archive_extractor (PE_image *pe)
279 {
280 SpiArchiveExtractor *extractor;
281
282 g_return_val_if_fail (pe, NULL);
283
284 extractor = g_new0 (SpiArchiveExtractor, 1);
285
286 extractor->is_supported = peimage_resolve (pe, "IsSupported");
287 if (!extractor->is_supported) {
288 g_print ("Cannot resolve IsSupported.\n");
289 goto ERROR;
290 }
291
292 extractor->get_archive_info = peimage_resolve (pe, "GetArchiveInfo");
293 if (!extractor->get_archive_info) {
294 g_print ("Cannot resolve GetArchiveInfo.\n");
295 goto ERROR;
296 }
297
298 extractor->get_file_info = peimage_resolve (pe, "GetFileInfo");
299 if (!extractor->get_file_info) {
300 g_print ("Cannot resolve GetFileInfo.\n");
301 goto ERROR;
302 }
303
304 extractor->get_file = peimage_resolve (pe, "GetFile");
305 if (!extractor->get_file) {
306 g_print ("Cannot resolve GetFile.\n");
307 goto ERROR;
308 }
309
310 spi_archive_extractor_list = g_list_append (spi_archive_extractor_list,
311 extractor);
312
313 return (SusiePlugin *) extractor;
314
315 ERROR:
316 g_free (extractor);
317 return NULL;
318 }
319
320
321
322 /*****************************************************************************
323 *
324 * Public functions.
325 *
326 *****************************************************************************/
327 void
spi_init()328 spi_init ()
329 {
330 GList *list;
331
332 spi_create_search_dir_list ();
333
334 /* load spi from disk */
335 list = g_list_last (spi_search_dir_list);
336 for (; list; list = g_list_previous (list)) {
337 gchar *dir = list->data;
338
339 if (dir && *dir)
340 spi_search_directory (dir);
341 }
342
343 spi_inited = TRUE;
344 }
345
346
347 GList *
spi_get_search_dir_list(void)348 spi_get_search_dir_list (void)
349 {
350 if (!spi_inited)
351 spi_init();
352 return spi_search_dir_list;
353 }
354
355
356 GList *
spi_get_import_filter_list(void)357 spi_get_import_filter_list (void)
358 {
359 if (!spi_inited)
360 spi_init();
361 return spi_import_filter_list;
362 }
363
364
365 GList *
spi_get_export_filter_list(void)366 spi_get_export_filter_list (void)
367 {
368 if (!spi_inited)
369 spi_init();
370 return spi_export_filter_list;
371 }
372
373
374 GList *
spi_get_archive_extractor_list(void)375 spi_get_archive_extractor_list (void)
376 {
377 if (!spi_inited)
378 spi_init();
379 return spi_archive_extractor_list;
380 }
381
382 #endif /* ENABLE_SPI */
383