5 * * add module types/classes
6 * * add list of exclusions that a module can't work withApi
10 /* local subsystem functions */
11 static void _e_module_free(E_Module *m);
12 static void _e_module_dialog_disable_show(const char *title, const char *body, E_Module *m);
13 static void _e_module_cb_dialog_disable(void *data, E_Dialog *dia);
14 static void _e_module_event_update_free(void *data, void *event);
15 static Eina_Bool _e_module_cb_idler(void *data);
16 static int _e_module_sort_priority(const void *d1, const void *d2);
18 /* local subsystem globals */
19 static Eina_List *_e_modules = NULL;
20 static Ecore_Idle_Enterer *_e_module_idler = NULL;
21 static Eina_List *_e_modules_delayed = NULL;
23 EAPI int E_EVENT_MODULE_UPDATE = 0;
24 EAPI int E_EVENT_MODULE_INIT_END = 0;
26 /* externally accessible functions */
30 E_EVENT_MODULE_UPDATE = ecore_event_type_new();
31 E_EVENT_MODULE_INIT_END = ecore_event_type_new();
36 e_module_shutdown(void)
41 /* do a leak check now before we dlclose() all those plugins, cause
42 * that means we won't get a decent backtrace to leaks in there
44 VALGRIND_DO_LEAK_CHECK
47 /* do not use EINA_LIST_FREE! e_object_del modifies list */
55 if ((m) && (m->enabled) && !(m->error))
61 e_object_del(E_OBJECT(m));
69 e_module_all_load(void)
76 eina_list_sort(e_config->modules, 0, _e_module_sort_priority);
78 EINA_LIST_FOREACH(e_config->modules, l, em)
81 printf ("[E17_MODULE_INFO] NAME:%s, ENABLE:%d, DELAYED:%d\n", em->name, em->enabled, em->delayed);
83 if ((em->delayed) && (em->enabled))
86 _e_module_idler = ecore_idle_enterer_add(_e_module_cb_idler, NULL);
88 eina_list_append(_e_modules_delayed,
89 eina_stringshare_add(em->name));
95 if (!em->name) continue;
97 e_util_env_set("E_MODULE_LOAD", em->name);
98 snprintf(buf, sizeof(buf), _("Loading Module: %s"), em->name);
99 e_init_status_set(buf);
101 m = e_module_new(em->name);
102 if (m) e_module_enable(m);
106 if (!_e_modules_delayed)
107 ecore_event_add(E_EVENT_MODULE_INIT_END, NULL, NULL, NULL);
109 unsetenv("E_MODULE_LOAD");
113 e_module_new(const char *name)
117 char body[4096], title[1024];
124 if (!name) return NULL;
125 m = E_OBJECT_ALLOC(E_Module, E_MODULE_TYPE, _e_module_free);
128 snprintf(buf, sizeof(buf), "%s/%s/module.so", name, MODULE_ARCH);
129 modpath = e_path_find(path_modules, buf);
132 modpath = eina_stringshare_add(name);
135 snprintf(body, sizeof(body),
136 _("There was an error loading module named: %s<br>"
137 "No module named %s could be found in the<br>"
138 "module search directories.<br>"), name, buf);
139 _e_module_dialog_disable_show(_("Error loading Module"), body, m);
143 m->handle = dlopen(modpath, (RTLD_NOW | RTLD_GLOBAL));
146 snprintf(body, sizeof(body),
147 _("There was an error loading module named: %s<br>"
148 "The full path to this module is:<br>"
150 "The error reported was:<br>"
151 "%s<br>"), name, buf, dlerror());
152 _e_module_dialog_disable_show(_("Error loading Module"), body, m);
156 m->api = dlsym(m->handle, "e_modapi");
157 m->func.init = dlsym(m->handle, "e_modapi_init");
158 m->func.shutdown = dlsym(m->handle, "e_modapi_shutdown");
159 m->func.save = dlsym(m->handle, "e_modapi_save");
161 if ((!m->func.init) || (!m->func.shutdown) || (!m->func.save) || (!m->api))
163 snprintf(body, sizeof(body),
164 _("There was an error loading module named: %s<br>"
165 "The full path to this module is:<br>"
167 "The error reported was:<br>"
169 name, buf, _("Module does not contain all needed functions"));
170 _e_module_dialog_disable_show(_("Error loading Module"), body, m);
173 m->func.shutdown = NULL;
181 if (m->api->version < E_MODULE_API_VERSION)
183 snprintf(body, sizeof(body),
184 _("Module API Error<br>Error initializing Module: %s<br>"
185 "It requires a minimum module API version of: %i.<br>"
186 "The module API advertized by Enlightenment is: %i.<br>"),
187 _(m->api->name), m->api->version, E_MODULE_API_VERSION);
189 snprintf(title, sizeof(title), _("Enlightenment %s Module"),
192 _e_module_dialog_disable_show(title, body, m);
195 m->func.shutdown = NULL;
205 _e_modules = eina_list_append(_e_modules, m);
206 m->name = eina_stringshare_add(name);
209 s = ecore_file_dir_get(modpath);
214 s2 = ecore_file_dir_get(s);
218 m->dir = eina_stringshare_add(s2);
223 EINA_LIST_FOREACH(e_config->modules, l, em)
226 if (em->name == m->name)
234 E_Config_Module *module;
236 module = E_NEW(E_Config_Module, 1);
237 module->name = eina_stringshare_add(m->name);
239 e_config->modules = eina_list_append(e_config->modules, module);
240 e_config_save_queue();
242 if (modpath) eina_stringshare_del(modpath);
247 e_module_save(E_Module *m)
249 E_OBJECT_CHECK_RETURN(m, 0);
250 E_OBJECT_TYPE_CHECK_RETURN(m, E_MODULE_TYPE, 0);
251 if ((!m->enabled) || (m->error)) return 0;
252 return m->func.save(m);
256 e_module_dir_get(E_Module *m)
258 E_OBJECT_CHECK_RETURN(m, NULL);
259 E_OBJECT_TYPE_CHECK_RETURN(m, E_MODULE_TYPE, 0);
264 e_module_enable(E_Module *m)
267 E_Event_Module_Update *ev;
270 E_OBJECT_CHECK_RETURN(m, 0);
271 E_OBJECT_TYPE_CHECK_RETURN(m, E_MODULE_TYPE, 0);
272 if ((m->enabled) || (m->error)) return 0;
273 m->data = m->func.init(m);
277 EINA_LIST_FOREACH(e_config->modules, l, em)
280 if (!e_util_strcmp(em->name, m->name))
283 e_config_save_queue();
285 ev = E_NEW(E_Event_Module_Update, 1);
286 ev->name = strdup(em->name);
288 ecore_event_add(E_EVENT_MODULE_UPDATE, ev,
289 _e_module_event_update_free, NULL);
299 e_module_disable(E_Module *m)
301 E_Event_Module_Update *ev;
306 E_OBJECT_CHECK_RETURN(m, 0);
307 E_OBJECT_TYPE_CHECK_RETURN(m, E_MODULE_TYPE, 0);
308 if ((!m->enabled) || (m->error)) return 0;
309 ret = m->func.shutdown(m);
312 EINA_LIST_FOREACH(e_config->modules, l, em)
315 if (!e_util_strcmp(em->name, m->name))
318 e_config_save_queue();
320 ev = E_NEW(E_Event_Module_Update, 1);
321 ev->name = strdup(em->name);
323 ecore_event_add(E_EVENT_MODULE_UPDATE, ev,
324 _e_module_event_update_free, NULL);
332 e_module_enabled_get(E_Module *m)
334 E_OBJECT_CHECK_RETURN(m, 0);
335 E_OBJECT_TYPE_CHECK_RETURN(m, E_MODULE_TYPE, 0);
340 e_module_save_all(void)
346 EINA_LIST_FOREACH(_e_modules, l, m)
347 e_object_ref(E_OBJECT(m));
348 EINA_LIST_FOREACH(_e_modules, l, m)
349 if ((m->enabled) && (!m->error))
351 if (!m->func.save(m)) ret = 0;
353 EINA_LIST_FOREACH(_e_modules, l, m)
354 e_object_unref(E_OBJECT(m));
359 e_module_find(const char *name)
364 if (!name) return NULL;
365 EINA_LIST_FOREACH(_e_modules, l, m)
366 if (!e_util_strcmp(name, m->name)) return m;
377 e_module_dialog_show(E_Module *m, const char *title, const char *body)
382 const char *icon = NULL;
384 dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
385 "E", "_module_dialog");
388 e_dialog_title_set(dia, title);
391 Efreet_Desktop *desktop;
393 snprintf(buf, sizeof(buf), "%s/module.desktop", e_module_dir_get(m));
395 desktop = efreet_desktop_new(buf);
396 if ((desktop) && (desktop->icon))
398 icon = efreet_icon_path_find(e_config->icon_theme, desktop->icon, 64);
401 snprintf(buf, sizeof(buf), "%s/%s.edj",
402 e_module_dir_get(m), desktop->icon);
403 dia->icon_object = e_util_icon_add(buf, e_win_evas_get(dia->win));
406 dia->icon_object = e_util_icon_add(icon, e_win_evas_get(dia->win));
407 edje_extern_object_min_size_set(dia->icon_object, 64, 64);
408 edje_object_part_swallow(dia->bg_object, "e.swallow.icon", dia->icon_object);
409 evas_object_show(dia->icon_object);
411 if (desktop) efreet_desktop_free(desktop);
414 e_dialog_icon_set(dia, "preferences-plugin", 64);
416 e_dialog_text_set(dia, body);
417 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
418 e_dialog_button_focus_num(dia, 0);
419 e_win_centered_set(dia->win, 1);
422 bd = dia->win->border;
424 bd->internal_icon = eina_stringshare_add(icon);
428 e_module_delayed_set(E_Module *m, int delayed)
433 EINA_LIST_FOREACH(e_config->modules, l, em)
436 if (!e_util_strcmp(m->name, em->name))
438 if (em->delayed != delayed)
440 em->delayed = delayed;
441 e_config_save_queue();
449 e_module_priority_set(E_Module *m, int priority)
451 /* Set the loading order for a module.
452 More priority means load earlier */
456 EINA_LIST_FOREACH(e_config->modules, l, em)
459 if (!e_util_strcmp(m->name, em->name))
461 if (em->priority != priority)
463 em->priority = priority;
464 e_config_save_queue();
471 /* local subsystem functions */
474 _e_module_free(E_Module *m)
479 EINA_LIST_FOREACH(e_config->modules, l, em)
482 if (!e_util_strcmp(em->name, m->name))
484 e_config->modules = eina_list_remove(e_config->modules, em);
485 if (em->name) eina_stringshare_del(em->name);
491 if ((m->enabled) && (!m->error))
496 if (m->name) eina_stringshare_del(m->name);
497 if (m->dir) eina_stringshare_del(m->dir);
498 // if (m->handle) dlclose(m->handle); DONT dlclose! causes problems with deferred callbacks for free etc. - when their code goes away!
499 _e_modules = eina_list_remove(_e_modules, m);
503 #if _F_USE_EXTN_DIALOG_
505 _e_module_dialog_disable_show(const char *title,
507 E_Module *m __UNUSED__)
509 printf("MODULE ERR:\n%s\n", body);
510 e_util_extn_dialog_show(title, body);
514 _e_module_dialog_disable_show(const char *title, const char *body, E_Module *m)
519 printf("MODULE ERR:\n%s\n", body);
520 dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
521 "E", "_module_unload_dialog");
524 snprintf(buf, sizeof(buf), "%s<br>%s", body,
525 _("What action should be taken with this module?<br>"));
527 e_dialog_title_set(dia, title);
528 e_dialog_icon_set(dia, "enlightenment", 64);
529 e_dialog_text_set(dia, buf);
530 e_dialog_button_add(dia, _("Unload"), NULL, _e_module_cb_dialog_disable, m);
531 e_dialog_button_add(dia, _("Keep"), NULL, NULL, NULL);
532 e_win_centered_set(dia->win, 1);
538 _e_module_cb_dialog_disable(void *data, E_Dialog *dia)
544 e_object_del(E_OBJECT(m));
545 e_object_del(E_OBJECT(dia));
546 e_config_save_queue();
550 _e_module_cb_idler(void *data __UNUSED__)
552 if (_e_modules_delayed)
557 name = eina_list_data_get(_e_modules_delayed);
559 eina_list_remove_list(_e_modules_delayed, _e_modules_delayed);
561 if (name) m = e_module_new(name);
564 #ifndef E17_RELEASE_BUILD
566 snprintf(buf, sizeof(buf), "DELAYED MODULE LOAD: %s", name);
571 eina_stringshare_del(name);
573 if (_e_modules_delayed)
576 return ECORE_CALLBACK_RENEW;
579 ecore_event_add(E_EVENT_MODULE_INIT_END, NULL, NULL, NULL);
581 _e_module_idler = NULL;
582 return ECORE_CALLBACK_CANCEL;
586 _e_module_sort_priority(const void *d1, const void *d2)
588 const E_Config_Module *m1, *m2;
592 return m2->priority - m1->priority;
596 _e_module_event_update_free(void *data __UNUSED__, void *event)
598 E_Event_Module_Update *ev;
600 if (!(ev = event)) return;