svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_imf / ecore_imf_module.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <limits.h>
13
14 #include <Ecore.h>
15 #include <ecore_private.h>
16
17 #include "Ecore_IMF.h"
18 #include "ecore_imf_private.h"
19
20 static void _ecore_imf_module_free(Ecore_IMF_Module *module);
21 static int _ecore_imf_modules_exists(const char *ctx_id);
22
23 typedef struct _Ecore_IMF_Selector
24 {
25   const char    *toselect;
26   void          *selected;
27 } Ecore_IMF_Selector;
28
29 static Eina_Hash *modules = NULL;
30 static Eina_Array *module_list = NULL;
31
32 void
33 ecore_imf_module_init(void)
34 {
35    char *homedir;
36
37    module_list = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/ecore/immodules", 0, NULL, NULL);
38    homedir = eina_module_environment_path_get("HOME", "/.ecore/immodules");
39    if (homedir)
40      {
41         module_list = eina_module_list_get(module_list, homedir, 0, NULL, NULL);
42         free(homedir);
43      }
44    eina_module_list_load(module_list);
45 }
46
47 void
48 ecore_imf_module_shutdown(void)
49 {
50    if (modules)
51      {
52         eina_hash_free(modules);
53         modules = NULL;
54      }
55    if (module_list)
56      {
57         eina_module_list_free(module_list);
58         modules = NULL;
59      }
60 }
61
62 static Eina_Bool
63 _hash_module_available_get(const Eina_Hash *hash __UNUSED__, int *data, void *list)
64 {
65   *(Eina_List**)list = eina_list_append(*(Eina_List**)list, data);
66   return EINA_TRUE;
67 }
68
69 Eina_List *
70 ecore_imf_module_available_get(void)
71 {
72    Eina_List *values = NULL;
73    Eina_Iterator *it = NULL;
74
75    if (!modules) return NULL;
76
77    it = eina_hash_iterator_data_new(modules);
78    if (!it)
79        return NULL;
80
81    eina_iterator_foreach(it, EINA_EACH(_hash_module_available_get), &values);
82    eina_iterator_free(it);
83
84    return values;
85 }
86
87 Ecore_IMF_Module *
88 ecore_imf_module_get(const char *ctx_id)
89 {
90    if (!modules) return NULL;
91    return eina_hash_find(modules, ctx_id);
92 }
93
94 Ecore_IMF_Context *
95 ecore_imf_module_context_create(const char *ctx_id)
96 {
97    Ecore_IMF_Module *module;
98    Ecore_IMF_Context *ctx = NULL;
99
100    if (!modules) return NULL;
101    module = eina_hash_find(modules, ctx_id);
102    if (module)
103      {
104         ctx = module->create();
105         if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
106           {
107              ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
108                               "ecore_imf_module_context_create");
109              return NULL;
110           }
111         ctx->module = module;
112      }
113    return ctx;
114 }
115
116 static Eina_Bool
117 _hash_ids_get(const Eina_Hash *hash __UNUSED__, const char *key, void *list)
118 {
119   *(Eina_List**)list = eina_list_append(*(Eina_List**)list, key);
120   return EINA_TRUE;
121 }
122
123 Eina_List *
124 ecore_imf_module_context_ids_get(void)
125 {
126    Eina_List *l = NULL;
127    Eina_Iterator *it = NULL;
128
129    if (!modules) return NULL;
130
131    it = eina_hash_iterator_key_new(modules);
132    if (!it)
133        return NULL;
134
135    eina_iterator_foreach(it, EINA_EACH(_hash_ids_get), &l);
136    eina_iterator_free(it);
137
138    return l;
139 }
140
141 static Eina_Bool
142 _hash_ids_by_canvas_type_get(const Eina_Hash *hash __UNUSED__, void *data, void *fdata)
143 {
144    Ecore_IMF_Module *module = data;
145    Ecore_IMF_Selector *selector = fdata;
146
147    if (!strcmp(module->info->canvas_type, selector->toselect))
148      selector->selected = eina_list_append(selector->selected, (void *)module->info->id);
149
150    return EINA_TRUE;
151 }
152
153 Eina_List *
154 ecore_imf_module_context_ids_by_canvas_type_get(const char *canvas_type)
155 {
156    Ecore_IMF_Selector selector;
157    Eina_List *values = NULL;
158    Eina_Iterator *it = NULL;
159
160    if (!modules) return NULL;
161
162    if (!canvas_type)
163      return ecore_imf_module_context_ids_get();
164
165    it = eina_hash_iterator_data_new(modules);
166    if (!it)
167        return NULL;
168
169    selector.toselect = canvas_type;
170    selector.selected = values;
171    eina_iterator_foreach(it, EINA_EACH(_hash_ids_by_canvas_type_get), &selector);
172    eina_iterator_free(it);
173
174    return values;
175 }
176
177 EAPI void
178 ecore_imf_module_register(const Ecore_IMF_Context_Info *info,
179                           Ecore_IMF_Context *(*imf_module_create)(void),
180                           Ecore_IMF_Context *(*imf_module_exit)(void))
181 {
182    Ecore_IMF_Module *module;
183
184    if (_ecore_imf_modules_exists(info->id)) return;
185
186    if (!modules)
187      modules = eina_hash_string_superfast_new(EINA_FREE_CB(_ecore_imf_module_free));
188
189    module = malloc(sizeof(Ecore_IMF_Module));
190    module->info = info;
191    /* cache imf_module_create as it may be used several times */
192    module->create = imf_module_create;
193    module->exit = imf_module_exit;
194
195    eina_hash_add(modules, info->id, module);
196 }
197
198 static void
199 _ecore_imf_module_free(Ecore_IMF_Module *module)
200 {
201    if (module->exit) module->exit();
202    free(module);
203 }
204
205 static int
206 _ecore_imf_modules_exists(const char *ctx_id)
207 {
208    if (!modules) return 0;
209    if (!ctx_id) return 0;
210
211    if (eina_hash_find(modules, ctx_id))
212      return 1;
213
214    return 0;
215 }