ecore_imf: insert example link in ecore_imf_context group
[framework/uifw/ecore.git] / src / lib / ecore_imf / ecore_imf_context.c
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 /**
16  * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions
17  *
18  * Functions that operate on Ecore Input Method Context objects.
19
20  * Ecore Input Method Context Function defines the interface for EFL input methods. 
21  * An input method is used by EFL text input widgets like elm_entry 
22  * (based on edje_entry) to map from key events to Unicode character strings.
23  *
24  * The default input method can be set through setting the ECORE_IMF_MODULE environment variable.
25  *
26  * An input method may consume multiple key events in sequence and finally output the composed result. 
27  * This is called preediting, and an input method may provide feedback about 
28  * this process by displaying the intermediate composition states as preedit text.
29  *
30  * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n
31  * ecore_imf_init() should be called to initialize and load immodule.@n
32  * ecore_imf_shutdown() is used for shutdowning and unloading immodule.
33  *
34  * An example of usage of these functions can be found at:
35  * @li @ref ecore_imf_example_c
36  */
37
38 /**
39  * Get the list of the available Input Method Context ids.
40  *
41  * Note that the caller is responsible for freeing the Eina_List
42  * when finished with it. There is no need to finish the list strings.
43  *
44  * @return Return an Eina_List of strings;
45  *         on failure it returns NULL.
46  * @ingroup Ecore_IMF_Context_Group
47  */
48 EAPI Eina_List *
49 ecore_imf_context_available_ids_get(void)
50 {
51    return ecore_imf_module_context_ids_get();
52 }
53
54 EAPI Eina_List *
55 ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type)
56 {
57    return ecore_imf_module_context_ids_by_canvas_type_get(canvas_type);
58 }
59
60 /*
61  * Match @locale against @against.
62  *
63  * 'en_US' against 'en_US'       => 4
64  * 'en_US' against 'en'          => 3
65  * 'en', 'en_UK' against 'en_US' => 2
66  *  all locales, against '*'     => 1
67  */
68 static int
69 _ecore_imf_context_match_locale(const char *locale, const char *against, int against_len)
70 {
71    if (strcmp(against, "*") == 0)
72      return 1;
73
74    if (strcasecmp(locale, against) == 0)
75      return 4;
76
77    if (strncasecmp(locale, against, 2) == 0)
78      return (against_len == 2) ? 3 : 2;
79
80    return 0;
81 }
82
83 /**
84  * Get the id of the default Input Method Context.
85  * The id may to used to create a new instance of an Input Method
86  * Context object.
87  *
88  * @return Return a string containing the id of the default Input
89  *         Method Context; on failure it returns NULL.
90  * @ingroup Ecore_IMF_Context_Group
91  */
92 EAPI const char *
93 ecore_imf_context_default_id_get(void)
94 {
95    return ecore_imf_context_default_id_by_canvas_type_get(NULL);
96 }
97
98 EAPI const char *
99 ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type)
100 {
101    const char *id;
102    Eina_List *modules;
103    Ecore_IMF_Module *module;
104    char *locale;
105    char *tmp;
106    int best_goodness = 0;
107
108    id = getenv("ECORE_IMF_MODULE");
109    if (id)
110      {
111         if (strcmp(id, "none") == 0) return NULL;
112         if (ecore_imf_module_get(id)) return id;
113      }
114
115    modules = ecore_imf_module_available_get();
116    if (!modules) return NULL;
117
118    locale = setlocale(LC_CTYPE, NULL);
119    if (!locale) return NULL;
120
121    locale = strdup(locale);
122
123    tmp = strchr(locale, '.');
124    if (tmp) *tmp = '\0';
125    tmp = strchr(locale, '@');
126    if (tmp) *tmp = '\0';
127
128    id = NULL;
129
130    EINA_LIST_FREE(modules, module)
131      {
132         if (canvas_type &&
133             strcmp(module->info->canvas_type, canvas_type) == 0)
134           continue;
135
136         const char *p = module->info->default_locales;
137         while (p)
138           {
139              const char *q = strchr(p, ':');
140              int goodness = _ecore_imf_context_match_locale(locale, p, q ? (size_t)(q - p) : strlen (p));
141
142              if (goodness > best_goodness)
143                {
144                   id = module->info->id;
145                   best_goodness = goodness;
146                }
147
148              p = q ? q + 1 : NULL;
149           }
150      }
151
152    free(locale);
153    return id;
154 }
155
156 /**
157  * Retrieve the info for the Input Method Context with @p id.
158  *
159  * @param id The Input Method Context id to query for.
160  * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id;
161  *         on failure it returns NULL.
162  * @ingroup Ecore_IMF_Context_Group
163  * 
164  * Example
165  * @code
166  *
167  * const char *ctx_id;
168  * const Ecore_IMF_Context_Info *ctx_info;
169  * Ecore_IMF_Context *imf_context;
170  * ctx_id = ecore_imf_context_default_id_get();
171  * if (ctx_id)
172  *   {
173  *      ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
174  *      if (!ctx_info->canvas_type ||
175  *          strcmp(ctx_info->canvas_type, "evas") == 0)
176  *        {
177  *           imf_context = ecore_imf_context_add(ctx_id);
178  *        }
179  *      else
180  *        {
181  *           ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
182  *           if (ctx_id)
183  *             {
184  *                imf_context = ecore_imf_context_add(ctx_id);
185  *             }
186  *        }
187  *   }
188  * @endcode
189  */
190 EAPI const Ecore_IMF_Context_Info *
191 ecore_imf_context_info_by_id_get(const char *id)
192 {
193    Ecore_IMF_Module *module;
194
195    if (!id) return NULL;
196    module = ecore_imf_module_get(id);
197    if (!module) return NULL;
198    return module->info;
199 }
200
201 /**
202  * Create a new Input Method Context defined by the given id.
203  *
204  * @param id The Input Method Context id.
205  * @return A newly allocated Input Method Context;
206  *         on failure it returns NULL.
207  * @ingroup Ecore_IMF_Context_Group
208  */
209 EAPI Ecore_IMF_Context *
210 ecore_imf_context_add(const char *id)
211 {
212    Ecore_IMF_Context *ctx;
213
214    if (!id) return NULL;
215    ctx = ecore_imf_module_context_create(id);
216    if (!ctx || !ctx->klass) return NULL;
217    if (ctx->klass->add) ctx->klass->add(ctx);
218    /* default use_preedit is EINA_TRUE, so let's make sure it's
219     * set on the immodule */
220    ecore_imf_context_use_preedit_set(ctx, EINA_TRUE);
221
222    /* default prediction is EINA_TRUE, so let's make sure it's
223     * set on the immodule */
224    ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE);
225
226    /* default autocapital type is SENTENCE type, so let's make sure it's
227     * set on the immodule */
228    ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE);
229
230    /* default input panel enabled status is EINA_TRUE, so let's make sure it's
231     * set on the immodule */
232    ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE);
233
234    /* default input panel layout type is NORMAL type, so let's make sure it's
235     * set on the immodule */
236    ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
237
238    /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's
239     * set on the immodule */
240    ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL);
241    return ctx;
242 }
243
244 /**
245  * Retrieve the info for the given Input Method Context.
246  *
247  * @param ctx An #Ecore_IMF_Context.
248  * @return Return a #Ecore_IMF_Context_Info for the given Input Method Context;
249  *         on failure it returns NULL.
250  * @ingroup Ecore_IMF_Context_Group
251  */
252 EAPI const Ecore_IMF_Context_Info *
253 ecore_imf_context_info_get(Ecore_IMF_Context *ctx)
254 {
255    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
256      {
257         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
258                          "ecore_imf_context_info_get");
259         return NULL;
260      }
261    return ctx->module->info;
262 }
263
264 /**
265  * Delete the given Input Method Context and free its memory.
266  *
267  * @param ctx An #Ecore_IMF_Context.
268  * @ingroup Ecore_IMF_Context_Group
269  */
270 EAPI void
271 ecore_imf_context_del(Ecore_IMF_Context *ctx)
272 {
273    Ecore_IMF_Func_Node *fn;
274
275    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
276      {
277         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
278                          "ecore_imf_context_del");
279         return;
280      }
281    if (ctx->klass->del) ctx->klass->del(ctx);
282
283    if (ctx->callbacks)
284      {
285         EINA_LIST_FREE(ctx->callbacks, fn)
286            free(fn);
287      }
288
289    ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE);
290    free(ctx);
291 }
292
293 /**
294  * Set the client window for the Input Method Context; this is the
295  * Ecore_X_Window when using X11, Ecore_Win32_Window when using Win32, etc.
296  * This window is used in order to correctly position status windows, and may
297  * also be used for purposes internal to the Input Method Context.
298  *
299  * @param ctx An #Ecore_IMF_Context.
300  * @param window The client window. This may be @c NULL to indicate
301  *               that the previous client window no longer exists.
302  * @ingroup Ecore_IMF_Context_Group
303  */
304 EAPI void
305 ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
306 {
307    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
308      {
309         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
310                          "ecore_imf_context_client_window_set");
311         return;
312      }
313    if (ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window);
314    ctx->window = window;
315 }
316
317 /**
318  * Get the client window of the Input Method Context
319  *
320  * See @ref ecore_imf_context_client_window_set for more details.
321  *
322  * @param ctx An #Ecore_IMF_Context.
323  * @return Return the client window.
324  * @ingroup Ecore_IMF_Context_Group
325  * @since 1.1.0
326  */
327 EAPI void *
328 ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx)
329 {
330    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
331      {
332         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
333                          "ecore_imf_context_client_window_get");
334         return NULL;
335      }
336    return ctx->window;
337 }
338
339 /**
340  * Set the client canvas for the Input Method Context; this is the
341  * canvas in which the input appears.
342  * The canvas type can be determined by using the context canvas type.
343  * Actually only canvas with type "evas" (Evas *) is supported.
344  * This canvas may be used in order to correctly position status windows, and may
345  * also be used for purposes internal to the Input Method Context.
346  *
347  * @param ctx An #Ecore_IMF_Context.
348  * @param canvas The client canvas. This may be @c NULL to indicate
349  *               that the previous client canvas no longer exists.
350  * @ingroup Ecore_IMF_Context_Group
351  */
352 EAPI void
353 ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
354 {
355    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
356      {
357         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
358                          "ecore_imf_context_client_canvas_set");
359         return;
360      }
361    if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas);
362    ctx->client_canvas = canvas;
363 }
364
365 /**
366  * Get the client canvas of the Input Method Context.
367  *
368  * See @ref ecore_imf_context_client_canvas_set for more details.
369  *
370  * @param ctx An #Ecore_IMF_Context.
371  * @return Return the client canvas.
372  * @ingroup Ecore_IMF_Context_Group
373  * @since 1.1.0
374  */
375 EAPI void *
376 ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx)
377 {
378    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
379      {
380         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
381                          "ecore_imf_context_client_canvas_get");
382         return NULL;
383      }
384    return ctx->client_canvas;
385 }
386
387 /**
388  * Ask the Input Method Context to show itself.
389  *
390  * @param ctx An #Ecore_IMF_Context.
391  * @ingroup Ecore_IMF_Context_Group
392  */
393 EAPI void
394 ecore_imf_context_show(Ecore_IMF_Context *ctx)
395 {
396    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
397      {
398         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
399                          "ecore_imf_context_show");
400         return;
401      }
402    if (ctx->klass->show) ctx->klass->show(ctx);
403 }
404
405 /**
406  * Ask the Input Method Context to hide itself.
407  *
408  * @param ctx An #Ecore_IMF_Context.
409  * @ingroup Ecore_IMF_Context_Group
410  */
411 EAPI void
412 ecore_imf_context_hide(Ecore_IMF_Context *ctx)
413 {
414    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
415      {
416         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
417                          "ecore_imf_context_hide");
418         return;
419      }
420    if (ctx->klass->hide) ctx->klass->hide(ctx);
421 }
422
423 /**
424  * Retrieve the current preedit string and cursor position
425  * for the Input Method Context.
426  *
427  * @param ctx An #Ecore_IMF_Context.
428  * @param str Location to store the retrieved string. The
429  *            string retrieved must be freed with free().
430  * @param cursor_pos Location to store position of cursor (in characters)
431  *                   within the preedit string.
432  * @ingroup Ecore_IMF_Context_Group
433  */
434 EAPI void
435 ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos)
436 {
437    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
438      {
439         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
440                          "ecore_imf_context_preedit_string_get");
441         return;
442      }
443    if (ctx->klass->preedit_string_get)
444      ctx->klass->preedit_string_get(ctx, str, cursor_pos);
445    else
446      {
447         if (str) *str = strdup("");
448         if (cursor_pos) *cursor_pos = 0;
449      }
450 }
451
452 /**
453  * Retrieve the current preedit string, attributes and
454  * cursor position for the Input Method Context.
455  *
456  * @param ctx An #Ecore_IMF_Context.
457  * @param str Location to store the retrieved string. The
458  *            string retrieved must be freed with free().
459  * @param attrs an Eina_List of attributes
460  * @param cursor_pos Location to store position of cursor (in characters)
461  *                   within the preedit string.
462  * @ingroup Ecore_IMF_Context_Group
463  *
464  * Example
465  * @code
466  * char *preedit_string;
467  * int cursor_pos;
468  * Eina_List *attrs = NULL, *l = NULL;
469  * Ecore_IMF_Preedit_Attr *attr;
470  *
471  * ecore_imf_context_preedit_string_with_attributes_get(imf_context,
472  *                                                      &preedit_string,
473  *                                                      &attrs, &cursor_pos);
474  * if (!preedit_string) return;
475  *
476  *  if (strlen(preedit_string) > 0)
477  *    {
478  *       if (attrs)
479  *         {
480  *            EINA_LIST_FOREACH(attrs, l, attr)
481  *              {
482  *                 if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
483  *                   {
484  *                      // Something to do
485  *                   }
486  *                 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2)
487  *                   {
488  *                      // Something to do
489  *                   }
490  *                 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
491  *                   {
492  *                      // Something to do
493  *                   }
494  *              }
495  *         }
496  *    }
497  * 
498  * // delete attribute list
499  * EINA_LIST_FREE(attrs, attr) free(attr);
500  *
501  * free(preedit_string);
502  * @endcode
503  * @since 1.1.0
504  */
505 EAPI void
506 ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos)
507 {
508    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
509      {
510         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
511                          "ecore_imf_context_preedit_string_with_attributes_get");
512         return;
513      }
514    if (ctx->klass->preedit_string_with_attributes_get)
515      ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos);
516    else
517      {
518         if (str) *str = strdup("");
519         if (attrs) *attrs = NULL;
520         if (cursor_pos) *cursor_pos = 0;
521      }
522 }
523
524 /**
525  * Notify the Input Method Context that the widget to which its
526  * correspond has gained focus.
527  *
528  * @param ctx An #Ecore_IMF_Context.
529  * @ingroup Ecore_IMF_Context_Group
530  *
531  * Example
532  * @code
533  * static void
534  * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source)
535  * {
536  *    ecore_imf_context_reset(imf_context);
537  *    ecore_imf_context_focus_in(imf_context);
538  * }
539  *
540  * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed);
541  * @endcode
542  */
543 EAPI void
544 ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
545 {
546    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
547      {
548         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
549                          "ecore_imf_context_focus_in");
550         return;
551      }
552    if (ctx->klass->focus_in) ctx->klass->focus_in(ctx);
553 }
554
555 /**
556  * Notify the Input Method Context that the widget to which its
557  * correspond has lost focus.
558  *
559  * @param ctx An #Ecore_IMF_Context.
560  * @ingroup Ecore_IMF_Context_Group
561  *
562  * Example
563  * @code
564  * static void
565  * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
566  * {
567  *    ecore_imf_context_reset(imf_context);
568  *    ecore_imf_context_focus_out(imf_context);
569  * }
570  *
571  * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
572  * @endcode
573  */
574 EAPI void
575 ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
576 {
577    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
578      {
579         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
580                          "ecore_imf_context_focus_out");
581         return;
582      }
583    if (ctx->klass->focus_out) ctx->klass->focus_out(ctx);
584 }
585
586 /**
587  * Notify the Input Method Context that a change such as a
588  * change in cursor position has been made. This will typically
589  * cause the Input Method Context to clear the preedit state.
590  *
591  * @param ctx An #Ecore_IMF_Context.
592  * @ingroup Ecore_IMF_Context_Group
593  * 
594  * Example
595  * @code
596  * static void
597  * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
598  * {
599  *    ecore_imf_context_reset(imf_context);
600  *    ecore_imf_context_focus_out(imf_context);
601  * }
602  *
603  * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
604  * @endcode
605  */
606 EAPI void
607 ecore_imf_context_reset(Ecore_IMF_Context *ctx)
608 {
609    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
610      {
611         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
612                          "ecore_imf_context_reset");
613         return;
614      }
615    if (ctx->klass->reset) ctx->klass->reset(ctx);
616 }
617
618 /**
619  * Notify the Input Method Context that a change in the cursor
620  * position has been made.
621  *
622  * @param ctx An #Ecore_IMF_Context.
623  * @param cursor_pos New cursor position in characters.
624  * @ingroup Ecore_IMF_Context_Group
625  */
626 EAPI void
627 ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
628 {
629    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
630      {
631         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
632                          "ecore_imf_context_cursor_position_set");
633         return;
634      }
635    if (ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos);
636 }
637
638 /**
639  * Notify the Input Method Context that a change in the cursor
640  * location has been made. The location is relative to the canvas.
641  * The cursor location can be used to determine the position of 
642  * candidate word window in the immodule.
643  *
644  * @param ctx An #Ecore_IMF_Context.
645  * @param x cursor x position.
646  * @param y cursor y position.
647  * @param w cursor width.
648  * @param h cursor height.
649  * @ingroup Ecore_IMF_Context_Group
650  * @since 1.1.0
651  */
652 EAPI void
653 ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
654 {
655    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
656      {
657         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
658                          "ecore_imf_context_cursor_location_set");
659         return;
660      }
661    if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h);
662 }
663
664 /**
665  * Set whether the IM context should use the preedit string
666  * to display feedback. If @c use_preedit is @c EINA_FALSE (default
667  * is @c EINA_TRUE), then the IM context may use some other method to display
668  * feedback, such as displaying it in a child of the root window.
669  *
670  * @param ctx An #Ecore_IMF_Context.
671  * @param use_preedit Whether the IM context should use the preedit string.
672  * @ingroup Ecore_IMF_Context_Group
673  */
674 EAPI void
675 ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
676 {
677    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
678      {
679         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
680                          "ecore_imf_context_use_preedit_set");
681         return;
682      }
683    if (ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit);
684 }
685
686 /**
687  * Set whether the IM context should allow to use the text prediction.
688  * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM
689  * context will not display the text prediction window.
690  *
691  * @param ctx An #Ecore_IMF_Context.
692  * @param prediction Whether the IM context should allow to use the text prediction.
693  * @ingroup Ecore_IMF_Context_Group
694  * @since 1.1.0
695  */
696 EAPI void
697 ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction)
698 {
699    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
700      {
701         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
702                          "ecore_imf_context_prediction_allow_set");
703         return;
704      }
705
706    ctx->allow_prediction = prediction;
707
708    if (ctx->klass->prediction_allow_set)
709      ctx->klass->prediction_allow_set(ctx, prediction);
710 }
711
712 /**
713  * Get whether the IM context should allow to use the text prediction.
714  *
715  * @param ctx An #Ecore_IMF_Context.
716  * @return @c EINA_TRUE if it allows to use the text prediction, otherwise
717  * @c EINA_FALSE.
718  * @ingroup Ecore_IMF_Context_Group
719  * @since 1.1.0
720  */
721 EAPI Eina_Bool
722 ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx)
723 {
724    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
725      {
726         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
727                          "ecore_imf_context_prediction_allow_get");
728         return EINA_FALSE;
729      }
730
731    return ctx->allow_prediction;
732 }
733
734 /**
735  * Set the autocapitalization type on the immodule.
736  *
737  * @param ctx An #Ecore_IMF_Context.
738  * @param autocapital_type the autocapitalization type.
739  * @ingroup Ecore_IMF_Context_Group
740  * @since 1.1.0
741  */
742 EAPI void
743 ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type)
744 {
745    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
746      {
747         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
748                          "ecore_imf_context_autocapital_type_set");
749         return;
750      }
751
752    ctx->autocapital_type = autocapital_type;
753
754    if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type);
755 }
756
757 /**
758  * Get the autocapitalization type.
759  *
760  * @param ctx An #Ecore_IMF_Context.
761  * @return The autocapital type being used by @p ctx.
762  * @ingroup Ecore_IMF_Context_Group
763  * @since 1.1.0
764  */
765 EAPI Ecore_IMF_Autocapital_Type
766 ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx)
767 {
768    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
769      {
770         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
771                          "ecore_imf_context_autocapital_allow_get");
772         return ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
773      }
774
775    return ctx->autocapital_type;
776 }
777
778 /**
779  * Set the callback to be used on surrounding_get request.
780  *
781  * This callback will be called when the Input Method Context
782  * module requests the surrounding context.
783  *
784  * @param ctx An #Ecore_IMF_Context.
785  * @param func The callback to be called.
786  * @param data The data pointer to be passed to @p func
787  * @ingroup Ecore_IMF_Context_Group
788  */
789 EAPI void
790 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)
791 {
792    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
793      {
794         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
795                          "ecore_imf_context_retrieve_surrounding_callback_set");
796         return;
797      }
798
799    ctx->retrieve_surrounding_func = func;
800    ctx->retrieve_surrounding_data = (void *) data;
801 }
802
803 /**
804  * Set the input mode used by the Ecore Input Context.
805  *
806  * The input mode can be one of the input modes defined in
807  * Ecore_IMF_Input_Mode. The default input mode is
808  * ECORE_IMF_INPUT_MODE_FULL.
809  *
810  * @param ctx An #Ecore_IMF_Context.
811  * @param input_mode The input mode to be used by @p ctx.
812  * @ingroup Ecore_IMF_Context_Group
813  */
814 EAPI void
815 ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
816 {
817    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
818      {
819         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
820                          "ecore_imf_context_input_mode_set");
821         return;
822      }
823    if (ctx->klass->input_mode_set) ctx->klass->input_mode_set(ctx, input_mode);
824    ctx->input_mode = input_mode;
825 }
826
827 /**
828  * Get the input mode being used by the Ecore Input Context.
829  *
830  * See @ref ecore_imf_context_input_mode_set for more details.
831  *
832  * @param ctx An #Ecore_IMF_Context.
833  * @return The input mode being used by @p ctx.
834  * @ingroup Ecore_IMF_Context_Group
835  */
836 EAPI Ecore_IMF_Input_Mode
837 ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx)
838 {
839    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
840      {
841         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
842                          "ecore_imf_context_input_mode_set");
843         return 0;
844      }
845    return ctx->input_mode;
846 }
847
848 /**
849  * Allow an Ecore Input Context to internally handle an event.
850  * If this function returns @c EINA_TRUE, then no further processing
851  * should be done for this event.
852  *
853  * Input methods must be able to accept all types of events (simply
854  * returning @c EINA_FALSE if the event was not handled), but there is no
855  * obligation of any events to be submitted to this function.
856  *
857  * @param ctx An #Ecore_IMF_Context.
858  * @param type The type of event defined by #Ecore_IMF_Event_Type.
859  * @param event The event itself.
860  * @return @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE.
861  * @ingroup Ecore_IMF_Context_Group
862  *
863  * Example
864  * @code
865  * static void
866  * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
867  * {
868  *    Evas_Event_Key_Down *ev = event_info;
869  *    if (!ev->keyname) return;
870  *
871  *    if (imf_context)
872  *      {
873  *         Ecore_IMF_Event_Key_Down ecore_ev;
874  *         ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
875  *         if (ecore_imf_context_filter_event(imf_context,
876  *                                            ECORE_IMF_EVENT_KEY_DOWN,
877  *                                            (Ecore_IMF_Event *)&ecore_ev))
878  *           return;
879  *      }
880  * }
881  *
882  * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data);
883  * @endcode
884  */
885 EAPI Eina_Bool
886 ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
887 {
888    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
889      {
890         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
891                          "ecore_imf_context_filter_event");
892         return EINA_FALSE;
893      }
894    if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event);
895    return EINA_FALSE;
896 }
897
898 /**
899  * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions
900  *
901  * Functions that should be used by Ecore Input Method Context modules.
902  */
903
904 /**
905  * Creates a new Input Method Context with klass specified by @p ctxc.
906  *
907  * This method should be used by modules implementing the Input
908  * Method Context interface.
909  *
910  * @param ctxc An #Ecore_IMF_Context_Class.
911  * @return A new #Ecore_IMF_Context; on failure it returns NULL.
912  * @ingroup Ecore_IMF_Context_Module_Group
913  */
914 EAPI Ecore_IMF_Context *
915 ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc)
916 {
917    Ecore_IMF_Context *ctx;
918
919    if (!ctxc) return NULL;
920    ctx = calloc(1, sizeof(Ecore_IMF_Context));
921    if (!ctx) return NULL;
922    ECORE_MAGIC_SET(ctx, ECORE_MAGIC_CONTEXT);
923    ctx->klass = ctxc;
924    ctx->data = NULL;
925    ctx->retrieve_surrounding_func = NULL;
926    ctx->retrieve_surrounding_data = NULL;
927    return ctx;
928 }
929
930 /**
931  * Set the Input Method Context specific data.
932  *
933  * Note that this method should be used by modules to set
934  * the Input Method Context specific data and it's not meant to
935  * be used by applications to store application specific data.
936  *
937  * @param ctx An #Ecore_IMF_Context.
938  * @param data The Input Method Context specific data.
939  * @return A new #Ecore_IMF_Context; on failure it returns NULL.
940  * @ingroup Ecore_IMF_Context_Module_Group
941  */
942 EAPI void
943 ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data)
944 {
945    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
946      {
947         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
948                          "ecore_imf_context_data_set");
949         return;
950      }
951    ctx->data = data;
952 }
953
954 /**
955  * Get the Input Method Context specific data.
956  *
957  * See @ref ecore_imf_context_data_set for more details.
958  *
959  * @param ctx An #Ecore_IMF_Context.
960  * @return The Input Method Context specific data.
961  * @ingroup Ecore_IMF_Context_Module_Group
962  */
963 EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx)
964 {
965    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
966      {
967         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
968                          "ecore_imf_context_data_get");
969         return NULL;
970      }
971    return ctx->data;
972 }
973
974 /**
975  * Retrieve context around insertion point.
976  * Input methods typically want context in order to constrain input text based on existing text; 
977  * this is important for languages such as Thai where only some sequences of characters are allowed.
978  * In addition, the text around the insertion point can be used for supporting autocapital feature.
979  *
980  * This function is implemented by calling the
981  * Ecore_IMF_Context::retrieve_surrounding_func (
982  * set using #ecore_imf_context_retrieve_surrounding_callback_set).
983  *
984  * There is no obligation for a widget to respond to the
985  * retrieve_surrounding_func, so input methods must be prepared
986  * to function without context.
987  *
988  * @param ctx An #Ecore_IMF_Context.
989  * @param text Location to store a UTF-8 encoded string of text
990  *             holding context around the insertion point.
991  *             If the function returns @c EINA_TRUE, then you must free
992  *             the result stored in this location with free().
993  * @param cursor_pos Location to store the position in characters of
994  *                   the insertion cursor within @p text.
995  * @return @c EINA_TRUE if surrounding text was provided; otherwise
996  * @c EINA_FALSE.
997  * @ingroup Ecore_IMF_Context_Module_Group
998  */
999 EAPI Eina_Bool
1000 ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos)
1001 {
1002    int result = EINA_FALSE;
1003
1004    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1005      {
1006         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1007                          "ecore_imf_context_surrounding_get");
1008         return EINA_FALSE;
1009      }
1010
1011    if (ctx->retrieve_surrounding_func)
1012      {
1013         result = ctx->retrieve_surrounding_func(ctx->retrieve_surrounding_data, ctx, text, cursor_pos);
1014         if (!result)
1015           {
1016              if (text) *text = NULL;
1017              if (cursor_pos) *cursor_pos = 0;
1018           }
1019      }
1020    return result;
1021 }
1022
1023 static void
1024 _ecore_imf_event_free_preedit(void *data __UNUSED__, void *event)
1025 {
1026    free(event);
1027 }
1028
1029 /**
1030  * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue.
1031  *
1032  * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts.
1033  * It's asynchronous method to put event to the event queue.
1034  * ecore_imf_context_event_callback_call() can be used as synchronous method.
1035  *
1036  * @param ctx An #Ecore_IMF_Context.
1037  * @ingroup Ecore_IMF_Context_Module_Group
1038  */
1039 EAPI void
1040 ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx)
1041 {
1042    Ecore_IMF_Event_Commit *ev;
1043
1044    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1045      {
1046         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1047                          "ecore_imf_context_preedit_start_event_add");
1048         return;
1049      }
1050
1051    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Start));
1052    ev->ctx = ctx;
1053    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_START,
1054                    ev, _ecore_imf_event_free_preedit, NULL);
1055 }
1056
1057 /**
1058  * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue.
1059  *
1060  * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled.
1061  * It's asynchronous method to put event to the event queue.
1062  * ecore_imf_context_event_callback_call() can be used as synchronous method.
1063  *
1064  * @param ctx An #Ecore_IMF_Context.
1065  * @ingroup Ecore_IMF_Context_Module_Group
1066  */
1067 EAPI void
1068 ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx)
1069 {
1070    Ecore_IMF_Event_Commit *ev;
1071
1072    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1073      {
1074         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1075                          "ecore_imf_context_preedit_end_event_add");
1076         return;
1077      }
1078
1079    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_End));
1080    ev->ctx = ctx;
1081    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_END,
1082                    ev, _ecore_imf_event_free_preedit, NULL);
1083 }
1084
1085 /**
1086  * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue.
1087  *
1088  * It's asynchronous method to put event to the event queue.
1089  * ecore_imf_context_event_callback_call() can be used as synchronous method.
1090  *
1091  * @param ctx An #Ecore_IMF_Context.
1092  * @ingroup Ecore_IMF_Context_Module_Group
1093  */
1094 EAPI void
1095 ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx)
1096 {
1097    Ecore_IMF_Event_Commit *ev;
1098
1099    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1100      {
1101         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1102                          "ecore_imf_context_preedit_changed_event_add");
1103         return;
1104      }
1105
1106    ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Changed));
1107    ev->ctx = ctx;
1108    ecore_event_add(ECORE_IMF_EVENT_PREEDIT_CHANGED,
1109                    ev, _ecore_imf_event_free_preedit, NULL);
1110 }
1111
1112 static void
1113 _ecore_imf_event_free_commit(void *data __UNUSED__, void *event)
1114 {
1115    Ecore_IMF_Event_Commit *ev;
1116
1117    ev = event;
1118    if (ev->str) free(ev->str);
1119    free(ev);
1120 }
1121
1122 /**
1123  * Adds ECORE_IMF_EVENT_COMMIT to the event queue.
1124  *
1125  * It's asynchronous method to put event to the event queue.
1126  * ecore_imf_context_event_callback_call() can be used as synchronous method.
1127  *
1128  * @param ctx An #Ecore_IMF_Context.
1129  * @param str The committed string.
1130  * @ingroup Ecore_IMF_Context_Module_Group
1131  */
1132 EAPI void
1133 ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str)
1134 {
1135    Ecore_IMF_Event_Commit *ev;
1136
1137    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1138      {
1139         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1140                          "ecore_imf_context_commit_event_add");
1141         return;
1142      }
1143
1144    ev = malloc(sizeof(Ecore_IMF_Event_Commit));
1145    ev->ctx = ctx;
1146    ev->str = str ? strdup(str) : NULL;
1147    ecore_event_add(ECORE_IMF_EVENT_COMMIT,
1148                    ev, _ecore_imf_event_free_commit, NULL);
1149
1150 }
1151
1152 static void
1153 _ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event)
1154 {
1155    free(event);
1156 }
1157
1158 /**
1159  * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
1160  *
1161  * Asks the widget that the input context is attached to to delete characters around the cursor position
1162  * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
1163  * Note that offset and n_chars are in characters not in bytes.
1164  *
1165  * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue.
1166  * ecore_imf_context_event_callback_call() can be used as synchronous method.
1167  *
1168  * @param ctx An #Ecore_IMF_Context.
1169  * @param offset The start offset of surrounding to be deleted.
1170  * @param n_chars The number of characters to be deleted.
1171  * @ingroup Ecore_IMF_Context_Module_Group
1172  */
1173 EAPI void
1174 ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars)
1175 {
1176    Ecore_IMF_Event_Delete_Surrounding *ev;
1177
1178    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1179      {
1180         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1181                          "ecore_imf_context_delete_surrounding_event_add");
1182         return;
1183      }
1184
1185    ev = malloc(sizeof(Ecore_IMF_Event_Delete_Surrounding));
1186    ev->ctx = ctx;
1187    ev->offset = offset;
1188    ev->n_chars = n_chars;
1189    ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
1190                    ev, _ecore_imf_event_free_delete_surrounding, NULL);
1191 }
1192
1193 /**
1194  * Add (register) a callback function to a given context event.
1195  *
1196  * This function adds a function callback to the context @p ctx when the
1197  * event of type @p type occurs on it. The function pointer is @p
1198  * func.
1199  *
1200  * The event type @p type to trigger the function may be one of
1201  * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END,
1202  * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and
1203  * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING.
1204  *
1205  * @param ctx Ecore_IMF_Context to attach a callback to.
1206  * @param type The type of event that will trigger the callback
1207  * @param func The (callback) function to be called when the event is
1208  *        triggered
1209  * @param data The data pointer to be passed to @p func
1210  * @ingroup Ecore_IMF_Context_Group
1211  * @since 1.2.0
1212  *
1213  * Example
1214  * @code
1215  * static void
1216  * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info)
1217  * {
1218  *    char *commit_str = event_info;
1219  *    // something to do
1220  * }
1221  *
1222  * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data);
1223  * @endcode
1224  */
1225 EAPI void
1226 ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data)
1227 {
1228    Ecore_IMF_Func_Node *fn = NULL;
1229
1230    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1231      {
1232         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1233                          "ecore_imf_context_event_callback_add");
1234         return;
1235      }
1236
1237    if (!func) return;
1238
1239    fn = calloc(1, sizeof (Ecore_IMF_Func_Node));
1240    if (!fn) return;
1241
1242    fn->func = func;
1243    fn->data = data;
1244    fn->type = type;
1245
1246    ctx->callbacks = eina_list_append(ctx->callbacks, fn);
1247 }
1248
1249 /**
1250  * Delete (unregister) a callback function registered to a given
1251  * context event.
1252  *
1253  * This function removes a function callback from the context @p ctx when the
1254  * event of type @p type occurs on it. The function pointer is @p
1255  * func.
1256  *
1257  * @see ecore_imf_context_event_callback_add() for more details
1258  *
1259  * @param ctx Ecore_IMF_Context to remove a callback from.
1260  * @param type The type of event that was triggering the callback
1261  * @param func The (callback) function that was to be called when the event was triggered
1262  * @return the data pointer
1263  * @ingroup Ecore_IMF_Context_Group
1264  * @since 1.2.0
1265  */
1266 EAPI void *
1267 ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func)
1268 {
1269    Eina_List *l = NULL;
1270    Eina_List *l_next = NULL;
1271    Ecore_IMF_Func_Node *fn = NULL;
1272
1273    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1274      {
1275         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1276                          "ecore_imf_context_event_callback_del");
1277         return NULL;
1278      }
1279
1280    if (!func) return NULL;
1281    if (!ctx->callbacks) return NULL;
1282
1283    EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn)
1284      {
1285         if ((fn) && (fn->func == func) && (fn->type == type))
1286           {
1287              void *tmp = (void *)fn->data;
1288              free(fn);
1289              ctx->callbacks = eina_list_remove_list(ctx->callbacks, l);
1290              return tmp;
1291           }
1292      }
1293    return NULL;
1294 }
1295
1296 /**
1297  * Call a given callback on the context @p ctx.
1298  *
1299  * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), 
1300  * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and
1301  * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous 
1302  * because those API adds each event to the event queue.
1303  *
1304  * This API provides the way to call each callback function immediately.
1305  *
1306  * @param ctx Ecore_IMF_Context.
1307  * @param type The type of event that will trigger the callback
1308  * @param event_info The pointer to event specific struct or information to
1309  *        pass to the callback functions registered on this event
1310  * @ingroup Ecore_IMF_Context_Module_Group
1311  * @since 1.2.0
1312  */
1313 EAPI void
1314 ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info)
1315 {
1316    Ecore_IMF_Func_Node *fn = NULL;
1317    Eina_List *l = NULL;
1318
1319    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1320      {
1321         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1322                          "ecore_imf_context_event_callback_call");
1323         return;
1324      }
1325
1326    EINA_LIST_FOREACH(ctx->callbacks, l, fn)
1327      {
1328         if ((fn) && (fn->type == type) && (fn->func))
1329           fn->func(fn->data, ctx, event_info);
1330      }
1331 }
1332
1333 /**
1334  * Ask the Input Method Context to show the control panel of using Input Method.
1335  *
1336  * @param ctx An #Ecore_IMF_Context.
1337  * @ingroup Ecore_IMF_Context_Group
1338  * @since 1.1.0
1339  */
1340 EAPI void
1341 ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx)
1342 {
1343    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1344      {
1345         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1346                          "ecore_imf_context_control_panel_show");
1347         return;
1348      }
1349
1350    if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx);
1351 }
1352
1353 /**
1354  * Ask the Input Method Context to hide the control panel of using Input Method.
1355  *
1356  * @param ctx An #Ecore_IMF_Context.
1357  * @ingroup Ecore_IMF_Context_Group
1358  * @since 1.1.0
1359  */
1360 EAPI void
1361 ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx)
1362 {
1363    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1364      {
1365         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1366                          "ecore_imf_context_control_panel_hide");
1367         return;
1368      }
1369
1370    if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx);
1371 }
1372
1373 /**
1374  * Ask the Input Method Context to show the input panel (virtual keyboard).
1375  *
1376  * @param ctx An #Ecore_IMF_Context.
1377  * @ingroup Ecore_IMF_Context_Group
1378  * @since 1.1.0
1379  */
1380 EAPI void
1381 ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
1382 {
1383    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1384      {
1385         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1386                          "ecore_imf_context_input_panel_show");
1387         return;
1388      }
1389
1390    if (ctx->klass->show) ctx->klass->show(ctx);
1391 }
1392
1393 /**
1394  * Ask the Input Method Context to hide the input panel.
1395  *
1396  * @param ctx An #Ecore_IMF_Context.
1397  * @ingroup Ecore_IMF_Context_Group
1398  * @since 1.1.0
1399  */
1400 EAPI void
1401 ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
1402 {
1403    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1404      {
1405         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1406                          "ecore_imf_context_input_panel_hide");
1407         return;
1408      }
1409
1410    if (ctx->klass->hide) ctx->klass->hide(ctx);
1411 }
1412
1413 /**
1414  * Set the layout of the input panel.
1415  *
1416  * @param ctx An #Ecore_IMF_Context.
1417  * @param layout see #Ecore_IMF_Input_Panel_Layout
1418  * @ingroup Ecore_IMF_Context_Group
1419  * @since 1.1.0
1420  */
1421 EAPI void
1422 ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout)
1423 {
1424    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1425      {
1426         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1427                          "ecore_imf_context_input_panel_layout_set");
1428         return;
1429      }
1430
1431    if (ctx->klass->input_panel_layout_set)
1432      ctx->klass->input_panel_layout_set(ctx, layout);
1433
1434    ctx->input_panel_layout = layout;
1435 }
1436
1437 /**
1438  * Get the layout of the current active input panel.
1439  *
1440  * @param ctx An #Ecore_IMF_Context.
1441  * @return layout see #Ecore_IMF_Input_Panel_Layout
1442  * @ingroup Ecore_IMF_Context_Group
1443  * @since 1.1.0
1444  */
1445 EAPI Ecore_IMF_Input_Panel_Layout
1446 ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
1447 {
1448    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1449      {
1450         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1451                          "ecore_imf_context_input_panel_layout_get");
1452         return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
1453      }
1454
1455    if (ctx->klass->input_panel_layout_get)
1456      return ctx->input_panel_layout;
1457    else
1458      return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
1459 }
1460
1461 /**
1462  * Set the language of the input panel.
1463  * This API can be used when you want to show the English keyboard.
1464  *
1465  * @param ctx An #Ecore_IMF_Context.
1466  * @param lang the language to be set to the input panel.
1467  * @ingroup Ecore_IMF_Context_Group
1468  * @since 1.1.0
1469  */
1470 EAPI void
1471 ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang)
1472 {
1473    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1474      {
1475         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1476                          "ecore_imf_context_input_panel_language_set");
1477         return;
1478      }
1479
1480    if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang);
1481    ctx->input_panel_lang = lang;
1482 }
1483
1484 /**
1485  * Get the language of the input panel.
1486  *
1487  * See @ref ecore_imf_context_input_panel_language_set for more details.
1488  *
1489  * @param ctx An #Ecore_IMF_Context.
1490  * @return Ecore_IMF_Input_Panel_Lang
1491  * @ingroup Ecore_IMF_Context_Group
1492  * @since 1.1.0
1493  */
1494 EAPI Ecore_IMF_Input_Panel_Lang
1495 ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx)
1496 {
1497    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1498      {
1499         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1500                          "ecore_imf_context_input_panel_language_get");
1501         return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
1502      }
1503
1504    return ctx->input_panel_lang;
1505 }
1506
1507 /**
1508  * Set whether the Input Method Context should request to show the input panel automatically
1509  * when the widget has focus.
1510  *
1511  * @param ctx An #Ecore_IMF_Context.
1512  * @param enabled If true, the input panel will be shown when the widget is clicked or has focus.
1513  * @ingroup Ecore_IMF_Context_Group
1514  * @since 1.1.0
1515  */
1516 EAPI void
1517 ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx,
1518                                            Eina_Bool enabled)
1519 {
1520    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1521      {
1522         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1523                          "ecore_imf_context_input_panel_enabled_set");
1524         return;
1525      }
1526
1527    ctx->input_panel_enabled = enabled;
1528 }
1529
1530 /**
1531  * Get whether the Input Method Context requests to show the input panel automatically.
1532  *
1533  * @param ctx An #Ecore_IMF_Context.
1534  * @return Return the attribute to show the input panel automatically
1535  * @ingroup Ecore_IMF_Context_Group
1536  * @since 1.1.0
1537  */
1538 EAPI Eina_Bool
1539 ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx)
1540 {
1541    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1542      {
1543         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1544                          "ecore_imf_context_input_panel_enabled_get");
1545         return EINA_FALSE;
1546      }
1547
1548    return ctx->input_panel_enabled;
1549 }
1550
1551 /**
1552  * Set the input panel-specific data to deliver to the input panel.
1553  * This API is used by applications to deliver specific data to the input panel.
1554  * The data format MUST be negotiated by both application and the input panel.
1555  * The size and format of data are defined by the input panel.
1556  *
1557  * @param ctx An #Ecore_IMF_Context.
1558  * @param data The specific data to be set to the input panel.
1559  * @param len the length of data, in bytes, to send to the input panel
1560  * @ingroup Ecore_IMF_Context_Group
1561  * @since 1.2.0
1562  */
1563 EAPI void
1564 ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len)
1565 {
1566    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1567      {
1568         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1569                          "ecore_imf_context_input_panel_imdata_set");
1570         return;
1571      }
1572
1573    if (!data) return;
1574
1575    if (ctx->klass->input_panel_imdata_set)
1576      ctx->klass->input_panel_imdata_set(ctx, data, len);
1577 }
1578
1579 /**
1580  * Get the specific data of the current active input panel.
1581  *
1582  * @param ctx An #Ecore_IMF_Context.
1583  * @param data The specific data to be got from the input panel
1584  * @param len The length of data
1585  * @ingroup Ecore_IMF_Context_Group
1586  * @since 1.2.0
1587  */
1588 EAPI void
1589 ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len)
1590 {
1591    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1592      {
1593         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1594                          "ecore_imf_context_input_panel_imdata_get");
1595         return;
1596      }
1597
1598    if (!data) return;
1599
1600    if (ctx->klass->input_panel_imdata_get)
1601      ctx->klass->input_panel_imdata_get(ctx, data, len);
1602 }
1603
1604 /**
1605  * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel.
1606  *
1607  * An input panel displays the string or icon associated with this type
1608  *
1609  * @param ctx An #Ecore_IMF_Context.
1610  * @param return_key_type The type of "return" key on the input panel
1611  * @ingroup Ecore_IMF_Context_Group
1612  * @since 1.2.0
1613  */
1614 EAPI void
1615 ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
1616 {
1617    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1618      {
1619         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1620                          "ecore_imf_context_input_panel_return_key_type_set");
1621         return;
1622      }
1623
1624    ctx->input_panel_return_key_type = return_key_type;
1625    if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type);
1626 }
1627
1628 /**
1629  * Get the "return" key type.
1630  *
1631  * @see ecore_imf_context_input_panel_return_key_type_set() for more details
1632  *
1633  * @param ctx An #Ecore_IMF_Context.
1634  * @return The type of "return" key on the input panel
1635  * @ingroup Ecore_IMF_Context_Group
1636  * @since 1.2.0
1637  */
1638 EAPI Ecore_IMF_Input_Panel_Return_Key_Type
1639 ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx)
1640 {
1641    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1642      {
1643         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1644                          "ecore_imf_context_input_panel_return_key_type_get");
1645         return EINA_FALSE;
1646      }
1647
1648    return ctx->input_panel_return_key_type;
1649 }
1650
1651 /**
1652  * Set the return key on the input panel to be disabled.
1653  *
1654  * @param ctx An #Ecore_IMF_Context.
1655  * @param disabled The state
1656  * @ingroup Ecore_IMF_Context_Group
1657  * @since 1.2.0
1658  */
1659 EAPI void
1660 ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled)
1661 {
1662    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1663      {
1664         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1665                          "ecore_imf_context_input_panel_return_key_disabled_set");
1666         return;
1667      }
1668
1669    ctx->input_panel_return_key_disabled = disabled;
1670    if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled);
1671 }
1672
1673 /**
1674  * Get whether the return key on the input panel should be disabled or not.
1675  *
1676  * @param ctx An #Ecore_IMF_Context.
1677  * @return @c EINA_TRUE if it should be disabled.
1678  * @ingroup Ecore_IMF_Context_Group
1679  * @since 1.2.0
1680  */
1681 EAPI Eina_Bool
1682 ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx)
1683 {
1684    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1685      {
1686         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1687                          "ecore_imf_context_input_panel_return_key_disabled_get");
1688         return EINA_FALSE;
1689      }
1690
1691    return ctx->input_panel_return_key_disabled;
1692 }
1693
1694 /**
1695  * Set the caps lock mode on the input panel.
1696  *
1697  * @param ctx An #Ecore_IMF_Context.
1698  * @param mode Turn on caps lock on the input panel if @c EINA_TRUE.
1699  * @ingroup Ecore_IMF_Context_Group
1700  * @since 1.2.0
1701  */
1702 EAPI void
1703 ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode)
1704 {
1705    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1706      {
1707         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1708                          "ecore_imf_context_input_panel_caps_lock_mode_set");
1709         return;
1710      }
1711
1712    if (ctx->klass->input_panel_caps_lock_mode_set)
1713      ctx->klass->input_panel_caps_lock_mode_set(ctx, mode);
1714
1715    ctx->input_panel_caps_lock_mode = mode;
1716 }
1717
1718 /**
1719  * Get the caps lock mode on the input panel.
1720  *
1721  * @param ctx An #Ecore_IMF_Context.
1722  * @return @c EINA_TRUE if the caps lock is turned on.
1723  * @ingroup Ecore_IMF_Context_Group
1724  * @since 1.2.0
1725  */
1726 EAPI Eina_Bool
1727 ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx)
1728 {
1729    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
1730      {
1731         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
1732                          "ecore_imf_context_input_panel_caps_lock_mode_get");
1733         return EINA_FALSE;
1734      }
1735
1736    return ctx->input_panel_caps_lock_mode;
1737 }
1738