1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include <stdlib.h>
6 #include <string.h>
7 #include <locale.h>
8 
9 #include <Ecore.h>
10 #include <ecore_private.h>
11 
12 #include "Ecore_IMF.h"
13 #include "ecore_imf_private.h"
14 
15 Ecore_IMF_Context *show_req_ctx = NULL;
16 
17 EAPI Eina_List *
ecore_imf_context_available_ids_get(void)18 ecore_imf_context_available_ids_get(void)
19 {
20    return ecore_imf_module_context_ids_get();
21 }
22 
23 EAPI Eina_List *
ecore_imf_context_available_ids_by_canvas_type_get(const char * canvas_type)24 ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type)
25 {
26    return ecore_imf_module_context_ids_by_canvas_type_get(canvas_type);
27 }
28 
29 /*
30  * Match @locale against @against.
31  *
32  * 'en_US' against 'en_US'       => 4
33  * 'en_US' against 'en'          => 3
34  * 'en', 'en_UK' against 'en_US' => 2
35  *  all locales, against '*'     => 1
36  */
37 /* XXX: disable because nto used anymore - see below
38  * ecore_imf_context_default_id_by_canvas_type_get
39 static int
40 _ecore_imf_context_match_locale(const char *locale, const char *against, int against_len)
41 {
42    if (strcmp(against, "*") == 0)
43      return 1;
44 
45    if (strcasecmp(locale, against) == 0)
46      return 4;
47 
48    if (strncasecmp(locale, against, 2) == 0)
49      return (against_len == 2) ? 3 : 2;
50 
51    return 0;
52 }
53 */
54 
55 EAPI const char *
ecore_imf_context_default_id_get(void)56 ecore_imf_context_default_id_get(void)
57 {
58    return ecore_imf_context_default_id_by_canvas_type_get(NULL);
59 }
60 
61 EAPI const char *
ecore_imf_context_default_id_by_canvas_type_get(const char * canvas_type EINA_UNUSED)62 ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type EINA_UNUSED)
63 {
64    const char *id = getenv("ECORE_IMF_MODULE");
65 
66    if (id)
67      {
68         if (strcmp(id, "none") == 0) return NULL;
69         if (ecore_imf_module_get(id)) return id;
70      }
71    else
72      {
73         if (getenv("WAYLAND_DISPLAY"))
74           {
75              id = "wayland";
76              if (ecore_imf_module_get(id)) return id;
77           }
78      }
79    return NULL;
80 /* XXX: I am not sure we need/want this. this causes imf modules to be
81  * used where ECORE_IMF_MODULE is not set (and this causes issues with things
82  * like scim where on some distros and some versions an scim connect BLOCKS
83  * and if no scim is around this means an app blocks/hangs ... so disable
84  * this so either you are in wayland mode OR you have to set
85  * ECORE_IMF_MODULE
86    Eina_List *modules;
87    Ecore_IMF_Module *module;
88    char *locale;
89    char *tmp;
90    int best_goodness = 0;
91 
92    modules = ecore_imf_module_available_get();
93    if (!modules) return NULL;
94 
95    locale = setlocale(LC_CTYPE, NULL);
96    if (!locale) return NULL;
97 
98    locale = strdup(locale);
99 
100    tmp = strchr(locale, '.');
101    if (tmp) *tmp = '\0';
102    tmp = strchr(locale, '@');
103    if (tmp) *tmp = '\0';
104 
105    id = NULL;
106 
107    EINA_LIST_FREE(modules, module)
108      {
109         if (canvas_type &&
110             strcmp(module->info->canvas_type, canvas_type) == 0)
111           continue;
112 
113         const char *p = module->info->default_locales;
114         while (p)
115           {
116              const char *q = strchr(p, ':');
117              int goodness = _ecore_imf_context_match_locale(locale, p, q ? (size_t)(q - p) : strlen (p));
118 
119              if (goodness > best_goodness)
120                {
121                   id = module->info->id;
122                   best_goodness = goodness;
123                }
124 
125              p = q ? q + 1 : NULL;
126           }
127      }
128 
129    free(locale);
130    return id;
131  */
132 }
133 
134 EAPI const Ecore_IMF_Context_Info *
ecore_imf_context_info_by_id_get(const char * id)135 ecore_imf_context_info_by_id_get(const char *id)
136 {
137    Ecore_IMF_Module *module;
138 
139    if (!id) return NULL;
140    module = ecore_imf_module_get(id);
141    if (!module) return NULL;
142    return module->info;
143 }
144 
145 EAPI Ecore_IMF_Context *
ecore_imf_context_add(const char * id)146 ecore_imf_context_add(const char *id)
147 {
148    Ecore_IMF_Context *ctx;
149 
150    if (!id) return NULL;
151    ctx = ecore_imf_module_context_create(id);
152    if (!ctx || !ctx->klass) return NULL;
153    if (ctx->klass->add) ctx->klass->add(ctx);
154    /* default use_preedit is EINA_TRUE, so let's make sure it's
155     * set on the immodule */
156    ecore_imf_context_use_preedit_set(ctx, EINA_TRUE);
157 
158    /* default prediction is EINA_TRUE, so let's make sure it's
159     * set on the immodule */
160    ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE);
161 
162    /* default autocapital type is SENTENCE type, so let's make sure it's
163     * set on the immodule */
164    ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE);
165 
166    /* default input hint */
167    ecore_imf_context_input_hint_set(ctx, ECORE_IMF_INPUT_HINT_AUTO_COMPLETE);
168 
169    /* default input panel enabled status is EINA_TRUE, so let's make sure it's
170     * set on the immodule */
171    ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE);
172 
173    /* default input panel layout type is NORMAL type, so let's make sure it's
174     * set on the immodule */
175    ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
176 
177    /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's
178     * set on the immodule */
179    ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL);
180 
181    ecore_imf_context_bidi_direction_set(ctx, ECORE_IMF_BIDI_DIRECTION_NEUTRAL);
182 
183    return ctx;
184 }
185 
186 EAPI const Ecore_IMF_Context_Info *
ecore_imf_context_info_get(Ecore_IMF_Context * ctx)187 ecore_imf_context_info_get(Ecore_IMF_Context *ctx)
188 {
189    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
190      {
191         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
192                          "ecore_imf_context_info_get");
193         return NULL;
194      }
195    return ctx->module->info;
196 }
197 
198 EAPI void
ecore_imf_context_del(Ecore_IMF_Context * ctx)199 ecore_imf_context_del(Ecore_IMF_Context *ctx)
200 {
201    Ecore_IMF_Func_Node *fn;
202 
203    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
204      {
205         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
206                          "ecore_imf_context_del");
207         return;
208      }
209 
210    if (show_req_ctx == ctx)
211      show_req_ctx = NULL;
212 
213    if (ctx->klass && ctx->klass->del) ctx->klass->del(ctx);
214 
215    if (ctx->callbacks)
216      {
217         EINA_LIST_FREE(ctx->callbacks, fn)
218            free(fn);
219      }
220 
221    if (ctx->input_panel_callbacks)
222      {
223         EINA_LIST_FREE(ctx->input_panel_callbacks, fn)
224            free(fn);
225      }
226 
227    if (ctx->prediction_hint_hash)
228      eina_hash_free(ctx->prediction_hint_hash);
229 
230    ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE);
231    free(ctx);
232 }
233 
234 EAPI void
ecore_imf_context_client_window_set(Ecore_IMF_Context * ctx,void * window)235 ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
236 {
237    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
238      {
239         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
240                          "ecore_imf_context_client_window_set");
241         return;
242      }
243 
244    if (ctx->klass && ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window);
245    ctx->window = window;
246 }
247 
248 EAPI void *
ecore_imf_context_client_window_get(Ecore_IMF_Context * ctx)249 ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx)
250 {
251    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
252      {
253         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
254                          "ecore_imf_context_client_window_get");
255         return NULL;
256      }
257    return ctx->window;
258 }
259 
260 EAPI void
ecore_imf_context_client_canvas_set(Ecore_IMF_Context * ctx,void * canvas)261 ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
262 {
263    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
264      {
265         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
266                          "ecore_imf_context_client_canvas_set");
267         return;
268      }
269 
270    if (ctx->klass && ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas);
271    ctx->client_canvas = canvas;
272 }
273 
274 EAPI void *
ecore_imf_context_client_canvas_get(Ecore_IMF_Context * ctx)275 ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx)
276 {
277    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
278      {
279         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
280                          "ecore_imf_context_client_canvas_get");
281         return NULL;
282      }
283    return ctx->client_canvas;
284 }
285 
286 EAPI void
ecore_imf_context_show(Ecore_IMF_Context * ctx)287 ecore_imf_context_show(Ecore_IMF_Context *ctx)
288 {
289    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
290      {
291         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
292                          "ecore_imf_context_show");
293         return;
294      }
295 
296    show_req_ctx = ctx;
297    if (ctx->klass && ctx->klass->show) ctx->klass->show(ctx);
298 }
299 
300 EAPI void
ecore_imf_context_hide(Ecore_IMF_Context * ctx)301 ecore_imf_context_hide(Ecore_IMF_Context *ctx)
302 {
303    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
304      {
305         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
306                          "ecore_imf_context_hide");
307         return;
308      }
309 
310    if (ctx->klass && ctx->klass->hide) ctx->klass->hide(ctx);
311 }
312 
313 EAPI void
ecore_imf_context_preedit_string_get(Ecore_IMF_Context * ctx,char ** str,int * cursor_pos)314 ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos)
315 {
316    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
317      {
318         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
319                          "ecore_imf_context_preedit_string_get");
320         return;
321      }
322 
323    if (ctx->klass && ctx->klass->preedit_string_get)
324      ctx->klass->preedit_string_get(ctx, str, cursor_pos);
325    else
326      {
327         if (str) *str = strdup("");
328         if (cursor_pos) *cursor_pos = 0;
329      }
330 }
331 
332 EAPI void
ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context * ctx,char ** str,Eina_List ** attrs,int * cursor_pos)333 ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos)
334 {
335    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
336      {
337         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
338                          "ecore_imf_context_preedit_string_with_attributes_get");
339         return;
340      }
341    if (ctx->klass && ctx->klass->preedit_string_with_attributes_get)
342      ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos);
343    else
344      {
345         if (str) *str = strdup("");
346         if (attrs) *attrs = NULL;
347         if (cursor_pos) *cursor_pos = 0;
348      }
349 }
350 
351 EAPI void
ecore_imf_context_focus_in(Ecore_IMF_Context * ctx)352 ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
353 {
354    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
355      {
356         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
357                          "ecore_imf_context_focus_in");
358         return;
359      }
360 
361    if (ctx->klass && ctx->klass->focus_in) ctx->klass->focus_in(ctx);
362 }
363 
364 EAPI void
ecore_imf_context_focus_out(Ecore_IMF_Context * ctx)365 ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
366 {
367    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
368      {
369         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
370                          "ecore_imf_context_focus_out");
371         return;
372      }
373 
374    if (ctx->klass && ctx->klass->focus_out) ctx->klass->focus_out(ctx);
375 }
376 
377 EAPI void
ecore_imf_context_reset(Ecore_IMF_Context * ctx)378 ecore_imf_context_reset(Ecore_IMF_Context *ctx)
379 {
380    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
381      {
382         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
383                          "ecore_imf_context_reset");
384         return;
385      }
386 
387    if (ctx->klass && ctx->klass->reset) ctx->klass->reset(ctx);
388 }
389 
390 EAPI void
ecore_imf_context_cursor_position_set(Ecore_IMF_Context * ctx,int cursor_pos)391 ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
392 {
393    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
394      {
395         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
396                          "ecore_imf_context_cursor_position_set");
397         return;
398      }
399 
400    if (ctx->klass && ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos);
401 }
402 
403 EAPI void
ecore_imf_context_cursor_location_set(Ecore_IMF_Context * ctx,int x,int y,int w,int h)404 ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
405 {
406    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
407      {
408         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
409                          "ecore_imf_context_cursor_location_set");
410         return;
411      }
412    if (ctx->klass && ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h);
413 }
414 
415 EAPI void
ecore_imf_context_use_preedit_set(Ecore_IMF_Context * ctx,Eina_Bool use_preedit)416 ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
417 {
418    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
419      {
420         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
421                          "ecore_imf_context_use_preedit_set");
422         return;
423      }
424    if (ctx->klass && ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit);
425 }
426 
427 EAPI void
ecore_imf_context_prediction_allow_set(Ecore_IMF_Context * ctx,Eina_Bool prediction)428 ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction)
429 {
430    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
431      {
432         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
433                          "ecore_imf_context_prediction_allow_set");
434         return;
435      }
436 
437    if (ctx->allow_prediction != prediction)
438      {
439         ctx->allow_prediction = prediction;
440 
441         if (ctx->klass && ctx->klass->prediction_allow_set)
442           ctx->klass->prediction_allow_set(ctx, prediction);
443      }
444 }
445 
446 EAPI Eina_Bool
ecore_imf_context_prediction_allow_get(Ecore_IMF_Context * ctx)447 ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx)
448 {
449    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
450      {
451         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
452                          "ecore_imf_context_prediction_allow_get");
453         return EINA_FALSE;
454      }
455 
456    return ctx->allow_prediction;
457 }
458 
459 EAPI void
ecore_imf_context_autocapital_type_set(Ecore_IMF_Context * ctx,Ecore_IMF_Autocapital_Type autocapital_type)460 ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type)
461 {
462    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
463      {
464         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
465                          "ecore_imf_context_autocapital_type_set");
466         return;
467      }
468 
469    if (ctx->autocapital_type != autocapital_type)
470      {
471         ctx->autocapital_type = autocapital_type;
472 
473         if (ctx->klass && ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type);
474      }
475 }
476 
477 EAPI Ecore_IMF_Autocapital_Type
ecore_imf_context_autocapital_type_get(Ecore_IMF_Context * ctx)478 ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx)
479 {
480    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
481      {
482         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
483                          "ecore_imf_context_autocapital_allow_get");
484         return ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
485      }
486 
487    return ctx->autocapital_type;
488 }
489 
490 EAPI void
ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context * ctx,Eina_Bool (* func)(void * data,Ecore_IMF_Context * ctx,char ** text,int * cursor_pos),const void * data)491 ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data)
492 {
493    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
494      {
495         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
496                          "ecore_imf_context_retrieve_surrounding_callback_set");
497         return;
498      }
499 
500    ctx->retrieve_surrounding_func = func;
501    ctx->retrieve_surrounding_data = (void *) data;
502 }
503 
504 EAPI void
ecore_imf_context_retrieve_selection_callback_set(Ecore_IMF_Context * ctx,Eina_Bool (* func)(void * data,Ecore_IMF_Context * ctx,char ** text),const void * data)505 ecore_imf_context_retrieve_selection_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*func)(void *data, Ecore_IMF_Context *ctx, char **text), const void *data)
506 {
507    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
508      {
509         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
510                          "ecore_imf_context_retrieve_selection_callback_set");
511         return;
512      }
513 
514    ctx->retrieve_selection_func = func;
515    ctx->retrieve_selection_data = (void *) data;
516 }
517 
518 EAPI void
ecore_imf_context_input_mode_set(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Mode input_mode)519 ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
520 {
521    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
522      {
523         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
524                          "ecore_imf_context_input_mode_set");
525         return;
526      }
527    if (ctx->klass && ctx->klass->input_mode_set) ctx->klass->input_mode_set(ctx, input_mode);
528    ctx->input_mode = input_mode;
529 }
530 
531 EAPI Ecore_IMF_Input_Mode
ecore_imf_context_input_mode_get(Ecore_IMF_Context * ctx)532 ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx)
533 {
534    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
535      {
536         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
537                          "ecore_imf_context_input_mode_get");
538         return 0;
539      }
540    return ctx->input_mode;
541 }
542 
543 EAPI Eina_Bool
ecore_imf_context_filter_event(Ecore_IMF_Context * ctx,Ecore_IMF_Event_Type type,Ecore_IMF_Event * event)544 ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
545 {
546    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
547      {
548         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
549                          "ecore_imf_context_filter_event");
550         return EINA_FALSE;
551      }
552    if (ctx->klass && ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event);
553    return EINA_FALSE;
554 }
555 
556 EAPI Ecore_IMF_Context *
ecore_imf_context_new(const Ecore_IMF_Context_Class * ctxc)557 ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc)
558 {
559    Ecore_IMF_Context *ctx;
560 
561    if (!ctxc) return NULL;
562    ctx = calloc(1, sizeof(Ecore_IMF_Context));
563    if (!ctx) return NULL;
564    ECORE_MAGIC_SET(ctx, ECORE_MAGIC_CONTEXT);
565    ctx->klass = ctxc;
566    ctx->data = NULL;
567    ctx->retrieve_surrounding_func = NULL;
568    ctx->retrieve_surrounding_data = NULL;
569    return ctx;
570 }
571 
572 EAPI void
ecore_imf_context_data_set(Ecore_IMF_Context * ctx,void * data)573 ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data)
574 {
575    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
576      {
577         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
578                          "ecore_imf_context_data_set");
579         return;
580      }
581    ctx->data = data;
582 }
583 
584 EAPI void *
ecore_imf_context_data_get(Ecore_IMF_Context * ctx)585 ecore_imf_context_data_get(Ecore_IMF_Context *ctx)
586 {
587    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
588      {
589         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
590                          "ecore_imf_context_data_get");
591         return NULL;
592      }
593    return ctx->data;
594 }
595 
596 EAPI Eina_Bool
ecore_imf_context_surrounding_get(Ecore_IMF_Context * ctx,char ** text,int * cursor_pos)597 ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos)
598 {
599    int result = EINA_FALSE;
600 
601    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
602      {
603         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
604                          "ecore_imf_context_surrounding_get");
605         return EINA_FALSE;
606      }
607 
608    if (ctx->retrieve_surrounding_func)
609      {
610         result = ctx->retrieve_surrounding_func(ctx->retrieve_surrounding_data, ctx, text, cursor_pos);
611         if (!result)
612           {
613              if (text) *text = NULL;
614              if (cursor_pos) *cursor_pos = 0;
615           }
616      }
617    return result;
618 }
619 
620 EAPI Eina_Bool
ecore_imf_context_selection_get(Ecore_IMF_Context * ctx,char ** text)621 ecore_imf_context_selection_get(Ecore_IMF_Context *ctx, char **text)
622 {
623    Eina_Bool result = EINA_FALSE;
624 
625    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
626      {
627         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
628                          "ecore_imf_context_selection_get");
629         return EINA_FALSE;
630      }
631 
632    if (ctx->retrieve_selection_func)
633      {
634         result = ctx->retrieve_selection_func(ctx->retrieve_selection_data, ctx, text);
635         if (!result)
636           {
637              if (text) *text = NULL;
638           }
639      }
640    return result;
641 }
642 
643 static void
_ecore_imf_event_free_preedit(void * data EINA_UNUSED,void * event)644 _ecore_imf_event_free_preedit(void *data EINA_UNUSED, void *event)
645 {
646    free(event);
647 }
648 
649 EAPI void
ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context * ctx)650 ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx)
651 {
652    Ecore_IMF_Event_Preedit_Start *ev;
653 
654    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
655      {
656         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
657                          "ecore_imf_context_preedit_start_event_add");
658         return;
659      }
660 
661    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Start));
662    EINA_SAFETY_ON_NULL_RETURN(ev);
663 
664    ev->ctx = ctx;
665    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_START,
666                    ev, _ecore_imf_event_free_preedit, NULL);
667 }
668 
669 EAPI void
ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context * ctx)670 ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx)
671 {
672    Ecore_IMF_Event_Preedit_End *ev;
673 
674    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
675      {
676         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
677                          "ecore_imf_context_preedit_end_event_add");
678         return;
679      }
680 
681    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_End));
682    EINA_SAFETY_ON_NULL_RETURN(ev);
683 
684    ev->ctx = ctx;
685    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_END,
686                    ev, _ecore_imf_event_free_preedit, NULL);
687 }
688 
689 EAPI void
ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context * ctx)690 ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx)
691 {
692    Ecore_IMF_Event_Preedit_Changed *ev;
693 
694    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
695      {
696         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
697                          "ecore_imf_context_preedit_changed_event_add");
698         return;
699      }
700 
701    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Changed));
702    EINA_SAFETY_ON_NULL_RETURN(ev);
703 
704    ev->ctx = ctx;
705    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_CHANGED,
706                    ev, _ecore_imf_event_free_preedit, NULL);
707 }
708 
709 static void
_ecore_imf_event_free_commit(void * data EINA_UNUSED,void * event)710 _ecore_imf_event_free_commit(void *data EINA_UNUSED, void *event)
711 {
712    Ecore_IMF_Event_Commit *ev;
713 
714    ev = event;
715    if (ev->str) free(ev->str);
716    free(ev);
717 }
718 
719 EAPI void
ecore_imf_context_commit_event_add(Ecore_IMF_Context * ctx,const char * str)720 ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str)
721 {
722    Ecore_IMF_Event_Commit *ev;
723 
724    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
725      {
726         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
727                          "ecore_imf_context_commit_event_add");
728         return;
729      }
730 
731    ev = malloc(sizeof(Ecore_IMF_Event_Commit));
732    EINA_SAFETY_ON_NULL_RETURN(ev);
733 
734    ev->ctx = ctx;
735    ev->str = str ? strdup(str) : NULL;
736    ecore_event_add(ECORE_IMF_EVENT_COMMIT,
737                    ev, _ecore_imf_event_free_commit, NULL);
738 }
739 
740 static void
_ecore_imf_event_free_delete_surrounding(void * data EINA_UNUSED,void * event)741 _ecore_imf_event_free_delete_surrounding(void *data EINA_UNUSED, void *event)
742 {
743    free(event);
744 }
745 
746 EAPI void
ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context * ctx,int offset,int n_chars)747 ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars)
748 {
749    Ecore_IMF_Event_Delete_Surrounding *ev;
750 
751    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
752      {
753         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
754                          "ecore_imf_context_delete_surrounding_event_add");
755         return;
756      }
757 
758    ev = malloc(sizeof(Ecore_IMF_Event_Delete_Surrounding));
759    ev->ctx = ctx;
760    ev->offset = offset;
761    ev->n_chars = n_chars;
762    ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
763                    ev, _ecore_imf_event_free_delete_surrounding, NULL);
764 }
765 
766 EAPI void
ecore_imf_context_event_callback_add(Ecore_IMF_Context * ctx,Ecore_IMF_Callback_Type type,Ecore_IMF_Event_Cb func,const void * data)767 ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data)
768 {
769    Ecore_IMF_Func_Node *fn = NULL;
770 
771    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
772      {
773         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
774                          "ecore_imf_context_event_callback_add");
775         return;
776      }
777 
778    if (!func) return;
779 
780    fn = calloc(1, sizeof (Ecore_IMF_Func_Node));
781    if (!fn) return;
782 
783    fn->func = func;
784    fn->data = data;
785    fn->type = type;
786 
787    ctx->callbacks = eina_list_append(ctx->callbacks, fn);
788 }
789 
790 EAPI void *
ecore_imf_context_event_callback_del(Ecore_IMF_Context * ctx,Ecore_IMF_Callback_Type type,Ecore_IMF_Event_Cb func)791 ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func)
792 {
793    Eina_List *l = NULL;
794    Eina_List *l_next = NULL;
795    Ecore_IMF_Func_Node *fn = NULL;
796 
797    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
798      {
799         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
800                          "ecore_imf_context_event_callback_del");
801         return NULL;
802      }
803 
804    if (!func) return NULL;
805    if (!ctx->callbacks) return NULL;
806 
807    EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn)
808      {
809         if ((fn) && (fn->func == func) && (fn->type == type))
810           {
811              void *tmp = (void *)fn->data;
812              free(fn);
813              ctx->callbacks = eina_list_remove_list(ctx->callbacks, l);
814              return tmp;
815           }
816      }
817    return NULL;
818 }
819 
820 EAPI void
ecore_imf_context_event_callback_call(Ecore_IMF_Context * ctx,Ecore_IMF_Callback_Type type,void * event_info)821 ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info)
822 {
823    Ecore_IMF_Func_Node *fn = NULL;
824    Eina_List *l = NULL;
825 
826    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
827      {
828         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
829                          "ecore_imf_context_event_callback_call");
830         return;
831      }
832 
833    EINA_LIST_FOREACH(ctx->callbacks, l, fn)
834      {
835         if ((fn) && (fn->type == type) && (fn->func))
836           fn->func(fn->data, ctx, event_info);
837      }
838 }
839 
840 EAPI void
ecore_imf_context_control_panel_show(Ecore_IMF_Context * ctx)841 ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx)
842 {
843    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
844      {
845         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
846                          "ecore_imf_context_control_panel_show");
847         return;
848      }
849 
850    if (ctx->klass && ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx);
851 }
852 
853 EAPI void
ecore_imf_context_control_panel_hide(Ecore_IMF_Context * ctx)854 ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx)
855 {
856    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
857      {
858         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
859                          "ecore_imf_context_control_panel_hide");
860         return;
861      }
862 
863    if (ctx->klass && ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx);
864 }
865 
866 EAPI void
ecore_imf_context_input_hint_set(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Hints input_hints)867 ecore_imf_context_input_hint_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Hints input_hints)
868 {
869     if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
870       {
871          ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
872                           "ecore_imf_context_input_hint_set");
873          return;
874       }
875 
876    if (ctx->input_hints != input_hints)
877      {
878         if (ctx->klass && ctx->klass->input_hint_set)
879           ctx->klass->input_hint_set(ctx, input_hints);
880 
881         ctx->input_hints = input_hints;
882      }
883 }
884 
885 EAPI Ecore_IMF_Input_Hints
ecore_imf_context_input_hint_get(Ecore_IMF_Context * ctx)886 ecore_imf_context_input_hint_get(Ecore_IMF_Context *ctx)
887 {
888     if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
889       {
890          ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
891                           "ecore_imf_context_input_hint_get");
892          return ECORE_IMF_INPUT_HINT_NONE;
893       }
894 
895     return ctx->input_hints;
896 }
897 
898 EAPI void
ecore_imf_context_input_panel_show(Ecore_IMF_Context * ctx)899 ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
900 {
901    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
902      {
903         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
904                          "ecore_imf_context_input_panel_show");
905         return;
906      }
907 
908    show_req_ctx = ctx;
909    if ((ctx->input_panel_enabled) ||
910        (getenv("ECORE_IMF_INPUT_PANEL_ENABLED")))
911      {
912         if (ctx->klass && ctx->klass->show) ctx->klass->show(ctx);
913      }
914 }
915 
916 EAPI void
ecore_imf_context_input_panel_hide(Ecore_IMF_Context * ctx)917 ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
918 {
919    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
920      {
921         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
922                          "ecore_imf_context_input_panel_hide");
923         return;
924      }
925 
926    if ((ctx->input_panel_enabled) ||
927        (getenv("ECORE_IMF_INPUT_PANEL_ENABLED")))
928      {
929         if (ctx->klass && ctx->klass->hide) ctx->klass->hide(ctx);
930      }
931 }
932 
933 EAPI void
ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Layout layout)934 ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout)
935 {
936    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
937      {
938         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
939                          "ecore_imf_context_input_panel_layout_set");
940         return;
941      }
942 
943    if (ctx->input_panel_layout != layout)
944      {
945         if (ctx->klass && ctx->klass->input_panel_layout_set)
946           ctx->klass->input_panel_layout_set(ctx, layout);
947 
948         ctx->input_panel_layout = layout;
949 
950         if (layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
951           ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_NONE);
952      }
953 }
954 
955 EAPI Ecore_IMF_Input_Panel_Layout
ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context * ctx)956 ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
957 {
958    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
959      {
960         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
961                          "ecore_imf_context_input_panel_layout_get");
962         return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
963      }
964 
965    if (ctx->klass && ctx->klass->input_panel_layout_get)
966      return ctx->input_panel_layout;
967    else
968      return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
969 }
970 
971 EAPI void
ecore_imf_context_input_panel_layout_variation_set(Ecore_IMF_Context * ctx,int variation)972 ecore_imf_context_input_panel_layout_variation_set(Ecore_IMF_Context *ctx, int variation)
973 {
974    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
975      {
976         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
977                          "ecore_imf_context_input_panel_layout_variation_set");
978         return;
979      }
980 
981    ctx->input_panel_layout_variation = variation;
982 }
983 
984 EAPI int
ecore_imf_context_input_panel_layout_variation_get(Ecore_IMF_Context * ctx)985 ecore_imf_context_input_panel_layout_variation_get(Ecore_IMF_Context *ctx)
986 {
987    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
988      {
989         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
990                          "ecore_imf_context_input_panel_layout_variation_get");
991         return 0;
992      }
993 
994    return ctx->input_panel_layout_variation;
995 }
996 
997 EAPI void
ecore_imf_context_input_panel_language_set(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Lang lang)998 ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang)
999 {
1000    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1001      {
1002         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1003                          "ecore_imf_context_input_panel_language_set");
1004         return;
1005      }
1006 
1007    if (ctx->input_panel_lang != lang)
1008      {
1009         if (ctx->klass && ctx->klass->input_panel_language_set)
1010           ctx->klass->input_panel_language_set(ctx, lang);
1011 
1012         ctx->input_panel_lang = lang;
1013      }
1014 }
1015 
1016 EAPI Ecore_IMF_Input_Panel_Lang
ecore_imf_context_input_panel_language_get(Ecore_IMF_Context * ctx)1017 ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx)
1018 {
1019    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1020      {
1021         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1022                          "ecore_imf_context_input_panel_language_get");
1023         return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
1024      }
1025 
1026    return ctx->input_panel_lang;
1027 }
1028 
1029 EAPI void
ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context * ctx,Eina_Bool enabled)1030 ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx,
1031                                            Eina_Bool enabled)
1032 {
1033    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1034      {
1035         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1036                          "ecore_imf_context_input_panel_enabled_set");
1037         return;
1038      }
1039 
1040    ctx->input_panel_enabled = enabled;
1041 }
1042 
1043 EAPI Eina_Bool
ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context * ctx)1044 ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx)
1045 {
1046    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1047      {
1048         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1049                          "ecore_imf_context_input_panel_enabled_get");
1050         return EINA_FALSE;
1051      }
1052 
1053    return ctx->input_panel_enabled;
1054 }
1055 
1056 EAPI void
ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context * ctx,const void * data,int len)1057 ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len)
1058 {
1059    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1060      {
1061         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1062                          "ecore_imf_context_input_panel_imdata_set");
1063         return;
1064      }
1065 
1066    if (!data) return;
1067 
1068    if (ctx->klass && ctx->klass->input_panel_imdata_set)
1069      ctx->klass->input_panel_imdata_set(ctx, data, len);
1070 }
1071 
1072 EAPI void
ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context * ctx,void * data,int * len)1073 ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len)
1074 {
1075    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1076      {
1077         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1078                          "ecore_imf_context_input_panel_imdata_get");
1079         return;
1080      }
1081 
1082    if (!data) return;
1083 
1084    if (ctx->klass && ctx->klass->input_panel_imdata_get)
1085      ctx->klass->input_panel_imdata_get(ctx, data, len);
1086 }
1087 
1088 EAPI void
ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)1089 ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
1090 {
1091    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1092      {
1093         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1094                          "ecore_imf_context_input_panel_return_key_type_set");
1095         return;
1096      }
1097 
1098    if (ctx->input_panel_return_key_type != return_key_type)
1099      {
1100         ctx->input_panel_return_key_type = return_key_type;
1101         if (ctx->klass && ctx->klass->input_panel_return_key_type_set)
1102           ctx->klass->input_panel_return_key_type_set(ctx, return_key_type);
1103      }
1104 }
1105 
1106 EAPI Ecore_IMF_Input_Panel_Return_Key_Type
ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context * ctx)1107 ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx)
1108 {
1109    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1110      {
1111         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1112                          "ecore_imf_context_input_panel_return_key_type_get");
1113         return ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
1114      }
1115 
1116    return ctx->input_panel_return_key_type;
1117 }
1118 
1119 EAPI void
ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context * ctx,Eina_Bool disabled)1120 ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled)
1121 {
1122    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1123      {
1124         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1125                          "ecore_imf_context_input_panel_return_key_disabled_set");
1126         return;
1127      }
1128 
1129    if (ctx->input_panel_return_key_disabled != disabled)
1130      {
1131         ctx->input_panel_return_key_disabled = disabled;
1132         if (ctx->klass && ctx->klass->input_panel_return_key_disabled_set)
1133           ctx->klass->input_panel_return_key_disabled_set(ctx, disabled);
1134      }
1135 }
1136 
1137 EAPI Eina_Bool
ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context * ctx)1138 ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx)
1139 {
1140    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1141      {
1142         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1143                          "ecore_imf_context_input_panel_return_key_disabled_get");
1144         return EINA_FALSE;
1145      }
1146 
1147    return ctx->input_panel_return_key_disabled;
1148 }
1149 
1150 EAPI void
ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context * ctx,Eina_Bool mode)1151 ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode)
1152 {
1153    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1154      {
1155         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1156                          "ecore_imf_context_input_panel_caps_lock_mode_set");
1157         return;
1158      }
1159 
1160    if (ctx->input_panel_caps_lock_mode != mode)
1161      {
1162         if (ctx->klass && ctx->klass->input_panel_caps_lock_mode_set)
1163           ctx->klass->input_panel_caps_lock_mode_set(ctx, mode);
1164 
1165         ctx->input_panel_caps_lock_mode = mode;
1166      }
1167 }
1168 
1169 EAPI Eina_Bool
ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context * ctx)1170 ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx)
1171 {
1172    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1173      {
1174         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1175                          "ecore_imf_context_input_panel_caps_lock_mode_get");
1176         return EINA_FALSE;
1177      }
1178 
1179    return ctx->input_panel_caps_lock_mode;
1180 }
1181 
1182 EAPI void
ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context * ctx,int * x,int * y,int * w,int * h)1183 ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h)
1184 {
1185    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1186      {
1187         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1188                          "ecore_imf_context_input_panel_geometry_get");
1189         return;
1190      }
1191 
1192    if (ctx->klass && ctx->klass->input_panel_geometry_get)
1193      ctx->klass->input_panel_geometry_get(ctx, x, y, w, h);
1194 }
1195 
1196 EAPI Ecore_IMF_Input_Panel_State
ecore_imf_context_input_panel_state_get(Ecore_IMF_Context * ctx)1197 ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx)
1198 {
1199    Ecore_IMF_Input_Panel_State state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
1200    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1201      {
1202         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1203                          "ecore_imf_context_input_panel_state_get");
1204         return ECORE_IMF_INPUT_PANEL_STATE_HIDE;
1205      }
1206 
1207    if (ctx->klass && ctx->klass->input_panel_state_get)
1208      state = ctx->klass->input_panel_state_get(ctx);
1209 
1210    return state;
1211 }
1212 
1213 EAPI void
ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Event type,void (* func)(void * data,Ecore_IMF_Context * ctx,int value),const void * data)1214 ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx,
1215                                                  Ecore_IMF_Input_Panel_Event type,
1216                                                  void (*func) (void *data, Ecore_IMF_Context *ctx, int value),
1217                                                  const void *data)
1218 {
1219    Ecore_IMF_Input_Panel_Callback_Node *fn = NULL;
1220 
1221    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1222      {
1223         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1224                          "ecore_imf_context_input_panel_event_callback_add");
1225         return;
1226      }
1227 
1228    if (!func) return;
1229 
1230    fn = calloc(1, sizeof (Ecore_IMF_Input_Panel_Callback_Node));
1231    if (!fn) return;
1232 
1233    fn->func = func;
1234    fn->data = data;
1235    fn->type = type;
1236 
1237    ctx->input_panel_callbacks = eina_list_append(ctx->input_panel_callbacks, fn);
1238 }
1239 
1240 EAPI void
ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Event type,void (* func)(void * data,Ecore_IMF_Context * ctx,int value))1241 ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx,
1242                                                  Ecore_IMF_Input_Panel_Event type,
1243                                                  void (*func) (void *data, Ecore_IMF_Context *ctx, int value))
1244 {
1245    Eina_List *l = NULL;
1246    Eina_List *l_next = NULL;
1247    Ecore_IMF_Input_Panel_Callback_Node *fn = NULL;
1248 
1249    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1250      {
1251         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1252                          "ecore_imf_context_input_panel_event_callback_del");
1253         return;
1254      }
1255 
1256    if (!func) return;
1257    if (!ctx->input_panel_callbacks) return;
1258 
1259    EINA_LIST_FOREACH_SAFE(ctx->input_panel_callbacks, l, l_next, fn)
1260      {
1261         if ((fn) && (fn->func == func) && (fn->type == type))
1262           {
1263              free(fn);
1264              ctx->input_panel_callbacks = eina_list_remove_list(ctx->input_panel_callbacks, l);
1265              return;
1266           }
1267      }
1268 }
1269 
1270 EAPI void
ecore_imf_context_input_panel_event_callback_call(Ecore_IMF_Context * ctx,Ecore_IMF_Input_Panel_Event type,int value)1271 ecore_imf_context_input_panel_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, int value)
1272 {
1273    Ecore_IMF_Input_Panel_Callback_Node *fn = NULL;
1274    Eina_List *l = NULL;
1275 
1276    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1277      {
1278         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1279                          "ecore_imf_context_input_panel_event_callback_call");
1280         return;
1281      }
1282 
1283    EINA_LIST_FOREACH(ctx->input_panel_callbacks, l, fn)
1284      {
1285         if ((fn) && (fn->type == type) && (fn->func))
1286           {
1287              fn->func(fn->data, ctx, value);
1288              if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT &&
1289                  value == ECORE_IMF_INPUT_PANEL_STATE_HIDE &&
1290                  show_req_ctx == ctx)
1291                show_req_ctx = NULL;
1292 
1293              if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1294                break;
1295           }
1296      }
1297 }
1298 
1299 EAPI void
ecore_imf_context_input_panel_event_callback_clear(Ecore_IMF_Context * ctx)1300 ecore_imf_context_input_panel_event_callback_clear(Ecore_IMF_Context *ctx)
1301 {
1302    Ecore_IMF_Input_Panel_Callback_Node *fn = NULL;
1303    Eina_List *l = NULL;
1304 
1305    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1306      {
1307         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1308                          "ecore_imf_context_input_panel_event_callback_clear");
1309         return;
1310      }
1311 
1312    for (l = ctx->input_panel_callbacks; l;)
1313      {
1314         fn = (Ecore_IMF_Input_Panel_Callback_Node *)l->data;
1315 
1316         if (fn)
1317           {
1318              ctx->input_panel_callbacks = eina_list_remove(ctx->input_panel_callbacks, fn);
1319              free (fn);
1320           }
1321         l = l->next;
1322      }
1323 }
1324 
1325 EAPI void
ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context * ctx,char ** lang)1326 ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang)
1327 {
1328    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1329      {
1330         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1331                          "ecore_imf_context_input_panel_language_locale_get");
1332         return;
1333      }
1334 
1335    if (ctx->klass && ctx->klass->input_panel_language_locale_get)
1336      ctx->klass->input_panel_language_locale_get(ctx, lang);
1337    else
1338      {
1339         if (lang) *lang = strdup("");
1340      }
1341 }
1342 
1343 EAPI void
ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context * ctx,int * x,int * y,int * w,int * h)1344 ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h)
1345 {
1346    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1347      {
1348         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1349                          "ecore_imf_context_candidate_panel_geometry_get");
1350         return;
1351      }
1352 
1353    if (ctx->klass && ctx->klass->candidate_panel_geometry_get)
1354      ctx->klass->candidate_panel_geometry_get(ctx, x, y, w, h);
1355 }
1356 
1357 EAPI void
ecore_imf_context_input_panel_show_on_demand_set(Ecore_IMF_Context * ctx,Eina_Bool ondemand)1358 ecore_imf_context_input_panel_show_on_demand_set(Ecore_IMF_Context *ctx, Eina_Bool ondemand)
1359 {
1360    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1361      {
1362         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1363                          "ecore_imf_context_input_panel_show_on_demand_set");
1364         return;
1365      }
1366 
1367    ctx->input_panel_show_on_demand = ondemand;
1368 }
1369 
1370 EAPI Eina_Bool
ecore_imf_context_input_panel_show_on_demand_get(Ecore_IMF_Context * ctx)1371 ecore_imf_context_input_panel_show_on_demand_get(Ecore_IMF_Context *ctx)
1372 {
1373    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1374      {
1375         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1376                          "ecore_imf_context_input_panel_show_on_demand_get");
1377         return EINA_FALSE;
1378      }
1379 
1380    return ctx->input_panel_show_on_demand;
1381 }
1382 
1383 EAPI void
ecore_imf_context_bidi_direction_set(Ecore_IMF_Context * ctx,Ecore_IMF_BiDi_Direction direction)1384 ecore_imf_context_bidi_direction_set(Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction direction)
1385 {
1386    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1387      {
1388         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1389                          "ecore_imf_context_bidi_direction_set");
1390         return;
1391      }
1392 
1393    if (ctx->bidi_direction != direction)
1394      {
1395         if (ctx->klass && ctx->klass->bidi_direction_set)
1396           ctx->klass->bidi_direction_set(ctx, direction);
1397 
1398         ctx->bidi_direction = direction;
1399      }
1400 }
1401 
1402 EAPI Ecore_IMF_BiDi_Direction
ecore_imf_context_bidi_direction_get(Ecore_IMF_Context * ctx)1403 ecore_imf_context_bidi_direction_get(Ecore_IMF_Context *ctx)
1404 {
1405    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1406      {
1407         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1408                          "ecore_imf_context_bidi_direction_get");
1409         return ECORE_IMF_BIDI_DIRECTION_NEUTRAL;
1410      }
1411 
1412    return ctx->bidi_direction;
1413 }
1414 
1415 EAPI Ecore_IMF_Input_Panel_Keyboard_Mode
ecore_imf_context_keyboard_mode_get(Ecore_IMF_Context * ctx)1416 ecore_imf_context_keyboard_mode_get(Ecore_IMF_Context *ctx)
1417 {
1418    Ecore_IMF_Input_Panel_Keyboard_Mode mode = ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE;
1419    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1420      {
1421         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1422                          "ecore_imf_context_keyboard_mode_get");
1423         return ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE;
1424      }
1425 
1426    if (ctx->klass && ctx->klass->keyboard_mode_get)
1427      mode = ctx->klass->keyboard_mode_get(ctx);
1428 
1429    return mode;
1430 }
1431 
1432 EAPI void
ecore_imf_context_prediction_hint_set(Ecore_IMF_Context * ctx,const char * prediction_hint)1433 ecore_imf_context_prediction_hint_set(Ecore_IMF_Context *ctx, const char *prediction_hint)
1434 {
1435    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1436      {
1437         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1438                          "ecore_imf_context_prediction_hint_set");
1439         return;
1440      }
1441 
1442    if (ctx->klass && ctx->klass->prediction_hint_set)
1443      ctx->klass->prediction_hint_set(ctx, prediction_hint);
1444 }
1445 
1446 EAPI void
ecore_imf_context_mime_type_accept_set(Ecore_IMF_Context * ctx,const char * mime_type)1447 ecore_imf_context_mime_type_accept_set(Ecore_IMF_Context *ctx, const char *mime_type)
1448 {
1449    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1450      {
1451         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1452                          "ecore_imf_context_mime_type_accept_set");
1453         return;
1454      }
1455 
1456    if (!mime_type) return;
1457 
1458    if (ctx->klass && ctx->klass->mime_type_accept_set)
1459      ctx->klass->mime_type_accept_set(ctx, mime_type);
1460 }
1461 
1462 EAPI void
ecore_imf_context_input_panel_position_set(Ecore_IMF_Context * ctx,int x,int y)1463 ecore_imf_context_input_panel_position_set(Ecore_IMF_Context *ctx, int x, int y)
1464 {
1465    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1466      {
1467         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1468                          "ecore_imf_context_input_panel_position_set");
1469         return;
1470      }
1471 
1472    if (x < 0 || y < 0) return;
1473 
1474    if (ctx->klass && ctx->klass->input_panel_position_set)
1475      ctx->klass->input_panel_position_set(ctx, x, y);
1476 }
1477 
1478 static void
_prediction_hint_hash_free_cb(void * data)1479 _prediction_hint_hash_free_cb(void *data)
1480 {
1481    free(data);
1482 }
1483 
1484 EAPI Eina_Bool
ecore_imf_context_prediction_hint_hash_set(Ecore_IMF_Context * ctx,const char * key,const char * value)1485 ecore_imf_context_prediction_hint_hash_set(Ecore_IMF_Context *ctx, const char *key, const char *value)
1486 {
1487    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1488      {
1489         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1490                          "ecore_imf_context_prediction_hint_hash_set");
1491         return EINA_FALSE;
1492      }
1493 
1494    if (!ctx->prediction_hint_hash)
1495      ctx->prediction_hint_hash = eina_hash_string_superfast_new(_prediction_hint_hash_free_cb);
1496 
1497    if (!ctx->prediction_hint_hash)
1498      return EINA_FALSE;
1499 
1500    char *old_value = eina_hash_set(ctx->prediction_hint_hash, key, value ? strdup(value) : strdup(""));
1501    if (old_value)
1502      free(old_value);
1503 
1504    return EINA_TRUE;
1505 }
1506 
1507 EAPI Eina_Bool
ecore_imf_context_prediction_hint_hash_del(Ecore_IMF_Context * ctx,const char * key)1508 ecore_imf_context_prediction_hint_hash_del(Ecore_IMF_Context *ctx, const char *key)
1509 {
1510    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1511      {
1512         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1513                          "ecore_imf_context_prediction_hint_hash_del");
1514         return EINA_FALSE;
1515      }
1516 
1517    if (!ctx->prediction_hint_hash)
1518      return EINA_FALSE;
1519 
1520    return eina_hash_del(ctx->prediction_hint_hash, key, NULL);
1521 }
1522 
1523 EAPI const Eina_Hash *
ecore_imf_context_prediction_hint_hash_get(Ecore_IMF_Context * ctx)1524 ecore_imf_context_prediction_hint_hash_get(Ecore_IMF_Context *ctx)
1525 {
1526    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1527      {
1528         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1529                          "ecore_imf_context_prediction_hint_hash_get");
1530         return NULL;
1531      }
1532 
1533    return ctx->prediction_hint_hash;
1534 }
1535