#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "Ecore_IMF.h" #include "ecore_imf_private.h" static void _ecore_imf_module_free(Ecore_IMF_Module *module); static int _ecore_imf_modules_exists(const char *ctx_id); typedef struct _Ecore_IMF_Selector { const char *toselect; void *selected; } Ecore_IMF_Selector; static Eina_Hash *modules = NULL; static Eina_Array *module_list = NULL; void ecore_imf_module_init(void) { char *homedir; module_list = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/ecore/immodules", 0, NULL, NULL); homedir = eina_module_environment_path_get("HOME", "/.ecore/immodules"); if (homedir) { module_list = eina_module_list_get(module_list, homedir, 0, NULL, NULL); free(homedir); } eina_module_list_load(module_list); } void ecore_imf_module_shutdown(void) { if (modules) { eina_hash_free(modules); modules = NULL; } if (module_list) { eina_module_list_free(module_list); module_list = NULL; } } static Eina_Bool _hash_module_available_get(const Eina_Hash *hash __UNUSED__, int *data, void *list) { *(Eina_List**)list = eina_list_append(*(Eina_List**)list, data); return EINA_TRUE; } Eina_List * ecore_imf_module_available_get(void) { Eina_List *values = NULL; Eina_Iterator *it = NULL; if (!modules) return NULL; it = eina_hash_iterator_data_new(modules); if (!it) return NULL; eina_iterator_foreach(it, EINA_EACH(_hash_module_available_get), &values); eina_iterator_free(it); return values; } Ecore_IMF_Module * ecore_imf_module_get(const char *ctx_id) { if (!modules) return NULL; return eina_hash_find(modules, ctx_id); } Ecore_IMF_Context * ecore_imf_module_context_create(const char *ctx_id) { Ecore_IMF_Module *module; Ecore_IMF_Context *ctx = NULL; if (!modules) return NULL; module = eina_hash_find(modules, ctx_id); if (module) { ctx = module->create(); if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, "ecore_imf_module_context_create"); return NULL; } ctx->module = module; } return ctx; } static Eina_Bool _hash_ids_get(const Eina_Hash *hash __UNUSED__, const char *key, void *list) { *(Eina_List**)list = eina_list_append(*(Eina_List**)list, key); return EINA_TRUE; } Eina_List * ecore_imf_module_context_ids_get(void) { Eina_List *l = NULL; Eina_Iterator *it = NULL; if (!modules) return NULL; it = eina_hash_iterator_key_new(modules); if (!it) return NULL; eina_iterator_foreach(it, EINA_EACH(_hash_ids_get), &l); eina_iterator_free(it); return l; } static Eina_Bool _hash_ids_by_canvas_type_get(const Eina_Hash *hash __UNUSED__, void *data, void *fdata) { Ecore_IMF_Module *module = data; Ecore_IMF_Selector *selector = fdata; if (!strcmp(module->info->canvas_type, selector->toselect)) selector->selected = eina_list_append(selector->selected, (void *)module->info->id); return EINA_TRUE; } Eina_List * ecore_imf_module_context_ids_by_canvas_type_get(const char *canvas_type) { Ecore_IMF_Selector selector; Eina_List *values = NULL; Eina_Iterator *it = NULL; if (!modules) return NULL; if (!canvas_type) return ecore_imf_module_context_ids_get(); it = eina_hash_iterator_data_new(modules); if (!it) return NULL; selector.toselect = canvas_type; selector.selected = values; eina_iterator_foreach(it, EINA_EACH(_hash_ids_by_canvas_type_get), &selector); eina_iterator_free(it); return values; } EAPI void ecore_imf_module_register(const Ecore_IMF_Context_Info *info, Ecore_IMF_Context *(*imf_module_create)(void), Ecore_IMF_Context *(*imf_module_exit)(void)) { Ecore_IMF_Module *module; if (_ecore_imf_modules_exists(info->id)) return; if (!modules) modules = eina_hash_string_superfast_new(EINA_FREE_CB(_ecore_imf_module_free)); module = malloc(sizeof(Ecore_IMF_Module)); module->info = info; /* cache imf_module_create as it may be used several times */ module->create = imf_module_create; module->exit = imf_module_exit; eina_hash_add(modules, info->id, module); } static void _ecore_imf_module_free(Ecore_IMF_Module *module) { if (module->exit) module->exit(); free(module); } static int _ecore_imf_modules_exists(const char *ctx_id) { if (!modules) return 0; if (!ctx_id) return 0; if (eina_hash_find(modules, ctx_id)) return 1; return 0; }