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