7 #include <evas_common.h>
8 #include <evas_private.h>
9 #include <evas_module.h>
21 static Eina_Hash *evas_modules[4] = {
28 static Eina_List *eina_evas_modules = NULL;
29 static Eina_List *evas_module_paths = NULL;
30 static Eina_Array *evas_engines = NULL;
33 _evas_module_append(Eina_List *list, char *path)
37 if (evas_file_path_exists(path))
38 list = eina_list_append(list, path);
45 /* this will alloc a list of paths to search for the modules */
46 /* by now these are: */
47 /* 1. ~/.evas/modules/ */
48 /* 2. $(EVAS_MODULE_DIR)/evas/modules/ */
49 /* 3. dladdr/evas/modules/ */
50 /* 4. PREFIX/evas/modules/ */
52 evas_module_paths_init(void)
59 /* 1. ~/.evas/modules/ */
60 path = eina_module_environment_path_get("HOME", "/.evas/modules");
61 evas_module_paths = _evas_module_append(evas_module_paths, path);
63 /* 2. $(EVAS_MODULE_DIR)/evas/modules/ */
64 path = eina_module_environment_path_get("EVAS_MODULES_DIR", "/evas/modules");
65 evas_module_paths = _evas_module_append(evas_module_paths, path);
67 /* 3. libevas.so/../evas/modules/ */
68 path2 = eina_module_symbol_path_get(evas_module_paths_init, "/evas/modules");
69 if (path2 && path && (strcmp(path, path2) == 0))
72 evas_module_paths = _evas_module_append(evas_module_paths, path2);
74 /* 4. PREFIX/evas/modules/ */
76 path3 = PACKAGE_LIB_DIR "/evas/modules";
77 if ((path && (strcmp(path, path3) != 0)) ||
78 (path2 && (strcmp(path2, path3) != 0)) ||
83 evas_module_paths = _evas_module_append(evas_module_paths, path);
88 #define EVAS_EINA_STATIC_MODULE_DEFINE(Tn, Name) \
89 Eina_Bool evas_##Tn##_##Name##_init(void); \
90 void evas_##Tn##_##Name##_shutdown(void);
92 #define EVAS_EINA_STATIC_MODULE_USE(Tn, Name) \
93 { evas_##Tn##_##Name##_init, evas_##Tn##_##Name##_shutdown }
95 EVAS_EINA_STATIC_MODULE_DEFINE(engine, buffer);
96 EVAS_EINA_STATIC_MODULE_DEFINE(engine, cairo_x11);
97 EVAS_EINA_STATIC_MODULE_DEFINE(engine, direct3d);
98 EVAS_EINA_STATIC_MODULE_DEFINE(engine, directfb);
99 EVAS_EINA_STATIC_MODULE_DEFINE(engine, fb);
100 EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_glew);
101 EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_x11);
102 EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_sdl);
103 EVAS_EINA_STATIC_MODULE_DEFINE(engine, quartz);
104 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16);
105 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_ddraw);
106 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_sdl);
107 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_wince);
108 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_x11);
109 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8);
110 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8_x11);
111 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_ddraw);
112 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_gdi);
113 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_generic);
114 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_qtopia);
115 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_sdl);
116 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_x11);
117 EVAS_EINA_STATIC_MODULE_DEFINE(engine, xrender_x11);
118 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
119 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, bmp);
120 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
121 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, svg);
122 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, png);
123 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, pmaps);
124 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, jpeg);
125 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, gif);
126 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, eet);
127 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, edb);
128 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tga);
129 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp);
130 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, edb);
131 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, eet);
132 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, jpeg);
133 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png);
134 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff);
136 static const struct {
137 Eina_Bool (*init)(void);
138 void (*shutdown)(void);
139 } evas_static_module[] = {
140 #ifdef EVAS_STATIC_BUILD_BUFFER
141 EVAS_EINA_STATIC_MODULE_USE(engine, buffer),
143 #ifdef EVAS_STATIC_BUILD_CAIRO_X11
144 EVAS_EINA_STATIC_MODULE_USE(engine, cairo_x11),
146 #ifdef EVAS_STATIC_BUILD_DIRECT3D
147 EVAS_EINA_STATIC_MODULE_USE(engine, direct3d),
149 #ifdef EVAS_STATIC_BUILD_DIRECTFB
150 EVAS_EINA_STATIC_MODULE_USE(engine, directfb),
152 #ifdef EVAS_STATIC_BUILD_FB
153 EVAS_EINA_STATIC_MODULE_USE(engine, fb),
155 #ifdef EVAS_STATIC_BUILD_GL_GLEW
156 EVAS_EINA_STATIC_MODULE_USE(engine, gl_glew),
158 #ifdef EVAS_STATIC_BUILD_GL_X11
159 EVAS_EINA_STATIC_MODULE_USE(engine, gl_x11),
161 #ifdef EVAS_STATIC_BUILD_GL_SDL
162 EVAS_EINA_STATIC_MODULE_USE(engine, gl_sdl),
164 #ifdef EVAS_STATIC_BUILD_QUARTZ
165 EVAS_EINA_STATIC_MODULE_USE(engine, quartz),
167 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16
168 EVAS_EINA_STATIC_MODULE_USE(engine, software_16),
170 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
171 EVAS_EINA_STATIC_MODULE_USE(engine, software_16_ddraw),
173 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_SDL
174 EVAS_EINA_STATIC_MODULE_USE(engine, software_16_sdl),
176 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
177 EVAS_EINA_STATIC_MODULE_USE(engine, software_16_wince),
179 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_X11
180 EVAS_EINA_STATIC_MODULE_USE(engine, software_16_x11),
182 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
183 EVAS_EINA_STATIC_MODULE_USE(engine, software_ddraw),
185 #ifdef EVAS_STATIC_BUILD_SOFTWARE_16_GDI
186 EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
188 #ifdef EVAS_STATIC_BUILD_SOFTWARE_8
189 EVAS_EINA_STATIC_MODULE_USE(engine, software_8),
191 #ifdef EVAS_STATIC_BUILD_SOFTWARE_8_X11
192 EVAS_EINA_STATIC_MODULE_USE(engine, software_8_x11),
194 #ifdef EVAS_STATIC_BUILD_SOFTWARE_GENERIC
195 EVAS_EINA_STATIC_MODULE_USE(engine, software_generic),
197 #ifdef EVAS_STATIC_BUILD_SOFTWARE_QTOPIA
198 EVAS_EINA_STATIC_MODULE_USE(engine, software_qtopia),
200 #ifdef EVAS_STATIC_BUILD_SOFTWARE_SDL
201 EVAS_EINA_STATIC_MODULE_USE(engine, software_sdl),
203 #ifdef EVAS_STATIC_BUILD_SOFTWARE_X11
204 EVAS_EINA_STATIC_MODULE_USE(engine, software_x11),
206 #ifdef EVAS_STATIC_BUILD_XRENDER_X11
207 EVAS_EINA_STATIC_MODULE_USE(engine, xrender_x11),
209 #ifdef EVAS_STATIC_BUILD_XPM
210 EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
212 #ifdef EVAS_STATIC_BUILD_BMP
213 EVAS_EINA_STATIC_MODULE_USE(image_loader, bmp),
215 #ifdef EVAS_STATIC_BUILD_TIFF
216 EVAS_EINA_STATIC_MODULE_USE(image_loader, tiff),
218 #ifdef EVAS_STATIC_BUILD_SVG
219 EVAS_EINA_STATIC_MODULE_USE(image_loader, svg),
221 #ifdef EVAS_STATIC_BUILD_PNG
222 EVAS_EINA_STATIC_MODULE_USE(image_loader, png),
224 #ifdef EVAS_STATIC_BUILD_PMAPS
225 EVAS_EINA_STATIC_MODULE_USE(image_loader, pmaps),
227 #ifdef EVAS_STATIC_BUILD_JPEG
228 EVAS_EINA_STATIC_MODULE_USE(image_loader, jpeg),
230 #ifdef EVAS_STATIC_BUILD_GIF
231 EVAS_EINA_STATIC_MODULE_USE(image_loader, gif),
233 #ifdef EVAS_STATIC_BUILD_EET
234 EVAS_EINA_STATIC_MODULE_USE(image_loader, eet),
236 #ifdef EVAS_STATIC_BUILD_EDB
237 EVAS_EINA_STATIC_MODULE_USE(image_loader, edb),
239 #ifdef EVAS_STATIC_BUILD_TGA
240 EVAS_EINA_STATIC_MODULE_USE(image_loader, tga),
242 #ifdef EVAS_STATIC_BUILD_WBMP
243 EVAS_EINA_STATIC_MODULE_USE(image_loader, wbmp),
245 #ifdef EVAS_STATIC_BUILD_EDB
246 EVAS_EINA_STATIC_MODULE_USE(image_saver, edb),
248 #ifdef EVAS_STATIC_BUILD_EET
249 EVAS_EINA_STATIC_MODULE_USE(image_saver, eet),
251 #ifdef EVAS_STATIC_BUILD_JPEG
252 EVAS_EINA_STATIC_MODULE_USE(image_saver, jpeg),
254 #ifdef EVAS_STATIC_BUILD_PNG
255 EVAS_EINA_STATIC_MODULE_USE(image_saver, png),
257 #ifdef EVAS_STATIC_BUILD_TIFF
258 EVAS_EINA_STATIC_MODULE_USE(image_saver, tiff),
263 /* this will alloc an Evas_Module struct for each module
264 * it finds on the paths */
266 evas_module_init(void)
270 evas_module_paths_init();
272 evas_modules[EVAS_MODULE_TYPE_ENGINE] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
273 evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
274 evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
275 evas_modules[EVAS_MODULE_TYPE_OBJECT] = eina_hash_string_small_new(/* FIXME: Add a function to cleanup stuff. */ NULL);
277 evas_engines = eina_array_new(4);
279 for (i = 0; evas_static_module[i].init; ++i)
280 evas_static_module[i].init();
284 evas_module_register(const Evas_Module_Api *module, Evas_Module_Type type)
288 if ((unsigned int)type > 3) return EINA_FALSE;
289 if (!module) return EINA_FALSE;
290 if (module->version != EVAS_MODULE_API_VERSION) return EINA_FALSE;
292 em = eina_hash_find(evas_modules[type], module->name);
293 if (em) return EINA_FALSE;
295 em = calloc(1, sizeof (Evas_Module));
296 if (!em) return EINA_FALSE;
298 em->definition = module;
300 if (type == EVAS_MODULE_TYPE_ENGINE)
302 eina_array_push(evas_engines, em);
303 em->id_engine = eina_array_count_get(evas_engines);
306 eina_hash_direct_add(evas_modules[type], module->name, em);
312 evas_module_unregister(const Evas_Module_Api *module, Evas_Module_Type type)
316 if ((unsigned int)type > 3) return EINA_FALSE;
317 if (!module) return EINA_FALSE;
319 em = eina_hash_find(evas_modules[type], module->name);
320 if (!em || em->definition != module) return EINA_FALSE;
322 if (type == EVAS_MODULE_TYPE_ENGINE)
323 eina_array_data_set(evas_engines, em->id_engine, NULL);
325 eina_hash_del(evas_modules[type], module->name, em);
331 #if defined(__CEGCC__) || defined(__MINGW32CE__)
332 # define EVAS_MODULE_NAME_IMAGE_SAVER "saver_%s.dll"
333 # define EVAS_MODULE_NAME_IMAGE_LOADER "loader_%s.dll"
334 # define EVAS_MODULE_NAME_ENGINE "engine_%s.dll"
335 # define EVAS_MODULE_NAME_OBJECT "object_%s.dll"
337 # define EVAS_MODULE_NAME_IMAGE_SAVER "module.dll"
338 # define EVAS_MODULE_NAME_IMAGE_LOADER "module.dll"
339 # define EVAS_MODULE_NAME_ENGINE "module.dll"
340 # define EVAS_MODULE_NAME_OBJECT "module.dll"
342 # define EVAS_MODULE_NAME_IMAGE_SAVER "module.so"
343 # define EVAS_MODULE_NAME_IMAGE_LOADER "module.so"
344 # define EVAS_MODULE_NAME_ENGINE "module.so"
345 # define EVAS_MODULE_NAME_OBJECT "module.so"
349 evas_module_find_type(Evas_Module_Type type, const char *name)
352 const char *format = NULL;
358 if ((unsigned int)type > 3) return NULL;
360 em = eina_hash_find(evas_modules[type], name);
363 EINA_LIST_FOREACH(evas_module_paths, l, path)
367 case EVAS_MODULE_TYPE_ENGINE: format = "%s/engines/%s/%s/" EVAS_MODULE_NAME_ENGINE; break;
368 case EVAS_MODULE_TYPE_IMAGE_LOADER: format = "%s/loaders/%s/%s/" EVAS_MODULE_NAME_IMAGE_LOADER; break;
369 case EVAS_MODULE_TYPE_IMAGE_SAVER: format = "%s/savers/%s/%s/" EVAS_MODULE_NAME_IMAGE_SAVER; break;
370 case EVAS_MODULE_TYPE_OBJECT: format = "%s/object/%s/%s/" EVAS_MODULE_NAME_OBJECT; break;
373 snprintf(buffer, sizeof (buffer), format, path, name, MODULE_ARCH, name);
374 if (!evas_file_path_is_file(buffer)) continue;
376 en = eina_module_new(buffer);
379 if (!eina_module_load(en))
381 eina_module_free(en);
385 em = eina_hash_find(evas_modules[type], name);
388 eina_evas_modules = eina_list_append(eina_evas_modules, en);
392 eina_module_free(en);
399 evas_module_engine_get(int render_method)
401 if ((render_method <= 0) ||
402 ((unsigned int)render_method > eina_array_count_get(evas_engines)))
404 return eina_array_data_get(evas_engines, render_method - 1);
408 evas_module_foreach_image_loader(Eina_Hash_Foreach cb, const void *fdata)
410 eina_hash_foreach(evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER], cb, fdata);
414 evas_module_load(Evas_Module *em)
416 if (em->loaded) return 1;
417 if (!em->definition) return 0;
419 if (!em->definition->func.open(em)) return 0;
422 #ifdef BUILD_ASYNC_PRELOAD
429 evas_module_unload(Evas_Module *em)
436 // for now lets not unload modules - they may still be in use.
437 // em->definition->func.close(em);
440 #ifdef BUILD_ASYNC_PRELOAD
446 evas_module_ref(Evas_Module *em)
448 #ifdef BUILD_ASYNC_PRELOAD
452 #ifdef BUILD_ASYNC_PRELOAD
458 evas_module_unref(Evas_Module *em)
460 #ifdef BUILD_ASYNC_PRELOAD
464 #ifdef BUILD_ASYNC_PRELOAD
469 static int use_count = 0;
472 evas_module_use(Evas_Module *em)
474 em->last_used = use_count;
478 evas_module_clean(void)
480 static int call_count = 0;
484 /* Evas_Module *em; */
486 /* only clean modules every 256 calls */
488 if (call_count <= 256) return;
493 if (getenv("EVAS_NOCLEAN"))
498 if (noclean == 1) return;
500 /* disable module cleaning for now - may cause instability with some modules */
503 /* FIXME: Don't know what it is supposed to do. */
504 /* /\* incriment use counter = 28bits *\/ */
506 /* if (use_count > 0x0fffffff) use_count = 0; */
508 /* /\* printf("CLEAN!\n"); *\/ */
509 /* /\* go through all modules *\/ */
510 /* EINA_LIST_FOREACH(evas_modules, l, em) */
512 /* /\* printf("M %s %i %i\n", em->name, em->ref, em->loaded); *\/ */
513 /* /\* if the module is refernced - skip *\/ */
514 /* if ((em->ref > 0) || (!em->loaded)) continue; */
515 /* /\* how many clean cycles ago was this module last used *\/ */
516 /* ago = use_count - em->last_used; */
517 /* if (em->last_used > use_count) ago += 0x10000000; */
518 /* /\* if it was used last more than N clean cycles ago - unload *\/ */
521 /* /\* printf(" UNLOAD %s\n", em->name); *\/ */
522 /* evas_module_unload(em); */
527 /* will dlclose all the modules loaded and free all the structs */
529 evas_module_shutdown(void)
535 for (i = 0; evas_static_module[i].shutdown; ++i)
536 evas_static_module[i].shutdown();
538 EINA_LIST_FREE(eina_evas_modules, en)
539 eina_module_free(en);
541 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_ENGINE]);
542 evas_modules[EVAS_MODULE_TYPE_ENGINE] = NULL;
543 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER]);
544 evas_modules[EVAS_MODULE_TYPE_IMAGE_LOADER] = NULL;
545 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER]);
546 evas_modules[EVAS_MODULE_TYPE_IMAGE_SAVER] = NULL;
547 eina_hash_free(evas_modules[EVAS_MODULE_TYPE_OBJECT]);
548 evas_modules[EVAS_MODULE_TYPE_OBJECT] = NULL;
550 EINA_LIST_FREE(evas_module_paths, path)
553 eina_array_free(evas_engines);
558 _evas_module_engine_inherit(Evas_Func *funcs, char *name)
562 em = evas_module_find_type(EVAS_MODULE_TYPE_ENGINE, name);
565 if (evas_module_load(em))
567 /* FIXME: no way to unref */
570 *funcs = *((Evas_Func *)(em->functions));