2007-11-19 10:27:11 -08:00
|
|
|
/*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
|
|
|
|
2009-01-31 10:33:39 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2009-01-31 10:33:39 -08:00
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
2007-11-19 10:27:11 -08:00
|
|
|
|
|
|
|
#include "ecore_imf_private.h"
|
|
|
|
|
|
|
|
static void _ecore_imf_module_load_all(void);
|
|
|
|
static void _ecore_imf_module_append(Ecore_Plugin *plugin, const Ecore_IMF_Context_Info *info, Ecore_IMF_Context *(*imf_module_create)(void));
|
|
|
|
static void _ecore_imf_module_free(Ecore_IMF_Module *module);
|
|
|
|
static int _ecore_imf_modules_exists(const char *ctx_id);
|
|
|
|
|
2008-12-11 05:55:47 -08:00
|
|
|
typedef struct _Ecore_IMF_Selector
|
|
|
|
{
|
|
|
|
const char *toselect;
|
|
|
|
void *selected;
|
|
|
|
} Ecore_IMF_Selector;
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
static Ecore_Path_Group *ecore_imf_modules_path = NULL;
|
2008-12-11 05:55:47 -08:00
|
|
|
static Eina_Hash *modules = NULL;
|
2007-11-19 10:27:11 -08:00
|
|
|
|
|
|
|
void
|
|
|
|
ecore_imf_module_init(void)
|
|
|
|
{
|
|
|
|
char pathname[PATH_MAX];
|
|
|
|
const char *homedir;
|
|
|
|
|
|
|
|
ecore_imf_modules_path = ecore_path_group_new();
|
|
|
|
snprintf(pathname, sizeof(pathname), "%s/ecore/immodules/",
|
|
|
|
PACKAGE_LIB_DIR);
|
|
|
|
ecore_path_group_add(ecore_imf_modules_path, pathname);
|
|
|
|
|
|
|
|
homedir = getenv("HOME");
|
|
|
|
if (homedir)
|
|
|
|
{
|
|
|
|
snprintf(pathname, sizeof(pathname), "%s/.ecore/immodules/",
|
|
|
|
homedir);
|
|
|
|
ecore_path_group_add(ecore_imf_modules_path, pathname);
|
|
|
|
}
|
|
|
|
|
|
|
|
modules = NULL;
|
|
|
|
_ecore_imf_module_load_all();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ecore_imf_module_shutdown(void)
|
|
|
|
{
|
|
|
|
if (modules)
|
|
|
|
{
|
2008-12-11 05:55:47 -08:00
|
|
|
eina_hash_free(modules);
|
2007-11-19 10:27:11 -08:00
|
|
|
modules = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ecore_path_group_del(ecore_imf_modules_path);
|
|
|
|
ecore_imf_modules_path = NULL;
|
|
|
|
}
|
|
|
|
|
2008-12-11 05:55:47 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_hash_module_available_get(const Eina_Hash *hash, int *data, void *list)
|
|
|
|
{
|
|
|
|
ecore_list_append(list, data);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
Ecore_List *
|
|
|
|
ecore_imf_module_available_get(void)
|
|
|
|
{
|
|
|
|
Ecore_List *values;
|
2008-12-11 05:55:47 -08:00
|
|
|
Eina_Iterator *it = NULL;
|
2007-11-19 10:27:11 -08:00
|
|
|
|
|
|
|
if (!modules) return NULL;
|
|
|
|
|
|
|
|
values = ecore_list_new();
|
2008-12-11 05:55:47 -08:00
|
|
|
if (!values) return NULL;
|
2007-11-19 10:27:11 -08:00
|
|
|
|
2008-12-11 05:55:47 -08:00
|
|
|
it = eina_hash_iterator_data_new(modules);
|
|
|
|
if (!it)
|
|
|
|
{
|
|
|
|
ecore_list_destroy(values);
|
|
|
|
return NULL;
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|
2008-12-11 05:55:47 -08:00
|
|
|
|
|
|
|
eina_iterator_foreach(it, EINA_EACH(_hash_module_available_get), values);
|
|
|
|
eina_iterator_free(it);
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
ecore_list_first_goto(values);
|
|
|
|
|
|
|
|
return values;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ecore_IMF_Module *
|
|
|
|
ecore_imf_module_get(const char *ctx_id)
|
|
|
|
{
|
|
|
|
if (!modules) return NULL;
|
2008-12-11 05:55:47 -08:00
|
|
|
return eina_hash_find(modules, ctx_id);
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Ecore_IMF_Context *
|
|
|
|
ecore_imf_module_context_create(const char *ctx_id)
|
|
|
|
{
|
|
|
|
Ecore_IMF_Module *module;
|
2007-11-21 14:20:16 -08:00
|
|
|
Ecore_IMF_Context *ctx = NULL;
|
2007-11-19 10:27:11 -08:00
|
|
|
|
|
|
|
if (!modules) return NULL;
|
2008-12-11 05:55:47 -08:00
|
|
|
module = eina_hash_find(modules, ctx_id);
|
2007-11-21 14:20:16 -08:00
|
|
|
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;
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|
|
|
|
|
2008-12-11 05:55:47 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_hash_ids_get(const Eina_Hash *hash, const char *key, void *list)
|
|
|
|
{
|
|
|
|
ecore_list_append(list, key);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
Ecore_List *
|
|
|
|
ecore_imf_module_context_ids_get(void)
|
|
|
|
{
|
2008-12-11 05:55:47 -08:00
|
|
|
Ecore_List *l = NULL;
|
|
|
|
Eina_Iterator *it = NULL;
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
if (!modules) return NULL;
|
2008-12-11 05:55:47 -08:00
|
|
|
|
|
|
|
l = ecore_list_new();
|
|
|
|
if (!l) return NULL;
|
|
|
|
|
|
|
|
it = eina_hash_iterator_key_new(modules);
|
|
|
|
if (!it)
|
|
|
|
{
|
|
|
|
ecore_list_destroy(l);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_iterator_foreach(it, EINA_EACH(_hash_ids_get), l);
|
|
|
|
eina_iterator_free(it);
|
|
|
|
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2008-12-15 12:52:51 -08:00
|
|
|
_hash_ids_by_canvas_type_get(const Eina_Hash *hash, void *data, void *fdata)
|
2008-12-11 05:55:47 -08:00
|
|
|
{
|
|
|
|
Ecore_IMF_Module *module = data;
|
|
|
|
Ecore_IMF_Selector *selector = fdata;
|
|
|
|
|
|
|
|
if (!strcmp(module->info->canvas_type, selector->toselect))
|
|
|
|
ecore_list_append(selector->selected, (void *)module->info->id);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|
|
|
|
|
2007-11-21 14:20:16 -08:00
|
|
|
Ecore_List *
|
|
|
|
ecore_imf_module_context_ids_by_canvas_type_get(const char *canvas_type)
|
|
|
|
{
|
2008-12-11 05:55:47 -08:00
|
|
|
Ecore_IMF_Selector selector;
|
2007-11-21 14:20:16 -08:00
|
|
|
Ecore_List *values;
|
2008-12-11 05:55:47 -08:00
|
|
|
Eina_Iterator *it = NULL;
|
2007-11-21 14:20:16 -08:00
|
|
|
|
|
|
|
if (!modules) return NULL;
|
|
|
|
|
|
|
|
if (!canvas_type)
|
|
|
|
return ecore_imf_module_context_ids_get();
|
|
|
|
|
|
|
|
values = ecore_list_new();
|
2008-12-11 05:55:47 -08:00
|
|
|
if (!values) return NULL;
|
|
|
|
|
|
|
|
it = eina_hash_iterator_data_new(modules);
|
|
|
|
if (!it)
|
2007-11-21 14:20:16 -08:00
|
|
|
{
|
2008-12-11 05:55:47 -08:00
|
|
|
ecore_list_destroy(values);
|
|
|
|
return NULL;
|
2007-11-21 14:20:16 -08:00
|
|
|
}
|
2008-12-11 05:55:47 -08:00
|
|
|
|
|
|
|
selector.toselect = canvas_type;
|
|
|
|
selector.selected = values;
|
|
|
|
eina_iterator_foreach(it, EINA_EACH(_hash_ids_by_canvas_type_get), &selector);
|
|
|
|
eina_iterator_free(it);
|
|
|
|
|
2007-11-21 14:20:16 -08:00
|
|
|
ecore_list_first_goto(values);
|
|
|
|
|
|
|
|
return values;
|
|
|
|
}
|
|
|
|
|
2007-11-19 10:27:11 -08:00
|
|
|
static void
|
|
|
|
_ecore_imf_module_load_all(void)
|
|
|
|
{
|
|
|
|
Ecore_List *avail;
|
|
|
|
char *filename;
|
|
|
|
Ecore_Plugin *plugin;
|
|
|
|
const Ecore_IMF_Context_Info *info = NULL;
|
|
|
|
int (*imf_module_init)(const Ecore_IMF_Context_Info **info);
|
|
|
|
Ecore_IMF_Context *(*imf_module_create)(void);
|
|
|
|
|
|
|
|
avail = ecore_plugin_available_get(ecore_imf_modules_path);
|
|
|
|
if (!avail) return;
|
|
|
|
|
|
|
|
ecore_list_first_goto(avail);
|
2007-11-22 03:55:35 -08:00
|
|
|
while ((filename = ecore_list_next(avail)))
|
2007-11-19 10:27:11 -08:00
|
|
|
{
|
|
|
|
plugin = ecore_plugin_load(ecore_imf_modules_path, filename, NULL);
|
|
|
|
if (!plugin)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "** ecore_imf: Error loading input method plugin %s!\n",
|
|
|
|
filename);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
imf_module_init = ecore_plugin_symbol_get(plugin, "imf_module_init");
|
|
|
|
if (!imf_module_init || !imf_module_init(&info) || !info)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "** ecore_imf: Error initializing input method plugin %s! "
|
|
|
|
"'imf_module_init' is missing or failed to run!",
|
|
|
|
filename);
|
|
|
|
ecore_plugin_unload(plugin);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_ecore_imf_modules_exists(info->id))
|
|
|
|
{
|
|
|
|
fprintf(stderr, "** ecore_imf: Error loading input method plugin %s! "
|
|
|
|
"Plugin with id='%s' already exists!",
|
2007-11-22 03:55:35 -08:00
|
|
|
filename, info->id);
|
2007-11-19 10:27:11 -08:00
|
|
|
ecore_plugin_unload(plugin);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
imf_module_create = ecore_plugin_symbol_get(plugin, "imf_module_create");
|
|
|
|
if (!imf_module_create)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "** ecore_imf: Error setting up input method plugin %s! "
|
|
|
|
"'imf_module_create' is missing!",
|
|
|
|
filename);
|
|
|
|
ecore_plugin_unload(plugin);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
_ecore_imf_module_append(plugin, info, imf_module_create);
|
|
|
|
}
|
|
|
|
|
|
|
|
ecore_list_destroy(avail);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_imf_module_append(Ecore_Plugin *plugin,
|
|
|
|
const Ecore_IMF_Context_Info *info,
|
|
|
|
Ecore_IMF_Context *(*imf_module_create)(void))
|
|
|
|
{
|
|
|
|
Ecore_IMF_Module *module;
|
|
|
|
|
|
|
|
if (!modules)
|
2008-12-11 05:55:47 -08:00
|
|
|
modules = eina_hash_string_superfast_new(_ecore_imf_module_free);
|
2007-11-19 10:27:11 -08:00
|
|
|
|
|
|
|
module = malloc(sizeof(Ecore_IMF_Module));
|
|
|
|
module->plugin = plugin;
|
|
|
|
module->info = info;
|
|
|
|
/* cache imf_module_create as it may be used several times */
|
|
|
|
module->create = imf_module_create;
|
|
|
|
|
2008-12-11 05:55:47 -08:00
|
|
|
eina_hash_add(modules, info->id, module);
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_imf_module_free(Ecore_IMF_Module *module)
|
|
|
|
{
|
|
|
|
int (*imf_module_exit)(void);
|
|
|
|
|
|
|
|
imf_module_exit = ecore_plugin_symbol_get(module->plugin, "imf_module_exit");
|
|
|
|
if (imf_module_exit) imf_module_exit();
|
|
|
|
ecore_plugin_unload(module->plugin);
|
|
|
|
free(module);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_ecore_imf_modules_exists(const char *ctx_id)
|
|
|
|
{
|
|
|
|
if (!modules) return 0;
|
2008-12-11 05:55:47 -08:00
|
|
|
if (!ctx_id) return 0;
|
|
|
|
|
|
|
|
if (eina_hash_find(modules, ctx_id))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
2007-11-19 10:27:11 -08:00
|
|
|
}
|