summaryrefslogtreecommitdiff
path: root/src/lib/evas/file
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/file
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/file')
-rw-r--r--src/lib/evas/file/evas_module.c607
-rw-r--r--src/lib/evas/file/evas_module.h94
-rw-r--r--src/lib/evas/file/evas_path.c152
-rw-r--r--src/lib/evas/file/evas_path.h15
4 files changed, 868 insertions, 0 deletions
diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c
new file mode 100644
index 0000000000..de20035374
--- /dev/null
+++ b/src/lib/evas/file/evas_module.c
@@ -0,0 +1,607 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <string.h>
6
7#include <evas_common.h>
8#include <evas_private.h>
9#include <evas_module.h>
10
11
12static Eina_Hash *evas_modules[4] = {
13 NULL,
14 NULL,
15 NULL,
16 NULL
17};
18
19static Eina_List *eina_evas_modules = NULL;
20static Eina_List *evas_module_paths = NULL;
21static Eina_Array *evas_engines = NULL;
22
23static Eina_List *
24_evas_module_append(Eina_List *list, char *path)
25{
26 if (path)
27 {
28 if (evas_file_path_exists(path))
29 list = eina_list_append(list, path);
30 else
31 free(path);
32 }
33 return list;
34}
35
36/* this will alloc a list of paths to search for the modules */
37/* by now these are: */
38/* 1. ~/.evas/modules/ */
39/* 2. $(EVAS_MODULE_DIR)/evas/modules/ */
40/* 3. dladdr/evas/modules/ */
41/* 4. PREFIX/evas/modules/ */
42void
43evas_module_paths_init(void)
44{
45 char *libdir, *path;
46
47 /* 1. ~/.evas/modules/ */
48 path = eina_module_environment_path_get("HOME", "/.evas/modules");
49 evas_module_paths = _evas_module_append(evas_module_paths, path);
50
51 /* 2. $(EVAS_MODULE_DIR)/evas/modules/ */
52 path = eina_module_environment_path_get("EVAS_MODULES_DIR", "/evas/modules");
53 if (eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path))
54 free(path);
55 else
56 evas_module_paths = _evas_module_append(evas_module_paths, path);
57
58 /* 3. libevas.so/../evas/modules/ */
59 libdir = (char *)_evas_module_libdir_get();
60 if (!libdir)
61 path = eina_module_symbol_path_get(evas_module_paths_init, "/evas/modules");
62 else
63 {
64 path = malloc(strlen(libdir) + strlen("/evas/modules") + 1);
65 if (path)
66 {
67 strcpy(path, libdir);
68 strcat(path, "/evas/modules");
69 }
70 }
71 if (eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path))
72 free(path);
73 else
74 evas_module_paths = _evas_module_append(evas_module_paths, path);
75
76 /* 4. PREFIX/lib/evas/modules/ */
77#ifndef _MSC_VER
78 path = PACKAGE_LIB_DIR "/evas/modules";
79 if (!eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path))
80 {
81 path = strdup(path);
82 if (path)
83 evas_module_paths = _evas_module_append(evas_module_paths, path);
84 }
85#endif
86}
87
88#define EVAS_EINA_STATIC_MODULE_DEFINE(Tn, Name) \
89 Eina_Bool evas_##Tn##_##Name##_init(void); \
90 void evas_##Tn##_##Name##_shutdown(void);
91
92#define EVAS_EINA_STATIC_MODULE_USE(Tn, Name) \
93 { evas_##Tn##_##Name##_init, evas_##Tn##_##Name##_shutdown }
94
95EVAS_EINA_STATIC_MODULE_DEFINE(engine, buffer);
96EVAS_EINA_STATIC_MODULE_DEFINE(engine, direct3d);
97EVAS_EINA_STATIC_MODULE_DEFINE(engine, directfb);
98EVAS_EINA_STATIC_MODULE_DEFINE(engine, fb);
99EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_x11);
100EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_sdl);
101EVAS_EINA_STATIC_MODULE_DEFINE(engine, psl1ght);
102EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8);
103EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8_x11);
104EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_ddraw);
105EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_gdi);
106EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_generic);
107EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_x11);
108EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, bmp);
109EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, eet);
110EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, generic);
111EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, gif);
112EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, ico);
113EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, jpeg);
114EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, pmaps);
115EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, png);
116EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, psd);
117EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, svg);
118EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tga);
119EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
120EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp);
121EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, webp);
122EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
123EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, eet);
124EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, jpeg);
125EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png);
126EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff);
127
128static const struct {
129 Eina_Bool (*init)(void);
130 void (*shutdown)(void);
131} evas_static_module[] = {
132#ifdef EVAS_STATIC_BUILD_BUFFER
133 EVAS_EINA_STATIC_MODULE_USE(engine, buffer),
134#endif
135#ifdef EVAS_STATIC_BUILD_DIRECT3D
136 EVAS_EINA_STATIC_MODULE_USE(engine, direct3d),
137#endif
138#ifdef EVAS_STATIC_BUILD_DIRECTFB
139 EVAS_EINA_STATIC_MODULE_USE(engine, directfb),
140#endif
141#ifdef EVAS_STATIC_BUILD_FB
142 EVAS_EINA_STATIC_MODULE_USE(engine, fb),
143#endif
144#ifdef EVAS_STATIC_BUILD_GL_X11
145 EVAS_EINA_STATIC_MODULE_USE(engine, gl_x11),
146#endif
147#ifdef EVAS_STATIC_BUILD_GL_SDL
148 EVAS_EINA_STATIC_MODULE_USE(engine, gl_sdl),
149#endif
150#ifdef EVAS_STATIC_BUILD_PSL1GHT
151 EVAS_EINA_STATIC_MODULE_USE(engine, psl1ght),
152#endif
153#ifdef EVAS_STATIC_BUILD_SOFTWARE_GDI
154 EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
155#endif
156#ifdef EVAS_STATIC_BUILD_SOFTWARE_DDRAW
157 EVAS_EINA_STATIC_MODULE_USE(engine, software_ddraw),
158#endif
159#ifdef EVAS_STATIC_BUILD_SOFTWARE_8
160 EVAS_EINA_STATIC_MODULE_USE(engine, software_8),
161#endif
162#ifdef EVAS_STATIC_BUILD_SOFTWARE_8_X11
163 EVAS_EINA_STATIC_MODULE_USE(engine, software_8_x11),
164#endif
165#ifdef EVAS_STATIC_BUILD_SOFTWARE_DDRAW
166 EVAS_EINA_STATIC_MODULE_USE(engine, software_ddraw),
167#endif
168#ifdef EVAS_STATIC_BUILD_SOFTWARE_GDI
169 EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
170#endif
171#ifdef EVAS_STATIC_BUILD_SOFTWARE_GENERIC
172 EVAS_EINA_STATIC_MODULE_USE(engine, software_generic),
173#endif
174#ifdef EVAS_STATIC_BUILD_SOFTWARE_X11
175 EVAS_EINA_STATIC_MODULE_USE(engine, software_x11),
176#endif
177#ifdef EVAS_STATIC_BUILD_BMP
178 EVAS_EINA_STATIC_MODULE_USE(image_loader, bmp),
179#endif
180#ifdef EVAS_STATIC_BUILD_EET
181 EVAS_EINA_STATIC_MODULE_USE(image_loader, eet),
182#endif
183#ifdef EVAS_STATIC_BUILD_GENERIC
184 EVAS_EINA_STATIC_MODULE_USE(image_loader, generic),
185#endif
186#ifdef EVAS_STATIC_BUILD_GIF
187 EVAS_EINA_STATIC_MODULE_USE(image_loader, gif),
188#endif
189#ifdef EVAS_STATIC_BUILD_ICO
190 EVAS_EINA_STATIC_MODULE_USE(image_loader, ico),
191#endif
192#ifdef EVAS_STATIC_BUILD_JPEG
193 EVAS_EINA_STATIC_MODULE_USE(image_loader, jpeg),
194#endif
195#ifdef EVAS_STATIC_BUILD_PMAPS
196 EVAS_EINA_STATIC_MODULE_USE(image_loader, pmaps),
197#endif
198#ifdef EVAS_STATIC_BUILD_PNG
199 EVAS_EINA_STATIC_MODULE_USE(image_loader, png),
200#endif
201#ifdef EVAS_STATIC_BUILD_PSD
202 EVAS_EINA_STATIC_MODULE_USE(image_loader, psd),
203#endif
204#ifdef EVAS_STATIC_BUILD_SVG
205 EVAS_EINA_STATIC_MODULE_USE(image_loader, svg),
206#endif
207#ifdef EVAS_STATIC_BUILD_TGA
208 EVAS_EINA_STATIC_MODULE_USE(image_loader, tga),
209#endif
210#ifdef EVAS_STATIC_BUILD_TIFF
211 EVAS_EINA_STATIC_MODULE_USE(image_loader, tiff),
212#endif
213#ifdef EVAS_STATIC_BUILD_WBMP
214 EVAS_EINA_STATIC_MODULE_USE(image_loader, wbmp),
215#endif
216#ifdef EVAS_STATIC_BUILD_WEBP
217 EVAS_EINA_STATIC_MODULE_USE(image_loader, webp),
218#endif
219#ifdef EVAS_STATIC_BUILD_XPM
220 EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
221#endif
222#ifdef EVAS_STATIC_BUILD_EET
223 EVAS_EINA_STATIC_MODULE_USE(image_saver, eet),
224#endif
225#if defined (EVAS_BUILD_SAVER_JPEG) && defined (EVAS_STATIC_BUILD_JPEG)
226 EVAS_EINA_STATIC_MODULE_USE(image_saver, jpeg),
227#endif
228#ifdef EVAS_STATIC_BUILD_PNG
229 EVAS_EINA_STATIC_MODULE_USE(image_saver, png),
230#endif
231#ifdef EVAS_STATIC_BUILD_TIFF
232 EVAS_EINA_STATIC_MODULE_USE(image_saver, tiff),
233#endif
234 { NULL, NULL }
235};
236
237/* this will alloc an Evas_Module struct for each module
238 * it finds on the paths */
239void
240evas_module_init(void)
241{
242 int i;
243
244 evas_module_paths_init();
245
246 evas_modules[EVAS_MODULE_TYPE_ENGINE] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
247 evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
248 evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
249 evas_modules[EVAS_MODULE_TYPE_OBJECT] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
250
251 evas_engines = eina_array_new(4);
252
253 for (i = 0; evas_static_module[i].init; ++i)
254 evas_static_module[i].init();
255}
256
257Eina_Bool
258evas_module_register(const Evas_Module_Api *module, Evas_Module_Type type)
259{
260 Evas_Module *em;
261
262 if ((unsigned int)type > 3) return EINA_FALSE;
263 if (!module) return EINA_FALSE;
264 if (module->version != EVAS_MODULE_API_VERSION) return EINA_FALSE;
265
266 em = eina_hash_find(evas_modules[type], module->name);
267 if (em) return EINA_FALSE;
268
269 em = calloc(1, sizeof (Evas_Module));
270 if (!em) return EINA_FALSE;
271
272 em->definition = module;
273
274 if (type == EVAS_MODULE_TYPE_ENGINE)
275 {
276 eina_array_push(evas_engines, em);
277 em->id_engine = eina_array_count(evas_engines);
278 }
279
280 eina_hash_direct_add(evas_modules[type], module->name, em);
281
282 return EINA_TRUE;
283}
284
285Eina_List *
286evas_module_engine_list(void)
287{
288 Evas_Module *em;
289 Eina_List *r = NULL, *l, *ll;
290 Eina_Array_Iterator iterator;
291 Eina_Iterator *it, *it2;
292 unsigned int i;
293 const char *s, *s2;
294 char buf[4096];
295
296 EINA_LIST_FOREACH(evas_module_paths, l, s)
297 {
298 snprintf(buf, sizeof(buf), "%s/engines", s);
299 it = eina_file_direct_ls(buf);
300 if (it)
301 {
302 Eina_File_Direct_Info *fi;
303
304 EINA_ITERATOR_FOREACH(it, fi)
305 {
306 const char *fname = fi->path + fi->name_start;
307 snprintf(buf, sizeof(buf), "%s/engines/%s/%s",
308 s, fname, MODULE_ARCH);
309 it2 = eina_file_ls(buf);
310 if (it2)
311 {
312 EINA_LIST_FOREACH(r, ll, s2)
313 {
314 if (!strcmp(fname, s2)) break;
315 }
316 if (!ll)
317 r = eina_list_append(r, eina_stringshare_add(fname));
318 eina_iterator_free(it2);
319 }
320 }
321 eina_iterator_free(it);
322 }
323 }
324
325 EINA_ARRAY_ITER_NEXT(evas_engines, i, em, iterator)
326 {
327 EINA_LIST_FOREACH(r, ll, s2)
328 {
329 if (!strcmp(em->definition->name, s2)) break;
330 }
331 if (!ll)
332 r = eina_list_append(r, eina_stringshare_add(em->definition->name));
333 }
334
335 return r;
336}
337
338Eina_Bool
339evas_module_unregister(const Evas_Module_Api *module, Evas_Module_Type type)
340{
341 Evas_Module *em;
342
343 if ((unsigned int)type > 3) return EINA_FALSE;
344 if (!module) return EINA_FALSE;
345
346 em = eina_hash_find(evas_modules[type], module->name);
347 if (!em || em->definition != module) return EINA_FALSE;
348
349 if (type == EVAS_MODULE_TYPE_ENGINE)
350 eina_array_data_set(evas_engines, em->id_engine, NULL);
351
352 eina_hash_del(evas_modules[type], module->name, em);
353 free(em);
354
355 return EINA_TRUE;
356}
357
358#if defined(__CEGCC__) || defined(__MINGW32CE__)
359# define EVAS_MODULE_NAME_IMAGE_SAVER "saver_%s.dll"
360# define EVAS_MODULE_NAME_IMAGE_LOADER "loader_%s.dll"
361# define EVAS_MODULE_NAME_ENGINE "engine_%s.dll"
362# define EVAS_MODULE_NAME_OBJECT "object_%s.dll"
363#elif _WIN32
364# define EVAS_MODULE_NAME_IMAGE_SAVER "module.dll"
365# define EVAS_MODULE_NAME_IMAGE_LOADER "module.dll"
366# define EVAS_MODULE_NAME_ENGINE "module.dll"
367# define EVAS_MODULE_NAME_OBJECT "module.dll"
368#else
369# define EVAS_MODULE_NAME_IMAGE_SAVER "module.so"
370# define EVAS_MODULE_NAME_IMAGE_LOADER "module.so"
371# define EVAS_MODULE_NAME_ENGINE "module.so"
372# define EVAS_MODULE_NAME_OBJECT "module.so"
373#endif
374
375Evas_Module *
376evas_module_find_type(Evas_Module_Type type, const char *name)
377{
378 const char *path;
379 const char *format = NULL;
380 char buffer[4096];
381 Evas_Module *em;
382 Eina_Module *en;
383 Eina_List *l;
384
385 if ((unsigned int)type > 3) return NULL;
386
387 em = eina_hash_find(evas_modules[type], name);
388 if (em) return em;
389
390 EINA_LIST_FOREACH(evas_module_paths, l, path)
391 {
392 switch (type)
393 {
394 case EVAS_MODULE_TYPE_ENGINE: format = "%s/engines/%s/%s/" EVAS_MODULE_NAME_ENGINE; break;
395 case EVAS_MODULE_TYPE_IMAGE_LOADER: format = "%s/loaders/%s/%s/" EVAS_MODULE_NAME_IMAGE_LOADER; break;
396 case EVAS_MODULE_TYPE_IMAGE_SAVER: format = "%s/savers/%s/%s/" EVAS_MODULE_NAME_IMAGE_SAVER; break;
397 case EVAS_MODULE_TYPE_OBJECT: format = "%s/object/%s/%s/" EVAS_MODULE_NAME_OBJECT; break;
398 }
399
400 snprintf(buffer, sizeof (buffer), format, path, name, MODULE_ARCH, name);
401 if (!evas_file_path_is_file(buffer)) continue;
402
403 en = eina_module_new(buffer);
404 if (!en) continue;
405
406 if (!eina_module_load(en))
407 {
408 eina_module_free(en);
409 continue;
410 }
411
412 em = eina_hash_find(evas_modules[type], name);
413 if (em)
414 {
415 eina_evas_modules = eina_list_append(eina_evas_modules, en);
416 return em;
417 }
418
419 eina_module_free(en);
420 }
421
422 return NULL;
423}
424
425Evas_Module *
426evas_module_engine_get(int render_method)
427{
428 if ((render_method <= 0) ||
429 ((unsigned int)render_method > eina_array_count(evas_engines)))
430 return NULL;
431 return eina_array_data_get(evas_engines, render_method - 1);
432}
433
434void
435evas_module_foreach_image_loader(Eina_Hash_Foreach cb, const void *fdata)
436{
437 eina_hash_foreach(evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER], cb, fdata);
438}
439
440int
441evas_module_load(Evas_Module *em)
442{
443 if (em->loaded) return 1;
444 if (!em->definition) return 0;
445
446 if (!em->definition->func.open(em)) return 0;
447 em->loaded = 1;
448
449 LKI(em->lock);
450 return 1;
451}
452
453void
454evas_module_unload(Evas_Module *em)
455{
456 if (!em->loaded)
457 return;
458 if (!em->definition)
459 return ;
460
461// for now lets not unload modules - they may still be in use.
462// em->definition->func.close(em);
463// em->loaded = 0;
464
465 LKD(em->lock);
466}
467
468void
469evas_module_ref(Evas_Module *em)
470{
471 LKL(em->lock);
472 em->ref++;
473 LKU(em->lock);
474}
475
476void
477evas_module_unref(Evas_Module *em)
478{
479 LKL(em->lock);
480 em->ref--;
481 LKU(em->lock);
482}
483
484static int use_count = 0;
485
486void
487evas_module_use(Evas_Module *em)
488{
489 em->last_used = use_count;
490}
491
492void
493evas_module_clean(void)
494{
495 static int call_count = 0;
496/* int ago; */
497 int noclean = -1;
498/* Eina_List *l; */
499/* Evas_Module *em; */
500
501 /* only clean modules every 256 calls */
502 call_count++;
503 if (call_count <= 256) return;
504 call_count = 0;
505
506 if (noclean == -1)
507 {
508 if (getenv("EVAS_NOCLEAN"))
509 noclean = 1;
510 else
511 noclean = 0;
512 }
513 if (noclean == 1) return;
514
515 /* disable module cleaning for now - may cause instability with some modules */
516 return;
517
518 /* FIXME: Don't know what it is supposed to do. */
519/* /\* incriment use counter = 28bits *\/ */
520/* use_count++; */
521/* if (use_count > 0x0fffffff) use_count = 0; */
522
523/* /\* printf("CLEAN!\n"); *\/ */
524/* /\* go through all modules *\/ */
525/* EINA_LIST_FOREACH(evas_modules, l, em) */
526/* { */
527/* /\* printf("M %s %i %i\n", em->name, em->ref, em->loaded); *\/ */
528/* /\* if the module is refernced - skip *\/ */
529/* if ((em->ref > 0) || (!em->loaded)) continue; */
530/* /\* how many clean cycles ago was this module last used *\/ */
531/* ago = use_count - em->last_used; */
532/* if (em->last_used > use_count) ago += 0x10000000; */
533/* /\* if it was used last more than N clean cycles ago - unload *\/ */
534/* if (ago > 5) */
535/* { */
536/* /\* printf(" UNLOAD %s\n", em->name); *\/ */
537/* evas_module_unload(em); */
538/* } */
539/* } */
540}
541
542static Eina_Prefix *pfx = NULL;
543
544/* will dlclose all the modules loaded and free all the structs */
545void
546evas_module_shutdown(void)
547{
548 Eina_Module *en;
549 char *path;
550 int i;
551
552 for (i = 0; evas_static_module[i].shutdown; ++i)
553 evas_static_module[i].shutdown();
554
555 EINA_LIST_FREE(eina_evas_modules, en)
556 eina_module_free(en);
557
558 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_ENGINE]);
559 evas_modules[EVAS_MODULE_TYPE_ENGINE] = NULL;
560 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER]);
561 evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER] = NULL;
562 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER]);
563 evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER] = NULL;
564 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_OBJECT]);
565 evas_modules[EVAS_MODULE_TYPE_OBJECT] = NULL;
566
567 EINA_LIST_FREE(evas_module_paths, path)
568 free(path);
569
570 eina_array_free(evas_engines);
571 evas_engines = NULL;
572 if (pfx)
573 {
574 eina_prefix_free(pfx);
575 pfx = NULL;
576 }
577}
578
579EAPI int
580_evas_module_engine_inherit(Evas_Func *funcs, char *name)
581{
582 Evas_Module *em;
583
584 em = evas_module_find_type(EVAS_MODULE_TYPE_ENGINE, name);
585 if (em)
586 {
587 if (evas_module_load(em))
588 {
589 /* FIXME: no way to unref */
590 evas_module_ref(em);
591 evas_module_use(em);
592 *funcs = *((Evas_Func *)(em->functions));
593 return 1;
594 }
595 }
596 return 0;
597}
598
599EAPI const char *
600_evas_module_libdir_get(void)
601{
602 if (!pfx) pfx = eina_prefix_new
603 (NULL, _evas_module_libdir_get, "EVAS", "evas", "checkme",
604 PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
605 if (!pfx) return NULL;
606 return eina_prefix_lib_get(pfx);
607}
diff --git a/src/lib/evas/file/evas_module.h b/src/lib/evas/file/evas_module.h
new file mode 100644
index 0000000000..8699b6bcb6
--- /dev/null
+++ b/src/lib/evas/file/evas_module.h
@@ -0,0 +1,94 @@
1#ifndef _EVAS_MODULE_H
2#define _EVAS_MODULE_H
3
4
5/* the module api version */
6#define EVAS_MODULE_API_VERSION 2
7
8
9/* the module types */
10typedef enum _Evas_Module_Type
11{
12 EVAS_MODULE_TYPE_ENGINE = 0,
13 EVAS_MODULE_TYPE_IMAGE_LOADER = 1,
14 EVAS_MODULE_TYPE_IMAGE_SAVER = 2,
15 EVAS_MODULE_TYPE_OBJECT = 3
16} Evas_Module_Type;
17
18
19typedef struct _Evas_Module_Api Evas_Module_Api;
20typedef struct _Evas_Module Evas_Module;
21typedef struct _Evas_Module_Path Evas_Module_Path;
22typedef struct _Evas_Module_Engine Evas_Module_Engine;
23typedef struct _Evas_Module_Public Evas_Module_Public;
24
25/* the module api structure, all modules should define this struct */
26struct _Evas_Module_Api
27{
28 int version;
29 const char *name;
30 const char *author;
31
32 struct
33 {
34 int (*open)(Evas_Module *);
35 void (*close)(Evas_Module *);
36 } func;
37};
38
39/* the module structure */
40struct _Evas_Module
41{
42 const Evas_Module_Api *definition;
43
44 void *functions; /* this are the functions exported by the module */
45 int id_engine; /* some internal data for the module i.e the id for engines */
46
47 int ref; /* how many refs */
48 int last_used; /* the cycle count when it was last used */
49
50 LK(lock);
51
52 unsigned char loaded : 1;
53};
54
55
56/* the internals of the module api use this struct to reference a path with a module type
57 * instead of deduce the type from the path.
58 * */
59struct _Evas_Module_Path
60{
61 Evas_Module_Type type;
62 char *path;
63};
64
65void evas_module_paths_init (void);
66void evas_module_init (void);
67Evas_Module *evas_module_find_type (Evas_Module_Type type, const char *name);
68Evas_Module *evas_module_engine_get(int render_method);
69void evas_module_foreach_image_loader(Eina_Hash_Foreach cb, const void *fdata);
70int evas_module_load (Evas_Module *em);
71void evas_module_unload (Evas_Module *em);
72void evas_module_ref (Evas_Module *em);
73void evas_module_unref (Evas_Module *em);
74void evas_module_use (Evas_Module *em);
75void evas_module_clean (void);
76void evas_module_shutdown (void);
77EAPI Eina_Bool evas_module_register (const Evas_Module_Api *module, Evas_Module_Type type);
78EAPI Eina_Bool evas_module_unregister (const Evas_Module_Api *module, Evas_Module_Type type);
79
80#define EVAS_MODULE_DEFINE(Type, Tn, Name) \
81 Eina_Bool evas_##Tn##_##Name##_init(void) \
82 { \
83 return evas_module_register(&evas_modapi, Type); \
84 } \
85 void evas_##Tn##_##Name##_shutdown(void) \
86 { \
87 evas_module_unregister(&evas_modapi, Type); \
88 }
89
90#define EVAS_EINA_MODULE_DEFINE(Tn, Name) \
91 EINA_MODULE_INIT(evas_##Tn##_##Name##_init); \
92 EINA_MODULE_SHUTDOWN(evas_##Tn##_##Name##_shutdown);
93
94#endif /* _EVAS_MODULE_H */
diff --git a/src/lib/evas/file/evas_path.c b/src/lib/evas/file/evas_path.c
new file mode 100644
index 0000000000..2ff646dd64
--- /dev/null
+++ b/src/lib/evas/file/evas_path.c
@@ -0,0 +1,152 @@
1/* os dependent file code. for unix-y like fs's only for now */
2/* if your os doesn't use unix-like fs starting with "/" for the root and */
3/* the file path separator isn't "/" then you may need to help out by */
4/* adding in a new set of functions here */
5
6#ifdef HAVE_CONFIG_H
7# include <config.h>
8#endif
9
10#include <limits.h>
11#include <stdlib.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14/* get the casefold feature! */
15#include <fnmatch.h>
16#ifndef _MSC_VER
17# include <unistd.h>
18# include <sys/param.h>
19#endif
20
21#ifdef HAVE_EVIL
22# include <Evil.h>
23#endif
24
25#include "evas_common.h"
26#include "evas_private.h"
27
28#ifdef _WIN32
29# define EVAS_PATH_SEPARATOR "\\"
30#else
31# define EVAS_PATH_SEPARATOR "/"
32#endif
33
34int
35evas_file_path_is_full_path(const char *path)
36{
37 if (!path) return 0;
38#if defined _WIN32_WCE
39 if (path[0] == '\\') return 1;
40#elif defined _WIN32
41 if (evil_path_is_absolute(path)) return 1;
42#else
43 if (path[0] == '/') return 1;
44#endif
45 return 0;
46}
47
48char *
49evas_file_path_join(const char *path, const char *end)
50{
51 char *res = NULL;
52 size_t len;
53
54 if ((!path) && (!end)) return NULL;
55 if (!path) return strdup(end);
56 if (!end) return strdup(path);
57 len = strlen(path);
58 len += strlen(end);
59 len += strlen(EVAS_PATH_SEPARATOR);
60 res = malloc(len + 1);
61 if (!res) return NULL;
62 strcpy(res, path);
63 strcat(res, EVAS_PATH_SEPARATOR);
64 strcat(res, end);
65 return res;
66}
67
68int
69evas_file_path_exists(const char *path)
70{
71 struct stat st;
72
73 if (!stat(path, &st)) return 1;
74 return 0;
75}
76
77int
78evas_file_path_is_file(const char *path)
79{
80 struct stat st;
81
82 if (stat(path, &st) == -1) return 0;
83 if (S_ISREG(st.st_mode)) return 1;
84 return 0;
85}
86
87int
88evas_file_path_is_dir(const char *path)
89{
90 struct stat st;
91
92 if (stat(path, &st) == -1) return 0;
93 if (S_ISDIR(st.st_mode)) return 1;
94 return 0;
95}
96
97Eina_List *
98evas_file_path_list(char *path, const char *match, int match_case)
99{
100 Eina_File_Direct_Info *info;
101 Eina_Iterator *it;
102 Eina_List *files = NULL;
103 int flags;
104
105 flags = FNM_PATHNAME;
106#ifdef FNM_CASEFOLD
107 if (!match_case)
108 flags |= FNM_CASEFOLD;
109#else
110/*#warning "Your libc does not provide case-insensitive matching!"*/
111#endif
112
113 it = eina_file_direct_ls(path);
114 EINA_ITERATOR_FOREACH(it, info)
115 {
116 if (match)
117 {
118 if (fnmatch(match, info->path + info->name_start, flags) == 0)
119 files = eina_list_append(files, strdup(info->path + info->name_start));
120 }
121 else
122 files = eina_list_append(files, strdup(info->path + info->name_start));
123 }
124 if (it) eina_iterator_free(it);
125 return files;
126}
127
128DATA64
129evas_file_modified_time(const char *file)
130{
131 struct stat st;
132
133 if (stat(file, &st) < 0) return 0;
134 if (st.st_ctime > st.st_mtime) return (DATA64)st.st_ctime;
135 else return (DATA64)st.st_mtime;
136 return 0;
137}
138
139char *
140evas_file_path_resolve(const char *file)
141{
142#if 0
143 char buf[PATH_MAX], *buf2;
144#endif
145
146 return strdup(file);
147#if 0
148 if (!realpath(file, buf)) return NULL;
149 buf2 = strdup(buf);
150 return buf2;
151#endif
152}
diff --git a/src/lib/evas/file/evas_path.h b/src/lib/evas/file/evas_path.h
new file mode 100644
index 0000000000..e0aa6bb4d0
--- /dev/null
+++ b/src/lib/evas/file/evas_path.h
@@ -0,0 +1,15 @@
1#ifndef _EVAS_PATH_H
2#define _EVAS_PATH_H
3
4
5int evas_file_path_is_full_path (const char *path);
6char *evas_file_path_join (const char *path, const char *end);
7int evas_file_path_exists (const char *path);
8int evas_file_path_is_file (const char *path);
9int evas_file_path_is_dir (const char *path);
10Eina_List *evas_file_path_list (char *path, const char *match, int match_case);
11DATA64 evas_file_modified_time (const char *file);
12char *evas_file_path_resolve (const char *file);
13
14
15#endif /* _EVAS_PATH_H */