ecore_imf: insert example link in ecore_imf_context group
[framework/uifw/ecore.git] / src / lib / ecore_imf / ecore_imf_context.c
index 7d6d2b1..5f4e5dc 100644 (file)
  * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions
  *
  * Functions that operate on Ecore Input Method Context objects.
+
+ * Ecore Input Method Context Function defines the interface for EFL input methods. 
+ * An input method is used by EFL text input widgets like elm_entry 
+ * (based on edje_entry) to map from key events to Unicode character strings.
+ *
+ * The default input method can be set through setting the ECORE_IMF_MODULE environment variable.
+ *
+ * An input method may consume multiple key events in sequence and finally output the composed result. 
+ * This is called preediting, and an input method may provide feedback about 
+ * this process by displaying the intermediate composition states as preedit text.
+ *
+ * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n
+ * ecore_imf_init() should be called to initialize and load immodule.@n
+ * ecore_imf_shutdown() is used for shutdowning and unloading immodule.
+ *
+ * An example of usage of these functions can be found at:
+ * @li @ref ecore_imf_example_c
  */
 
 /**
@@ -51,16 +68,16 @@ ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type)
 static int
 _ecore_imf_context_match_locale(const char *locale, const char *against, int against_len)
 {
-  if (strcmp(against, "*") == 0)
-    return 1;
+   if (strcmp(against, "*") == 0)
+     return 1;
 
-  if (strcasecmp(locale, against) == 0)
-    return 4;
+   if (strcasecmp(locale, against) == 0)
+     return 4;
 
-  if (strncasecmp(locale, against, 2) == 0)
-    return (against_len == 2) ? 3 : 2;
+   if (strncasecmp(locale, against, 2) == 0)
+     return (against_len == 2) ? 3 : 2;
 
-  return 0;
+   return 0;
 }
 
 /**
@@ -122,13 +139,13 @@ ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type)
              const char *q = strchr(p, ':');
              int goodness = _ecore_imf_context_match_locale(locale, p, q ? (size_t)(q - p) : strlen (p));
 
-              if (goodness > best_goodness)
-                {
-                   id = module->info->id;
-                   best_goodness = goodness;
-                }
+             if (goodness > best_goodness)
+               {
+                  id = module->info->id;
+                  best_goodness = goodness;
+               }
 
-              p = q ? q + 1 : NULL;
+             p = q ? q + 1 : NULL;
           }
      }
 
@@ -143,6 +160,32 @@ ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type)
  * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id;
  *         on failure it returns NULL.
  * @ingroup Ecore_IMF_Context_Group
+ * 
+ * Example
+ * @code
+ *
+ * const char *ctx_id;
+ * const Ecore_IMF_Context_Info *ctx_info;
+ * Ecore_IMF_Context *imf_context;
+ * ctx_id = ecore_imf_context_default_id_get();
+ * if (ctx_id)
+ *   {
+ *      ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
+ *      if (!ctx_info->canvas_type ||
+ *          strcmp(ctx_info->canvas_type, "evas") == 0)
+ *        {
+ *           imf_context = ecore_imf_context_add(ctx_id);
+ *        }
+ *      else
+ *        {
+ *           ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
+ *           if (ctx_id)
+ *             {
+ *                imf_context = ecore_imf_context_add(ctx_id);
+ *             }
+ *        }
+ *   }
+ * @endcode
  */
 EAPI const Ecore_IMF_Context_Info *
 ecore_imf_context_info_by_id_get(const char *id)
@@ -175,6 +218,23 @@ ecore_imf_context_add(const char *id)
    /* default use_preedit is EINA_TRUE, so let's make sure it's
     * set on the immodule */
    ecore_imf_context_use_preedit_set(ctx, EINA_TRUE);
+
+   /* default prediction is EINA_TRUE, so let's make sure it's
+    * set on the immodule */
+   ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE);
+
+   /* default autocapital type is SENTENCE type, so let's make sure it's
+    * set on the immodule */
+   ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE);
+
+   /* default input panel enabled status is EINA_TRUE, so let's make sure it's
+    * set on the immodule */
+   ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE);
+
+   /* default input panel layout type is NORMAL type, so let's make sure it's
+    * set on the immodule */
+   ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
+
    /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's
     * set on the immodule */
    ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL);
@@ -210,6 +270,8 @@ ecore_imf_context_info_get(Ecore_IMF_Context *ctx)
 EAPI void
 ecore_imf_context_del(Ecore_IMF_Context *ctx)
 {
+   Ecore_IMF_Func_Node *fn;
+
    if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
      {
         ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
@@ -217,6 +279,13 @@ ecore_imf_context_del(Ecore_IMF_Context *ctx)
         return;
      }
    if (ctx->klass->del) ctx->klass->del(ctx);
+
+   if (ctx->callbacks)
+     {
+        EINA_LIST_FREE(ctx->callbacks, fn)
+           free(fn);
+     }
+
    ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE);
    free(ctx);
 }
@@ -228,7 +297,7 @@ ecore_imf_context_del(Ecore_IMF_Context *ctx)
  * also be used for purposes internal to the Input Method Context.
  *
  * @param ctx An #Ecore_IMF_Context.
- * @param window The client window. This may be NULL to indicate
+ * @param window The client window. This may be @c NULL to indicate
  *               that the previous client window no longer exists.
  * @ingroup Ecore_IMF_Context_Group
  */
@@ -242,6 +311,29 @@ ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
         return;
      }
    if (ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window);
+   ctx->window = window;
+}
+
+/**
+ * Get the client window of the Input Method Context
+ *
+ * See @ref ecore_imf_context_client_window_set for more details.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return Return the client window.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void *
+ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_client_window_get");
+        return NULL;
+     }
+   return ctx->window;
 }
 
 /**
@@ -253,7 +345,7 @@ ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
  * also be used for purposes internal to the Input Method Context.
  *
  * @param ctx An #Ecore_IMF_Context.
- * @param canvas The client canvas. This may be NULL to indicate
+ * @param canvas The client canvas. This may be @c NULL to indicate
  *               that the previous client canvas no longer exists.
  * @ingroup Ecore_IMF_Context_Group
  */
@@ -267,6 +359,29 @@ ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
         return;
      }
    if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas);
+   ctx->client_canvas = canvas;
+}
+
+/**
+ * Get the client canvas of the Input Method Context.
+ *
+ * See @ref ecore_imf_context_client_canvas_set for more details.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return Return the client canvas.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void *
+ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_client_canvas_get");
+        return NULL;
+     }
+   return ctx->client_canvas;
 }
 
 /**
@@ -335,11 +450,95 @@ ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cu
 }
 
 /**
+ * Retrieve the current preedit string, attributes and
+ * cursor position for the Input Method Context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param str Location to store the retrieved string. The
+ *            string retrieved must be freed with free().
+ * @param attrs an Eina_List of attributes
+ * @param cursor_pos Location to store position of cursor (in characters)
+ *                   within the preedit string.
+ * @ingroup Ecore_IMF_Context_Group
+ *
+ * Example
+ * @code
+ * char *preedit_string;
+ * int cursor_pos;
+ * Eina_List *attrs = NULL, *l = NULL;
+ * Ecore_IMF_Preedit_Attr *attr;
+ *
+ * ecore_imf_context_preedit_string_with_attributes_get(imf_context,
+ *                                                      &preedit_string,
+ *                                                      &attrs, &cursor_pos);
+ * if (!preedit_string) return;
+ *
+ *  if (strlen(preedit_string) > 0)
+ *    {
+ *       if (attrs)
+ *         {
+ *            EINA_LIST_FOREACH(attrs, l, attr)
+ *              {
+ *                 if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
+ *                   {
+ *                      // Something to do
+ *                   }
+ *                 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2)
+ *                   {
+ *                      // Something to do
+ *                   }
+ *                 else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
+ *                   {
+ *                      // Something to do
+ *                   }
+ *              }
+ *         }
+ *    }
+ * 
+ * // delete attribute list
+ * EINA_LIST_FREE(attrs, attr) free(attr);
+ *
+ * free(preedit_string);
+ * @endcode
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_preedit_string_with_attributes_get");
+        return;
+     }
+   if (ctx->klass->preedit_string_with_attributes_get)
+     ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos);
+   else
+     {
+        if (str) *str = strdup("");
+        if (attrs) *attrs = NULL;
+        if (cursor_pos) *cursor_pos = 0;
+     }
+}
+
+/**
  * Notify the Input Method Context that the widget to which its
  * correspond has gained focus.
  *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Group
+ *
+ * Example
+ * @code
+ * static void
+ * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source)
+ * {
+ *    ecore_imf_context_reset(imf_context);
+ *    ecore_imf_context_focus_in(imf_context);
+ * }
+ *
+ * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed);
+ * @endcode
  */
 EAPI void
 ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
@@ -359,6 +558,18 @@ ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
  *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Group
+ *
+ * Example
+ * @code
+ * static void
+ * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
+ * {
+ *    ecore_imf_context_reset(imf_context);
+ *    ecore_imf_context_focus_out(imf_context);
+ * }
+ *
+ * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
+ * @endcode
  */
 EAPI void
 ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
@@ -379,6 +590,18 @@ ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
  *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Group
+ * 
+ * Example
+ * @code
+ * static void
+ * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source)
+ * {
+ *    ecore_imf_context_reset(imf_context);
+ *    ecore_imf_context_focus_out(imf_context);
+ * }
+ *
+ * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed);
+ * @endcode
  */
 EAPI void
 ecore_imf_context_reset(Ecore_IMF_Context *ctx)
@@ -413,9 +636,35 @@ ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
 }
 
 /**
+ * Notify the Input Method Context that a change in the cursor
+ * location has been made. The location is relative to the canvas.
+ * The cursor location can be used to determine the position of 
+ * candidate word window in the immodule.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param x cursor x position.
+ * @param y cursor y position.
+ * @param w cursor width.
+ * @param h cursor height.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_cursor_location_set");
+        return;
+     }
+   if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h);
+}
+
+/**
  * Set whether the IM context should use the preedit string
- * to display feedback. If @use_preedit is EINA_FALSE (default
- * is EINA_TRUE), then the IM context may use some other method to display
+ * to display feedback. If @c use_preedit is @c EINA_FALSE (default
+ * is @c EINA_TRUE), then the IM context may use some other method to display
  * feedback, such as displaying it in a child of the root window.
  *
  * @param ctx An #Ecore_IMF_Context.
@@ -435,7 +684,99 @@ ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
 }
 
 /**
- * Set the callback to be used on get_surrounding request.
+ * Set whether the IM context should allow to use the text prediction.
+ * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM
+ * context will not display the text prediction window.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param prediction Whether the IM context should allow to use the text prediction.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_prediction_allow_set");
+        return;
+     }
+
+   ctx->allow_prediction = prediction;
+
+   if (ctx->klass->prediction_allow_set)
+     ctx->klass->prediction_allow_set(ctx, prediction);
+}
+
+/**
+ * Get whether the IM context should allow to use the text prediction.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return @c EINA_TRUE if it allows to use the text prediction, otherwise
+ * @c EINA_FALSE.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI Eina_Bool
+ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_prediction_allow_get");
+        return EINA_FALSE;
+     }
+
+   return ctx->allow_prediction;
+}
+
+/**
+ * Set the autocapitalization type on the immodule.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param autocapital_type the autocapitalization type.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_autocapital_type_set");
+        return;
+     }
+
+   ctx->autocapital_type = autocapital_type;
+
+   if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type);
+}
+
+/**
+ * Get the autocapitalization type.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return The autocapital type being used by @p ctx.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI Ecore_IMF_Autocapital_Type
+ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_autocapital_allow_get");
+        return ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
+     }
+
+   return ctx->autocapital_type;
+}
+
+/**
+ * Set the callback to be used on surrounding_get request.
  *
  * This callback will be called when the Input Method Context
  * module requests the surrounding context.
@@ -463,7 +804,7 @@ ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina
  * Set the input mode used by the Ecore Input Context.
  *
  * The input mode can be one of the input modes defined in
- * #Ecore_IMF_Input_Mode. The default input mode is
+ * Ecore_IMF_Input_Mode. The default input mode is
  * ECORE_IMF_INPUT_MODE_FULL.
  *
  * @param ctx An #Ecore_IMF_Context.
@@ -506,18 +847,40 @@ ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx)
 
 /**
  * Allow an Ecore Input Context to internally handle an event.
- * If this function returns EINA_TRUE, then no further processing
+ * If this function returns @c EINA_TRUE, then no further processing
  * should be done for this event.
  *
  * Input methods must be able to accept all types of events (simply
- * returning EINA_FALSE if the event was not handled), but there is no
+ * returning @c EINA_FALSE if the event was not handled), but there is no
  * obligation of any events to be submitted to this function.
  *
  * @param ctx An #Ecore_IMF_Context.
  * @param type The type of event defined by #Ecore_IMF_Event_Type.
  * @param event The event itself.
- * @return EINA_TRUE if the event was handled; otherwise EINA_FALSE.
+ * @return @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE.
  * @ingroup Ecore_IMF_Context_Group
+ *
+ * Example
+ * @code
+ * static void
+ * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+ * {
+ *    Evas_Event_Key_Down *ev = event_info;
+ *    if (!ev->keyname) return;
+ *
+ *    if (imf_context)
+ *      {
+ *         Ecore_IMF_Event_Key_Down ecore_ev;
+ *         ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
+ *         if (ecore_imf_context_filter_event(imf_context,
+ *                                            ECORE_IMF_EVENT_KEY_DOWN,
+ *                                            (Ecore_IMF_Event *)&ecore_ev))
+ *           return;
+ *      }
+ * }
+ *
+ * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data);
+ * @endcode
  */
 EAPI Eina_Bool
 ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
@@ -610,23 +973,27 @@ EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx)
 
 /**
  * Retrieve context around insertion point.
+ * Input methods typically want context in order to constrain input text based on existing text; 
+ * this is important for languages such as Thai where only some sequences of characters are allowed.
+ * In addition, the text around the insertion point can be used for supporting autocapital feature.
  *
  * This function is implemented by calling the
  * Ecore_IMF_Context::retrieve_surrounding_func (
  * set using #ecore_imf_context_retrieve_surrounding_callback_set).
  *
  * There is no obligation for a widget to respond to the
- * ::retrieve_surrounding_func, so input methods must be prepared
+ * retrieve_surrounding_func, so input methods must be prepared
  * to function without context.
  *
  * @param ctx An #Ecore_IMF_Context.
  * @param text Location to store a UTF-8 encoded string of text
  *             holding context around the insertion point.
- *             If the function returns EINA_TRUE, then you must free
+ *             If the function returns @c EINA_TRUE, then you must free
  *             the result stored in this location with free().
  * @param cursor_pos Location to store the position in characters of
- *                   the insertion cursor within @text.
- * @return EINA_TRUE if surrounding text was provided; otherwise EINA_FALSE.
+ *                   the insertion cursor within @p text.
+ * @return @c EINA_TRUE if surrounding text was provided; otherwise
+ * @c EINA_FALSE.
  * @ingroup Ecore_IMF_Context_Module_Group
  */
 EAPI Eina_Bool
@@ -662,6 +1029,10 @@ _ecore_imf_event_free_preedit(void *data __UNUSED__, void *event)
 /**
  * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue.
  *
+ * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts.
+ * It's asynchronous method to put event to the event queue.
+ * ecore_imf_context_event_callback_call() can be used as synchronous method.
+ *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Module_Group
  */
@@ -686,6 +1057,10 @@ ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx)
 /**
  * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue.
  *
+ * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled.
+ * It's asynchronous method to put event to the event queue.
+ * ecore_imf_context_event_callback_call() can be used as synchronous method.
+ *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Module_Group
  */
@@ -710,6 +1085,9 @@ ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx)
 /**
  * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue.
  *
+ * It's asynchronous method to put event to the event queue.
+ * ecore_imf_context_event_callback_call() can be used as synchronous method.
+ *
  * @param ctx An #Ecore_IMF_Context.
  * @ingroup Ecore_IMF_Context_Module_Group
  */
@@ -744,6 +1122,9 @@ _ecore_imf_event_free_commit(void *data __UNUSED__, void *event)
 /**
  * Adds ECORE_IMF_EVENT_COMMIT to the event queue.
  *
+ * It's asynchronous method to put event to the event queue.
+ * ecore_imf_context_event_callback_call() can be used as synchronous method.
+ *
  * @param ctx An #Ecore_IMF_Context.
  * @param str The committed string.
  * @ingroup Ecore_IMF_Context_Module_Group
@@ -777,6 +1158,13 @@ _ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event)
 /**
  * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
  *
+ * Asks the widget that the input context is attached to to delete characters around the cursor position
+ * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
+ * Note that offset and n_chars are in characters not in bytes.
+ *
+ * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue.
+ * ecore_imf_context_event_callback_call() can be used as synchronous method.
+ *
  * @param ctx An #Ecore_IMF_Context.
  * @param offset The start offset of surrounding to be deleted.
  * @param n_chars The number of characters to be deleted.
@@ -801,3 +1189,550 @@ ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offse
    ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
                    ev, _ecore_imf_event_free_delete_surrounding, NULL);
 }
+
+/**
+ * Add (register) a callback function to a given context event.
+ *
+ * This function adds a function callback to the context @p ctx when the
+ * event of type @p type occurs on it. The function pointer is @p
+ * func.
+ *
+ * The event type @p type to trigger the function may be one of
+ * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END,
+ * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and
+ * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING.
+ *
+ * @param ctx Ecore_IMF_Context to attach a callback to.
+ * @param type The type of event that will trigger the callback
+ * @param func The (callback) function to be called when the event is
+ *        triggered
+ * @param data The data pointer to be passed to @p func
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ *
+ * Example
+ * @code
+ * static void
+ * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info)
+ * {
+ *    char *commit_str = event_info;
+ *    // something to do
+ * }
+ *
+ * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data);
+ * @endcode
+ */
+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)
+{
+   Ecore_IMF_Func_Node *fn = NULL;
+
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_event_callback_add");
+        return;
+     }
+
+   if (!func) return;
+
+   fn = calloc(1, sizeof (Ecore_IMF_Func_Node));
+   if (!fn) return;
+
+   fn->func = func;
+   fn->data = data;
+   fn->type = type;
+
+   ctx->callbacks = eina_list_append(ctx->callbacks, fn);
+}
+
+/**
+ * Delete (unregister) a callback function registered to a given
+ * context event.
+ *
+ * This function removes a function callback from the context @p ctx when the
+ * event of type @p type occurs on it. The function pointer is @p
+ * func.
+ *
+ * @see ecore_imf_context_event_callback_add() for more details
+ *
+ * @param ctx Ecore_IMF_Context to remove a callback from.
+ * @param type The type of event that was triggering the callback
+ * @param func The (callback) function that was to be called when the event was triggered
+ * @return the data pointer
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI void *
+ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func)
+{
+   Eina_List *l = NULL;
+   Eina_List *l_next = NULL;
+   Ecore_IMF_Func_Node *fn = NULL;
+
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_event_callback_del");
+        return NULL;
+     }
+
+   if (!func) return NULL;
+   if (!ctx->callbacks) return NULL;
+
+   EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn)
+     {
+        if ((fn) && (fn->func == func) && (fn->type == type))
+          {
+             void *tmp = (void *)fn->data;
+             free(fn);
+             ctx->callbacks = eina_list_remove_list(ctx->callbacks, l);
+             return tmp;
+          }
+     }
+   return NULL;
+}
+
+/**
+ * Call a given callback on the context @p ctx.
+ *
+ * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), 
+ * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and
+ * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous 
+ * because those API adds each event to the event queue.
+ *
+ * This API provides the way to call each callback function immediately.
+ *
+ * @param ctx Ecore_IMF_Context.
+ * @param type The type of event that will trigger the callback
+ * @param event_info The pointer to event specific struct or information to
+ *        pass to the callback functions registered on this event
+ * @ingroup Ecore_IMF_Context_Module_Group
+ * @since 1.2.0
+ */
+EAPI void
+ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info)
+{
+   Ecore_IMF_Func_Node *fn = NULL;
+   Eina_List *l = NULL;
+
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_event_callback_call");
+        return;
+     }
+
+   EINA_LIST_FOREACH(ctx->callbacks, l, fn)
+     {
+        if ((fn) && (fn->type == type) && (fn->func))
+          fn->func(fn->data, ctx, event_info);
+     }
+}
+
+/**
+ * Ask the Input Method Context to show the control panel of using Input Method.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_control_panel_show");
+        return;
+     }
+
+   if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx);
+}
+
+/**
+ * Ask the Input Method Context to hide the control panel of using Input Method.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_control_panel_hide");
+        return;
+     }
+
+   if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx);
+}
+
+/**
+ * Ask the Input Method Context to show the input panel (virtual keyboard).
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_show");
+        return;
+     }
+
+   if (ctx->klass->show) ctx->klass->show(ctx);
+}
+
+/**
+ * Ask the Input Method Context to hide the input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_hide");
+        return;
+     }
+
+   if (ctx->klass->hide) ctx->klass->hide(ctx);
+}
+
+/**
+ * Set the layout of the input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param layout see #Ecore_IMF_Input_Panel_Layout
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_layout_set");
+        return;
+     }
+
+   if (ctx->klass->input_panel_layout_set)
+     ctx->klass->input_panel_layout_set(ctx, layout);
+
+   ctx->input_panel_layout = layout;
+}
+
+/**
+ * Get the layout of the current active input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return layout see #Ecore_IMF_Input_Panel_Layout
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI Ecore_IMF_Input_Panel_Layout
+ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_layout_get");
+        return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
+     }
+
+   if (ctx->klass->input_panel_layout_get)
+     return ctx->input_panel_layout;
+   else
+     return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID;
+}
+
+/**
+ * Set the language of the input panel.
+ * This API can be used when you want to show the English keyboard.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param lang the language to be set to the input panel.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_language_set");
+        return;
+     }
+
+   if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang);
+   ctx->input_panel_lang = lang;
+}
+
+/**
+ * Get the language of the input panel.
+ *
+ * See @ref ecore_imf_context_input_panel_language_set for more details.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return Ecore_IMF_Input_Panel_Lang
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI Ecore_IMF_Input_Panel_Lang
+ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_language_get");
+        return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
+     }
+
+   return ctx->input_panel_lang;
+}
+
+/**
+ * Set whether the Input Method Context should request to show the input panel automatically
+ * when the widget has focus.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param enabled If true, the input panel will be shown when the widget is clicked or has focus.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI void
+ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx,
+                                           Eina_Bool enabled)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_enabled_set");
+        return;
+     }
+
+   ctx->input_panel_enabled = enabled;
+}
+
+/**
+ * Get whether the Input Method Context requests to show the input panel automatically.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return Return the attribute to show the input panel automatically
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.1.0
+ */
+EAPI Eina_Bool
+ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_enabled_get");
+        return EINA_FALSE;
+     }
+
+   return ctx->input_panel_enabled;
+}
+
+/**
+ * Set the input panel-specific data to deliver to the input panel.
+ * This API is used by applications to deliver specific data to the input panel.
+ * The data format MUST be negotiated by both application and the input panel.
+ * The size and format of data are defined by the input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param data The specific data to be set to the input panel.
+ * @param len the length of data, in bytes, to send to the input panel
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI void
+ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_imdata_set");
+        return;
+     }
+
+   if (!data) return;
+
+   if (ctx->klass->input_panel_imdata_set)
+     ctx->klass->input_panel_imdata_set(ctx, data, len);
+}
+
+/**
+ * Get the specific data of the current active input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param data The specific data to be got from the input panel
+ * @param len The length of data
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI void
+ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_imdata_get");
+        return;
+     }
+
+   if (!data) return;
+
+   if (ctx->klass->input_panel_imdata_get)
+     ctx->klass->input_panel_imdata_get(ctx, data, len);
+}
+
+/**
+ * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel.
+ *
+ * An input panel displays the string or icon associated with this type
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param return_key_type The type of "return" key on the input panel
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+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)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_return_key_type_set");
+        return;
+     }
+
+   ctx->input_panel_return_key_type = return_key_type;
+   if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type);
+}
+
+/**
+ * Get the "return" key type.
+ *
+ * @see ecore_imf_context_input_panel_return_key_type_set() for more details
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return The type of "return" key on the input panel
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI Ecore_IMF_Input_Panel_Return_Key_Type
+ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_return_key_type_get");
+        return EINA_FALSE;
+     }
+
+   return ctx->input_panel_return_key_type;
+}
+
+/**
+ * Set the return key on the input panel to be disabled.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param disabled The state
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI void
+ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_return_key_disabled_set");
+        return;
+     }
+
+   ctx->input_panel_return_key_disabled = disabled;
+   if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled);
+}
+
+/**
+ * Get whether the return key on the input panel should be disabled or not.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return @c EINA_TRUE if it should be disabled.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI Eina_Bool
+ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_return_key_disabled_get");
+        return EINA_FALSE;
+     }
+
+   return ctx->input_panel_return_key_disabled;
+}
+
+/**
+ * Set the caps lock mode on the input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param mode Turn on caps lock on the input panel if @c EINA_TRUE.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI void
+ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_caps_lock_mode_set");
+        return;
+     }
+
+   if (ctx->klass->input_panel_caps_lock_mode_set)
+     ctx->klass->input_panel_caps_lock_mode_set(ctx, mode);
+
+   ctx->input_panel_caps_lock_mode = mode;
+}
+
+/**
+ * Get the caps lock mode on the input panel.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return @c EINA_TRUE if the caps lock is turned on.
+ * @ingroup Ecore_IMF_Context_Group
+ * @since 1.2.0
+ */
+EAPI Eina_Bool
+ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx)
+{
+   if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+     {
+        ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+                         "ecore_imf_context_input_panel_caps_lock_mode_get");
+        return EINA_FALSE;
+     }
+
+   return ctx->input_panel_caps_lock_mode;
+}
+