efl: move ecore/immodules to ecore_imf
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Wed, 9 Jan 2013 16:46:58 +0000 (16:46 +0000)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Wed, 9 Jan 2013 16:46:58 +0000 (16:46 +0000)
Move both the source tree and the install directory.

SVN revision: 82474

16 files changed:
src/Makefile_Ecore_Imf.am
src/lib/ecore_imf/ecore_imf_module.c
src/modules/ecore/immodules/ibus/ibus_imcontext.c [deleted file]
src/modules/ecore/immodules/ibus/ibus_imcontext.h [deleted file]
src/modules/ecore/immodules/ibus/ibus_module.c [deleted file]
src/modules/ecore/immodules/scim/scim_imcontext.cpp [deleted file]
src/modules/ecore/immodules/scim/scim_imcontext.h [deleted file]
src/modules/ecore/immodules/scim/scim_module.cpp [deleted file]
src/modules/ecore/immodules/xim/ecore_imf_xim.c [deleted file]
src/modules/ecore_imf/ibus/ibus_imcontext.c [new file with mode: 0644]
src/modules/ecore_imf/ibus/ibus_imcontext.h [new file with mode: 0644]
src/modules/ecore_imf/ibus/ibus_module.c [new file with mode: 0644]
src/modules/ecore_imf/scim/scim_imcontext.cpp [new file with mode: 0644]
src/modules/ecore_imf/scim/scim_imcontext.h [new file with mode: 0644]
src/modules/ecore_imf/scim/scim_module.cpp [new file with mode: 0644]
src/modules/ecore_imf/xim/ecore_imf_xim.c [new file with mode: 0644]

index 9be2846df9ac134eb040d9931e4616797a11678c..79fcfdab744ea4c815bf7087208e46a9629285a5 100644 (file)
@@ -73,13 +73,13 @@ lib_ecore_imf_libecore_imf_evas_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
 # Ibus
 
 if BUILD_ECORE_IMF_IBUS
-ecoreimfibuspkgdir = $(libdir)/ecore/immodules
-ecoreimfibuspkg_LTLIBRARIES = modules/ecore/immodules/ibus/ibus.la
-modules_ecore_immodules_ibus_ibus_la_SOURCES = \
-modules/ecore/immodules/ibus/ibus_module.c \
-modules/ecore/immodules/ibus/ibus_imcontext.c \
-modules/ecore/immodules/ibus/ibus_imcontext.h
-modules_ecore_immodules_ibus_ibus_la_CPPFLAGS = \
+ecoreimfibuspkgdir = $(libdir)/ecore_imf
+ecoreimfibuspkg_LTLIBRARIES = modules/ecore_imf/ibus/ibus.la
+modules_ecore_imf_ibus_ibus_la_SOURCES = \
+modules/ecore_imf/ibus/ibus_module.c \
+modules/ecore_imf/ibus/ibus_imcontext.c \
+modules/ecore_imf/ibus/ibus_imcontext.h
+modules_ecore_imf_ibus_ibus_la_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/eina \
 -I$(top_builddir)/src/lib/eina \
 -I$(top_srcdir)/src/lib/eo \
@@ -93,7 +93,7 @@ modules_ecore_immodules_ibus_ibus_la_CPPFLAGS = \
 @ECORE_IMF_CFLAGS@ \
 @EFL_COV_CFLAGS@ \
 @IBUS_CFLAGS@
-modules_ecore_immodules_ibus_ibus_la_LIBADD = \
+modules_ecore_imf_ibus_ibus_la_LIBADD = \
 lib/ecore_evas/libecore_evas.la \
 lib/ecore_imf/libecore_imf.la \
 lib/ecore_x/libecore_x.la \
@@ -102,20 +102,20 @@ lib/eo/libeo.la \
 lib/eina/libeina.la \
 @IBUS_LIBS@ \
 @EFL_COV_LIBS@
-modules_ecore_immodules_ibus_ibus_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
-modules_ecore_immodules_ibus_ibus_la_LIBTOOLFLAGS = --tag=disable-static
+modules_ecore_imf_ibus_ibus_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
+modules_ecore_imf_ibus_ibus_la_LIBTOOLFLAGS = --tag=disable-static
 endif
 
 # Scim
 
 if BUILD_ECORE_IMF_SCIM
-ecoreimfscimpkgdir = $(libdir)/ecore/immodules
-ecoreimfscimpkg_LTLIBRARIES = modules/ecore/immodules/scim/scim.la
-modules_ecore_immodules_scim_scim_la_SOURCES = \
-modules/ecore/immodules/scim/scim_module.cpp \
-modules/ecore/immodules/scim/scim_imcontext.cpp \
-modules/ecore/immodules/scim/scim_imcontext.h
-modules_ecore_immodules_scim_scim_la_CPPFLAGS = \
+ecoreimfscimpkgdir = $(libdir)/ecore_imf
+ecoreimfscimpkg_LTLIBRARIES = modules/ecore_imf/scim/scim.la
+modules_ecore_imf_scim_scim_la_SOURCES = \
+modules/ecore_imf/scim/scim_module.cpp \
+modules/ecore_imf/scim/scim_imcontext.cpp \
+modules/ecore_imf/scim/scim_imcontext.h
+modules_ecore_imf_scim_scim_la_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/eina \
 -I$(top_builddir)/src/lib/eina \
 -I$(top_srcdir)/src/lib/eo \
@@ -129,7 +129,7 @@ modules_ecore_immodules_scim_scim_la_CPPFLAGS = \
 @ECORE_IMF_CFLAGS@ \
 @EFL_COV_CFLAGS@ \
 @SCIM_CFLAGS@
-modules_ecore_immodules_scim_scim_la_LIBADD = \
+modules_ecore_imf_scim_scim_la_LIBADD = \
 lib/ecore_evas/libecore_evas.la \
 lib/ecore_imf/libecore_imf.la \
 lib/ecore_x/libecore_x.la \
@@ -138,18 +138,18 @@ lib/eo/libeo.la \
 lib/eina/libeina.la \
 @SCIM_LIBS@ \
 @EFL_COV_LIBS@
-modules_ecore_immodules_scim_scim_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
-modules_ecore_immodules_scim_scim_la_LIBTOOLFLAGS = --tag=disable-static
+modules_ecore_imf_scim_scim_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
+modules_ecore_imf_scim_scim_la_LIBTOOLFLAGS = --tag=disable-static
 endif
 
 # Xim
 
 if BUILD_ECORE_IMF_XIM
-ecoreimfximpkgdir = $(libdir)/ecore/immodules
-ecoreimfximpkg_LTLIBRARIES = modules/ecore/immodules/xim/xim.la
-modules_ecore_immodules_xim_xim_la_SOURCES = \
-modules/ecore/immodules/xim/ecore_imf_xim.c
-modules_ecore_immodules_xim_xim_la_CPPFLAGS = \
+ecoreimfximpkgdir = $(libdir)/ecore_imf
+ecoreimfximpkg_LTLIBRARIES = modules/ecore_imf/xim/xim.la
+modules_ecore_imf_xim_xim_la_SOURCES = \
+modules/ecore_imf/xim/ecore_imf_xim.c
+modules_ecore_imf_xim_xim_la_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/eina \
 -I$(top_builddir)/src/lib/eina \
 -I$(top_srcdir)/src/lib/eo \
@@ -160,13 +160,13 @@ modules_ecore_immodules_xim_xim_la_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/ecore_imf \
 @ECORE_IMF_CFLAGS@ \
 @EFL_COV_CFLAGS@
-modules_ecore_immodules_xim_xim_la_LIBADD = \
+modules_ecore_imf_xim_xim_la_LIBADD = \
 lib/ecore_imf/libecore_imf.la \
 lib/ecore_x/libecore_x.la \
 lib/ecore/libecore.la \
 lib/eo/libeo.la \
 lib/eina/libeina.la \
 @EFL_COV_LIBS@
-modules_ecore_immodules_xim_xim_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
-modules_ecore_immodules_xim_xim_la_LIBTOOLFLAGS = --tag=disable-static
+modules_ecore_imf_xim_xim_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
+modules_ecore_imf_xim_xim_la_LIBTOOLFLAGS = --tag=disable-static
 endif
index bf8cf6b73121d623b49b3ab009b2457a8e5c559c..9df95a713052b9bba8a5bbb3dbd64ec01b54b52b 100644 (file)
@@ -40,7 +40,7 @@ ecore_imf_module_init(void)
    if (getenv("EFL_RUN_IN_TREE"))
      {
         struct stat st;
-        snprintf(buf, sizeof(buf), "%s/src/modules/ecore/immodules",
+        snprintf(buf, sizeof(buf), "%s/src/modules/ecore_imf",
                  PACKAGE_BUILD_DIR);
         if (stat(buf, &st) == 0)
           {
@@ -60,7 +60,7 @@ ecore_imf_module_init(void)
              for (itr = built_modules; *itr != NULL; itr++)
                {
                   snprintf(buf, sizeof(buf),
-                           "%s/src/modules/ecore/immodules/%s/.libs",
+                           "%s/src/modules/ecore_imf/%s/.libs",
                            PACKAGE_BUILD_DIR, *itr);
                   module_list = eina_module_list_get(module_list, buf,
                                                      EINA_FALSE, NULL, NULL);
@@ -72,10 +72,10 @@ ecore_imf_module_init(void)
           }
      }
 
-   snprintf(buf, sizeof(buf), "%s/ecore/immodules", eina_prefix_lib_get(pfx));
+   snprintf(buf, sizeof(buf), "%s/ecore_imf", eina_prefix_lib_get(pfx));
 
    module_list = eina_module_list_get(NULL, buf, 0, NULL, NULL);
-   homedir = eina_module_environment_path_get("HOME", "/.ecore/immodules");
+   homedir = eina_module_environment_path_get("HOME", "/.ecore_imf");
    if (homedir)
      {
         module_list = eina_module_list_get(module_list, homedir, 0, NULL, NULL);
diff --git a/src/modules/ecore/immodules/ibus/ibus_imcontext.c b/src/modules/ecore/immodules/ibus/ibus_imcontext.c
deleted file mode 100644 (file)
index 02f4fce..0000000
+++ /dev/null
@@ -1,822 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-
-#include <X11/Xlib.h>
-#include <Ecore_X.h>
-#include <Ecore_Evas.h>
-
-#include <ibus.h>
-#include "ibus_imcontext.h"
-
-struct _IBusIMContext
-{
-   /* instance members */
-   Ecore_IMF_Context *ctx;
-
-   /* enabled */
-   Eina_Bool        enable;
-   IBusInputContext *ibuscontext;
-
-   /* preedit status */
-   char            *preedit_string;
-   Eina_List       *preedit_attrs;
-   int              preedit_cursor_pos;
-   Eina_Bool        preedit_visible;
-
-   int              cursor_x;
-   int              cursor_y;
-   int              cursor_w;
-   int              cursor_h;
-
-   Eina_Bool        has_focus;
-
-   Ecore_X_Window   client_window;
-   Evas            *client_canvas;
-
-   int              caps;
-};
-
-typedef struct _KeyEvent KeyEvent;
-
-struct _KeyEvent
-{
-   int keysym;
-   int state;
-};
-
-static Eina_Bool _use_sync_mode = EINA_FALSE;
-
-static Ecore_IMF_Context *_focus_im_context = NULL;
-static IBusBus           *_bus = NULL;
-
-/* functions prototype */
-/* static methods*/
-static void     _create_input_context       (IBusIMContext      *context);
-static void     _set_cursor_location_internal
-(Ecore_IMF_Context  *ctx);
-static void     _bus_connected_cb           (IBusBus            *bus,
-                                             IBusIMContext      *context);
-static XKeyEvent createXKeyEvent            (Window win, Eina_Bool press, int keysym, int modifiers);
-
-static void
-_window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y)
-{
-   Ecore_X_Window root_window, win;
-   int win_x, win_y;
-   int sum_x = 0, sum_y = 0;
-
-   root_window = ecore_x_window_root_get(client_win);
-   win = client_win;
-
-   while (root_window != win)
-     {
-        ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL);
-        sum_x += win_x;
-        sum_y += win_y;
-        win = ecore_x_window_parent_get(win);
-     }
-
-   if (x)
-     *x = sum_x;
-   if (y)
-     *y = sum_y;
-}
-
-static unsigned int
-_ecore_imf_modifier_to_ibus_modifier(unsigned int modifier)
-{
-   unsigned int state = 0;
-
-   /**< "Control" is pressed */
-   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
-     state |= IBUS_CONTROL_MASK;
-
-   /**< "Alt" is pressed */
-   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
-     state |= IBUS_MOD1_MASK;
-
-   /**< "Shift" is pressed */
-   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
-     state |= IBUS_SHIFT_MASK;
-
-   /**< "Win" (between "Ctrl" and "Alt") */
-   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
-     state |= IBUS_SUPER_MASK;
-
-   /**< "AltGr" is pressed */
-   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
-     state |= IBUS_MOD5_MASK;
-
-   return state;
-}
-
-static void
-key_event_put(int keysym, int state)
-{
-   // Find the window which has the current keyboard focus.
-   Window winFocus = 0;
-   int revert = RevertToParent;
-
-   XGetInputFocus(ecore_x_display_get(), &winFocus, &revert);
-
-   XKeyEvent event;
-   if (state & IBUS_RELEASE_MASK)
-     {
-        event = createXKeyEvent(winFocus, EINA_FALSE, keysym, state);
-        XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event);
-     }
-   else
-     {
-        event = createXKeyEvent(winFocus, EINA_TRUE, keysym, state);
-        XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
-     }
-}
-
-static KeyEvent *
-key_event_copy(int keysym, int state)
-{
-   KeyEvent *kev = calloc(1, sizeof(KeyEvent));
-   kev->keysym = keysym;
-   kev->state = state;
-
-   return kev;
-}
-
-IBusIMContext *
-ibus_im_context_new(void)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-
-   IBusIMContext *context = calloc(1, sizeof(IBusIMContext));
-
-   /* init bus object */
-   if (_bus == NULL)
-     {
-        char *display_name = NULL;
-
-        if ((display_name = getenv("DISPLAY")))
-          ibus_set_display(display_name);
-        else
-          ibus_set_display(":0.0");
-
-        _bus = ibus_bus_new();
-     }
-
-   return context;
-}
-
-static void
-_process_key_event_done(GObject      *object,
-                        GAsyncResult *res,
-                        gpointer      user_data)
-{
-    IBusInputContext *context = (IBusInputContext *)object;
-    KeyEvent *event = (KeyEvent *)user_data;
-
-    GError *error = NULL;
-    Eina_Bool retval = ibus_input_context_process_key_event_async_finish(context,
-                                                                         res,
-                                                                         &error);
-
-    if (error != NULL)
-      {
-         g_warning("Process Key Event failed: %s.", error->message);
-         g_error_free(error);
-      }
-
-    if (retval == EINA_FALSE)
-      {
-         key_event_put(event->keysym, event->state);
-      }
-    free(event);
-}
-
-EAPI void
-ibus_im_context_add(Ecore_IMF_Context *ctx)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-
-   char *s = NULL;
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   ibusimcontext->client_window = 0;
-
-   // Init ibus status
-   ibusimcontext->enable = EINA_FALSE;
-
-   // Init preedit status
-   ibusimcontext->preedit_string = NULL;
-   ibusimcontext->preedit_attrs = NULL;
-   ibusimcontext->preedit_cursor_pos = 0;
-   ibusimcontext->preedit_visible = EINA_FALSE;
-
-   // Init cursor area
-   ibusimcontext->cursor_x = -1;
-   ibusimcontext->cursor_y = -1;
-   ibusimcontext->cursor_w = 0;
-   ibusimcontext->cursor_h = 0;
-
-   ibusimcontext->ibuscontext = NULL;
-   ibusimcontext->has_focus = EINA_FALSE;
-   ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
-   ibusimcontext->ctx = ctx;
-
-   s = getenv("IBUS_ENABLE_SYNC_MODE");
-   if (s)
-     _use_sync_mode = !!atoi(s);
-
-   if (ibus_bus_is_connected(_bus))
-     _create_input_context (ibusimcontext);
-
-   g_signal_connect(_bus, "connected", G_CALLBACK (_bus_connected_cb), ctx);
-}
-
-EAPI void
-ibus_im_context_del(Ecore_IMF_Context *ctx)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   g_signal_handlers_disconnect_by_func(_bus, G_CALLBACK(_bus_connected_cb), ctx);
-
-   if (ibusimcontext->ibuscontext)
-     ibus_proxy_destroy((IBusProxy *)ibusimcontext->ibuscontext);
-
-   // release preedit
-   if (ibusimcontext->preedit_string)
-     free(ibusimcontext->preedit_string);
-   if (_focus_im_context == ctx)
-     _focus_im_context = NULL;
-}
-
-EAPI Eina_Bool
-ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
-{
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ibusimcontext, EINA_FALSE);
-
-   if (type != ECORE_IMF_EVENT_KEY_UP && type != ECORE_IMF_EVENT_KEY_DOWN)
-     return EINA_FALSE;
-
-   EINA_LOG_DBG("%s", __FUNCTION__);
-
-   if (G_LIKELY(ibusimcontext->ibuscontext && ibusimcontext->has_focus))
-     {
-        /* If context does not have focus, ibus will process key event in sync mode.
-         * It is a workaround for increase search in treeview.
-         */
-        Eina_Bool retval = EINA_FALSE;
-        int keycode;
-        int keysym;
-        unsigned int state = 0;
-
-        if (type == ECORE_IMF_EVENT_KEY_UP)
-          {
-             Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event;
-             if (ev->timestamp == 0)
-               return EINA_FALSE;
-
-             keycode = ecore_x_keysym_keycode_get(ev->key);
-             keysym = XStringToKeysym(ev->key);
-             state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | IBUS_RELEASE_MASK;
-
-             if (_use_sync_mode)
-               {
-                  retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext,
-                                                                keysym,
-                                                                keycode - 8,
-                                                                state);
-               }
-             else
-               {
-                  ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext,
-                                                             keysym,
-                                                             keycode - 8,
-                                                             state,
-                                                             -1,
-                                                             NULL,
-                                                             _process_key_event_done,
-                                                             key_event_copy(keysym, state));
-                  retval = EINA_TRUE;
-               }
-          }
-        else if (type == ECORE_IMF_EVENT_KEY_DOWN)
-          {
-             Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
-             if (ev->timestamp == 0)
-               return EINA_FALSE;
-
-             keycode = ecore_x_keysym_keycode_get(ev->key);
-             keysym = XStringToKeysym(ev->key);
-             state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers);
-             if (_use_sync_mode)
-               {
-                  retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext,
-                                                                keysym,
-                                                                keycode - 8,
-                                                                state);
-               }
-             else
-               {
-                  ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext,
-                                                             keysym,
-                                                             keycode - 8,
-                                                             state,
-                                                             -1,
-                                                             NULL,
-                                                             _process_key_event_done,
-                                                             key_event_copy(keysym, state));
-                  retval = EINA_TRUE;
-               }
-          }
-        else
-          retval = EINA_FALSE;
-
-        if (retval)
-          return EINA_TRUE;
-        else
-          return EINA_FALSE;
-     }
-   else
-     return EINA_FALSE;
-}
-
-EAPI void
-ibus_im_context_focus_in(Ecore_IMF_Context *ctx)
-{
-   EINA_LOG_DBG("ctx : %p", ctx);
-
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->has_focus)
-     return;
-
-   if (_focus_im_context != NULL)
-     ecore_imf_context_focus_out(_focus_im_context);
-
-   ibusimcontext->has_focus = EINA_TRUE;
-   if (ibusimcontext->ibuscontext)
-     ibus_input_context_focus_in(ibusimcontext->ibuscontext);
-
-   if (_focus_im_context != ctx)
-     _focus_im_context = ctx;
-}
-
-EAPI void
-ibus_im_context_focus_out(Ecore_IMF_Context *ctx)
-{
-   EINA_LOG_DBG("ctx : %p", ctx);
-
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->has_focus == EINA_FALSE)
-     return;
-
-   if (_focus_im_context == ctx)
-     _focus_im_context = NULL;
-
-   ibusimcontext->has_focus = EINA_FALSE;
-   if (ibusimcontext->ibuscontext)
-     ibus_input_context_focus_out(ibusimcontext->ibuscontext);
-}
-
-EAPI void
-ibus_im_context_reset(Ecore_IMF_Context *ctx)
-{
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->ibuscontext)
-     ibus_input_context_reset(ibusimcontext->ibuscontext);
-}
-
-EAPI void
-ibus_im_context_preedit_string_get(Ecore_IMF_Context *ctx,
-                                   char          **str,
-                                   int            *cursor_pos)
-{
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->enable && ibusimcontext->preedit_visible)
-     {
-        if (str)
-          *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: "");
-
-        if (cursor_pos)
-          *cursor_pos = ibusimcontext->preedit_cursor_pos;
-     }
-   else
-     {
-        if (str)
-          *str = strdup("");
-
-        if (cursor_pos)
-          *cursor_pos = 0;
-     }
-   EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos);
-}
-
-EAPI void
-ibus_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context   *ctx,
-                                                   char          **str,
-                                                   Eina_List     **attr EINA_UNUSED,
-                                                   int            *cursor_pos)
-{
-   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->enable && ibusimcontext->preedit_visible)
-     {
-        if (str)
-          *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: "");
-
-        if (cursor_pos)
-          *cursor_pos = ibusimcontext->preedit_cursor_pos;
-     }
-   else
-     {
-        if (str)
-          *str = strdup("");
-
-        if (cursor_pos)
-          *cursor_pos = 0;
-     }
-   EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos);
-}
-
-EAPI void
-ibus_im_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
-{
-   EINA_LOG_DBG("canvas : %p", window);
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (window != NULL)
-     ibusimcontext->client_window = (Ecore_X_Window)(Ecore_Window)window;
-}
-
-EAPI void
-ibus_im_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
-{
-   EINA_LOG_DBG("canvas : %p", canvas);
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (canvas != NULL)
-     ibusimcontext->client_canvas = canvas;
-}
-
-static void
-_set_cursor_location_internal(Ecore_IMF_Context *ctx)
-{
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   Ecore_Evas *ee;
-   int canvas_x, canvas_y;
-
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->ibuscontext == NULL)
-     return;
-
-   if (ibusimcontext->client_canvas)
-     {
-        ee = ecore_evas_ecore_evas_get(ibusimcontext->client_canvas);
-        if (!ee) return;
-
-        ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
-     }
-   else
-     {
-        if (ibusimcontext->client_window)
-          _window_to_screen_geometry_get(ibusimcontext->client_window, &canvas_x, &canvas_y);
-        else
-          return;
-     }
-
-   ibus_input_context_set_cursor_location(ibusimcontext->ibuscontext,
-                                          ibusimcontext->cursor_x + canvas_x,
-                                          ibusimcontext->cursor_y + canvas_y,
-                                          ibusimcontext->cursor_w,
-                                          ibusimcontext->cursor_h);
-}
-
-EAPI void
-ibus_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
-{
-   EINA_LOG_DBG("x : %d, y : %d, w, %d, h :%d", x, y, w, h);
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->cursor_x != x ||
-       ibusimcontext->cursor_y != y ||
-       ibusimcontext->cursor_w != w ||
-       ibusimcontext->cursor_h != h)
-     {
-        ibusimcontext->cursor_x = x;
-        ibusimcontext->cursor_y = y;
-        ibusimcontext->cursor_w = w;
-        ibusimcontext->cursor_h = h;
-
-        _set_cursor_location_internal(ctx);
-     }
-}
-
-EAPI void
-ibus_im_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
-{
-   EINA_LOG_DBG("preedit : %d", use_preedit);
-   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->ibuscontext)
-     {
-        if (use_preedit)
-          ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT;
-        else
-          ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT;
-
-        ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps);
-     }
-}
-
-static void
-_bus_connected_cb(IBusBus          *bus EINA_UNUSED,
-                  IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("ibus is connected");
-
-   if (ibusimcontext)
-     _create_input_context(ibusimcontext);
-}
-
-static void
-_ibus_context_commit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                             IBusText         *text,
-                             IBusIMContext    *ibusimcontext)
-{
-   if (!ibusimcontext || !text) return;
-   char *commit_str = text->text ? text->text : "";
-
-   EINA_LOG_DBG("commit string : %s", commit_str);
-
-   if (ibusimcontext->ctx)
-     {
-        ecore_imf_context_commit_event_add(ibusimcontext->ctx, text->text);
-        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit_str);
-     }
-}
-
-static XKeyEvent createXKeyEvent(Window win, Eina_Bool press, int keysym, int modifiers)
-{
-   XKeyEvent event;
-   Display *display = ecore_x_display_get();
-
-   event.display     = display;
-   event.window      = win;
-   event.root        = ecore_x_window_root_get(win);
-   event.subwindow   = None;
-   event.time        = 0;
-   event.x           = 1;
-   event.y           = 1;
-   event.x_root      = 1;
-   event.y_root      = 1;
-   event.same_screen = EINA_TRUE;
-   event.state       = modifiers;
-   event.keycode     = XKeysymToKeycode(display, keysym);
-   if (press)
-     event.type = KeyPress;
-   else
-     event.type = KeyRelease;
-   event.send_event  = EINA_FALSE;
-   event.serial = 0;
-
-   return event;
-}
-
-static void
-_ibus_context_forward_key_event_cb(IBusInputContext  *ibuscontext EINA_UNUSED,
-                                   guint              keyval,
-                                   guint              state,
-                                   IBusIMContext     *ibusimcontext EINA_UNUSED)
-{
-   EINA_LOG_DBG("keyval : %d, state : %d", keyval, state);
-
-   key_event_put(keyval, state);
-}
-
-static void
-_ibus_context_update_preedit_text_cb(IBusInputContext  *ibuscontext EINA_UNUSED,
-                                     IBusText          *text,
-                                     gint               cursor_pos,
-                                     gboolean           visible,
-                                     IBusIMContext     *ibusimcontext)
-{
-   if (!ibusimcontext || !text) return;
-
-   const char *str;
-   gboolean flag;
-
-   if (ibusimcontext->preedit_string)
-     free (ibusimcontext->preedit_string);
-
-   str = text->text;
-
-   if (str)
-     ibusimcontext->preedit_string = strdup(str);
-   else
-     ibusimcontext->preedit_string = strdup("");
-
-   ibusimcontext->preedit_cursor_pos = cursor_pos;
-
-   EINA_LOG_DBG("string : %s, cursor : %d", ibusimcontext->preedit_string, ibusimcontext->preedit_cursor_pos);
-
-   flag = ibusimcontext->preedit_visible != visible;
-   ibusimcontext->preedit_visible = visible;
-
-   if (ibusimcontext->preedit_visible)
-     {
-        if (flag)
-          {
-             ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx);
-             ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-          }
-
-        ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-     }
-   else
-     {
-        if (flag)
-          {
-             ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-             ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-          }
-
-        ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
-        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-     }
-}
-
-static void
-_ibus_context_show_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                                   IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("preedit visible : %d", ibusimcontext->preedit_visible);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->preedit_visible == EINA_TRUE)
-     return;
-
-   ibusimcontext->preedit_visible = EINA_TRUE;
-
-   // call preedit start
-   ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-
-   // call preedit changed
-   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-}
-
-static void
-_ibus_context_hide_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                                   IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   if (ibusimcontext->preedit_visible == EINA_FALSE)
-     return;
-
-   ibusimcontext->preedit_visible = EINA_FALSE;
-
-   // call preedit changed
-   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-
-   // call preedit end
-   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-}
-
-static void
-_ibus_context_enabled_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                         IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   ibusimcontext->enable = EINA_TRUE;
-}
-
-static void
-_ibus_context_disabled_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                          IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   ibusimcontext->enable = EINA_FALSE;
-
-   /* clear preedit */
-   ibusimcontext->preedit_visible = EINA_FALSE;
-   ibusimcontext->preedit_cursor_pos = 0;
-   free (ibusimcontext->preedit_string);
-   ibusimcontext->preedit_string = NULL;
-
-   // call preedit changed
-   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-
-   // call preedit end
-   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-}
-
-static void
-_ibus_context_destroy_cb(IBusInputContext *ibuscontext EINA_UNUSED,
-                         IBusIMContext    *ibusimcontext)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   ibusimcontext->ibuscontext = NULL;
-   ibusimcontext->enable = EINA_FALSE;
-
-   /* clear preedit */
-   ibusimcontext->preedit_visible = EINA_FALSE;
-   ibusimcontext->preedit_cursor_pos = 0;
-   free (ibusimcontext->preedit_string);
-   ibusimcontext->preedit_string = NULL;
-
-   // call preedit changed
-   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-
-   // call preedit end
-   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
-   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-}
-
-static void
-_create_input_context(IBusIMContext *ibusimcontext)
-{
-   EINA_LOG_DBG("%s", __FUNCTION__);
-   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
-
-   ibusimcontext->ibuscontext = ibus_bus_create_input_context(_bus, "ecore");
-
-   g_return_if_fail(ibusimcontext->ibuscontext != NULL);
-
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "commit-text",
-                    G_CALLBACK (_ibus_context_commit_text_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "forward-key-event",
-                    G_CALLBACK (_ibus_context_forward_key_event_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "update-preedit-text",
-                    G_CALLBACK (_ibus_context_update_preedit_text_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "show-preedit-text",
-                    G_CALLBACK (_ibus_context_show_preedit_text_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "hide-preedit-text",
-                    G_CALLBACK (_ibus_context_hide_preedit_text_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "enabled",
-                    G_CALLBACK (_ibus_context_enabled_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext,
-                    "disabled",
-                    G_CALLBACK (_ibus_context_disabled_cb),
-                    ibusimcontext);
-   g_signal_connect(ibusimcontext->ibuscontext, "destroy",
-                    G_CALLBACK (_ibus_context_destroy_cb),
-                    ibusimcontext);
-
-   ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps);
-
-   if (ibusimcontext->has_focus)
-     ibus_input_context_focus_in(ibusimcontext->ibuscontext);
-}
diff --git a/src/modules/ecore/immodules/ibus/ibus_imcontext.h b/src/modules/ecore/immodules/ibus/ibus_imcontext.h
deleted file mode 100644 (file)
index ce5c075..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __IBUS_IM_CONTEXT_H_
-#define __IBUS_IM_CONTEXT_H_
-
-#include <Ecore_IMF.h>
-
-typedef struct _IBusIMContext IBusIMContext;
-
-EAPI void ibus_im_context_add     (Ecore_IMF_Context *ctx);
-EAPI void ibus_im_context_del     (Ecore_IMF_Context *ctx);
-EAPI void ibus_im_context_reset   (Ecore_IMF_Context *context);
-EAPI void ibus_im_context_focus_in(Ecore_IMF_Context *context);
-EAPI void ibus_im_context_focus_out(Ecore_IMF_Context *context);
-EAPI void ibus_im_context_preedit_string_get
-                                            (Ecore_IMF_Context     *context,
-                                             char                  **str,
-                                             int                   *cursor_pos);
-EAPI void ibus_im_context_preedit_string_with_attributes_get
-                                            (Ecore_IMF_Context     *context,
-                                             char                  **str,
-                                             Eina_List             **attr,
-                                             int                   *cursor_pos);
-
-EAPI void ibus_im_context_cursor_location_set(Ecore_IMF_Context *context,
-                                              int x, int y, int w, int h);
-EAPI void ibus_im_context_use_preedit_set(Ecore_IMF_Context *context,
-                                          Eina_Bool use_preedit);
-EAPI void
-ibus_im_context_client_window_set(Ecore_IMF_Context   *context, void *window);
-EAPI void
-ibus_im_context_client_canvas_set(Ecore_IMF_Context   *context, void *canvas);
-EAPI Eina_Bool
-ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
-
-IBusIMContext
-        *ibus_im_context_new      (void);
-#endif
diff --git a/src/modules/ecore/immodules/ibus/ibus_module.c b/src/modules/ecore/immodules/ibus/ibus_module.c
deleted file mode 100644 (file)
index 8ac1bf3..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include <Ecore.h>
-#include <Ecore_IMF.h>
-
-#include <ibus.h>
-#include "ibus_imcontext.h"
-
-#define IBUS_LOCALDIR ""
-static const Ecore_IMF_Context_Info ibus_im_info = {
-    "ibus",
-    "IBus (Intelligent Input Bus)",
-    "*",
-    NULL,
-    0
-};
-
-static Ecore_IMF_Context_Class ibus_imf_class = {
-    ibus_im_context_add,                    /* add */
-    ibus_im_context_del,                    /* del */
-    ibus_im_context_client_window_set,      /* client_window_set */
-    ibus_im_context_client_canvas_set,      /* client_canvas_set */
-    NULL,                                   /* input_panel_show */
-    NULL,                                   /* input_panel_hide */
-    ibus_im_context_preedit_string_get,     /* get_preedit_string */
-    ibus_im_context_focus_in,               /* focus_in */
-    ibus_im_context_focus_out,              /* focus_out */
-    ibus_im_context_reset,                  /* reset */
-    NULL,                                   /* cursor_position_set */
-    ibus_im_context_use_preedit_set,        /* use_preedit_set */
-    NULL,                                   /* input_mode_set */
-    ibus_im_context_filter_event,           /* filter_event */
-    ibus_im_context_preedit_string_with_attributes_get,  /* preedit_string_with_attribute_get */
-    NULL,                                   /* prediction_allow_set */
-    NULL,                                   /* autocapital_type_set */
-    NULL,                                   /* control panel show */
-    NULL,                                   /* control panel hide */
-    NULL,                                   /* input_panel_layout_set */
-    NULL,                                   /* ibus_im_context_input_panel_layout_get, */
-    NULL,                                   /* ibus_im_context_input_panel_language_set, */
-    NULL,                                   /* ibus_im_context_input_panel_language_get, */
-    ibus_im_context_cursor_location_set,    /* cursor_location_set */
-    NULL,                                   /* input_panel_imdata_set */
-    NULL,                                   /* input_panel_imdata_get */
-    NULL,                                   /* input_panel_return_key_type_set */
-    NULL,                                   /* input_panel_return_key_disabled_set */
-    NULL,                                   /* input_panel_caps_lock_mode_set */
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-static Ecore_IMF_Context *im_module_create (void);
-static Ecore_IMF_Context *im_module_exit (void);
-
-static Eina_Bool
-im_module_init(void)
-{
-    ecore_main_loop_glib_integrate();
-    ibus_init();
-    ecore_imf_module_register(&ibus_im_info, im_module_create, im_module_exit);
-
-    return EINA_TRUE;
-}
-
-static void im_module_shutdown(void)
-{
-}
-
-static Ecore_IMF_Context *
-im_module_exit(void)
-{
-    return NULL;
-}
-
-static Ecore_IMF_Context *
-im_module_create(void)
-{
-    Ecore_IMF_Context *ctx = NULL;
-    IBusIMContext *ctxd = NULL;
-
-    ctxd = ibus_im_context_new();
-    if (!ctxd)
-      {
-         return NULL;
-      }
-
-    ctx = ecore_imf_context_new(&ibus_imf_class);
-    if (!ctx)
-      {
-         free(ctxd);
-         return NULL;
-      }
-
-    ecore_imf_context_data_set(ctx, ctxd);
-
-    return ctx;
-}
-
-EINA_MODULE_INIT(im_module_init);
-EINA_MODULE_SHUTDOWN(im_module_shutdown);
-
diff --git a/src/modules/ecore/immodules/scim/scim_imcontext.cpp b/src/modules/ecore/immodules/scim/scim_imcontext.cpp
deleted file mode 100644 (file)
index 80fd295..0000000
+++ /dev/null
@@ -1,2899 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define Uses_SCIM_DEBUG
-#define Uses_SCIM_BACKEND
-#define Uses_SCIM_IMENGINE_MODULE
-#define Uses_SCIM_HOTKEY
-#define Uses_SCIM_PANEL_CLIENT
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <Ecore_Evas.h>
-#include <Ecore_X.h>
-#include <Ecore.h>
-#include <Evas.h>
-
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/Xutil.h>
-
-#include <scim.h>
-#include "scim_imcontext.h"
-
-using namespace scim;
-
-struct _EcoreIMFContextISFImpl
-{
-    EcoreIMFContextISF      *parent;
-    IMEngineInstancePointer  si;
-    Ecore_X_Window           client_window;
-    Evas                    *client_canvas;
-    Ecore_IMF_Input_Mode     input_mode;
-    WideString               preedit_string;
-    AttributeList            preedit_attrlist;
-    Ecore_IMF_Autocapital_Type autocapital_type;
-    int                      preedit_caret;
-    int                      cursor_x;
-    int                      cursor_y;
-    int                      cursor_pos;
-    bool                     use_preedit;
-    bool                     is_on;
-    bool                     shared_si;
-    bool                     preedit_started;
-    bool                     preedit_updating;
-    bool                     need_commit_preedit;
-    bool                     uppercase;
-    bool                     prediction_allow;
-
-    EcoreIMFContextISFImpl  *next;
-};
-
-/* Input Context handling functions. */
-static EcoreIMFContextISFImpl *new_ic_impl              (EcoreIMFContextISF     *parent);
-static void                    delete_ic_impl           (EcoreIMFContextISFImpl *impl);
-static void                    delete_all_ic_impl       (void);
-
-static EcoreIMFContextISF     *find_ic                  (int                     id);
-
-
-/* private functions */
-static void     panel_slot_reload_config                (int                     context);
-static void     panel_slot_exit                         (int                     context);
-static void     panel_slot_update_lookup_table_page_size(int                     context,
-                                                         int                     page_size);
-static void     panel_slot_lookup_table_page_up         (int                     context);
-static void     panel_slot_lookup_table_page_down       (int                     context);
-static void     panel_slot_trigger_property             (int                     context,
-                                                         const String           &property);
-static void     panel_slot_process_helper_event         (int                     context,
-                                                         const String           &target_uuid,
-                                                         const String           &helper_uuid,
-                                                         const Transaction      &trans);
-static void     panel_slot_move_preedit_caret           (int                     context,
-                                                         int                     caret_pos);
-static void     panel_slot_select_candidate             (int                     context,
-                                                         int                     cand_index);
-static void     panel_slot_process_key_event            (int                     context,
-                                                         const KeyEvent         &key);
-static void     panel_slot_commit_string                (int                     context,
-                                                         const WideString       &wstr);
-static void     panel_slot_forward_key_event            (int                     context,
-                                                         const KeyEvent         &key);
-static void     panel_slot_request_help                 (int                     context);
-static void     panel_slot_request_factory_menu         (int                     context);
-static void     panel_slot_change_factory               (int                     context,
-                                                         const String           &uuid);
-
-static void     panel_req_focus_in                      (EcoreIMFContextISF     *ic);
-static void     panel_req_update_factory_info           (EcoreIMFContextISF     *ic);
-static void     panel_req_update_spot_location          (EcoreIMFContextISF     *ic);
-static void     panel_req_show_help                     (EcoreIMFContextISF     *ic);
-static void     panel_req_show_factory_menu             (EcoreIMFContextISF     *ic);
-
-/* Panel iochannel handler*/
-static bool     panel_initialize                        (void);
-static void     panel_finalize                          (void);
-static Eina_Bool panel_iochannel_handler                (void                   *data,
-                                                         Ecore_Fd_Handler       *fd_handler);
-
-/* utility functions */
-static bool     filter_hotkeys                          (EcoreIMFContextISF     *ic,
-                                                         const KeyEvent         &key);
-static void     turn_on_ic                              (EcoreIMFContextISF     *ic);
-static void     turn_off_ic                             (EcoreIMFContextISF     *ic);
-static void     set_ic_capabilities                     (EcoreIMFContextISF     *ic);
-
-static void     initialize                              (void);
-static void     finalize                                (void);
-
-static void     open_next_factory                       (EcoreIMFContextISF     *ic);
-static void     open_previous_factory                   (EcoreIMFContextISF     *ic);
-static void     open_specific_factory                   (EcoreIMFContextISF     *ic,
-                                                         const String           &uuid);
-static void     initialize_modifier_bits                (Display *display);
-static unsigned int scim_x11_keymask_scim_to_x11        (Display *display, uint16 scimkeymask);
-static XKeyEvent createKeyEvent                         (Display *display, Window &win,
-                                                         Window &winRoot, bool press,
-                                                         int keysym, int modifiers);
-static void     _x_send_key_event                       (const KeyEvent &key);
-
-static void     attach_instance                         (const IMEngineInstancePointer &si);
-
-/* slot functions */
-static void     slot_show_preedit_string                (IMEngineInstanceBase   *si);
-static void     slot_show_aux_string                    (IMEngineInstanceBase   *si);
-static void     slot_show_lookup_table                  (IMEngineInstanceBase   *si);
-
-static void     slot_hide_preedit_string                (IMEngineInstanceBase   *si);
-static void     slot_hide_aux_string                    (IMEngineInstanceBase   *si);
-static void     slot_hide_lookup_table                  (IMEngineInstanceBase   *si);
-
-static void     slot_update_preedit_caret               (IMEngineInstanceBase   *si,
-                                                         int                     caret);
-static void     slot_update_preedit_string              (IMEngineInstanceBase   *si,
-                                                         const WideString       &str,
-                                                         const AttributeList    &attrs);
-static void     slot_update_aux_string                  (IMEngineInstanceBase   *si,
-                                                         const WideString       &str,
-                                                         const AttributeList    &attrs);
-static void     slot_commit_string                      (IMEngineInstanceBase   *si,
-                                                         const WideString       &str);
-static void     slot_forward_key_event                  (IMEngineInstanceBase   *si,
-                                                         const KeyEvent         &key);
-static void     slot_update_lookup_table                (IMEngineInstanceBase   *si,
-                                                         const LookupTable      &table);
-
-static void     slot_register_properties                (IMEngineInstanceBase   *si,
-                                                         const PropertyList     &properties);
-static void     slot_update_property                    (IMEngineInstanceBase   *si,
-                                                         const Property         &property);
-static void     slot_beep                               (IMEngineInstanceBase   *si);
-static void     slot_start_helper                       (IMEngineInstanceBase   *si,
-                                                         const String           &helper_uuid);
-static void     slot_stop_helper                        (IMEngineInstanceBase   *si,
-                                                         const String           &helper_uuid);
-static void     slot_send_helper_event                  (IMEngineInstanceBase   *si,
-                                                         const String           &helper_uuid,
-                                                         const Transaction      &trans);
-static bool     slot_get_surrounding_text               (IMEngineInstanceBase   *si,
-                                                         WideString             &text,
-                                                         int                    &cursor,
-                                                         int                     maxlen_before,
-                                                         int                     maxlen_after);
-static bool     slot_delete_surrounding_text            (IMEngineInstanceBase   *si,
-                                                         int                     offset,
-                                                         int                     len);
-
-static void     reload_config_callback                  (const ConfigPointer    &config);
-
-static void     fallback_commit_string_cb               (IMEngineInstanceBase   *si,
-                                                         const WideString       &str);
-
-static void     caps_mode_check                         (Ecore_IMF_Context *ctx, Eina_Bool force);
-
-/* Local variables declaration */
-static String                                           _language;
-static EcoreIMFContextISFImpl                          *_used_ic_impl_list          = 0;
-static EcoreIMFContextISFImpl                          *_free_ic_impl_list          = 0;
-static EcoreIMFContextISF                              *_ic_list                    = 0;
-
-static KeyboardLayout                                   _keyboard_layout            = SCIM_KEYBOARD_Default;
-static int                                              _valid_key_mask             = SCIM_KEY_AllMasks;
-
-static FrontEndHotkeyMatcher                            _frontend_hotkey_matcher;
-static IMEngineHotkeyMatcher                            _imengine_hotkey_matcher;
-
-static IMEngineInstancePointer                          _default_instance;
-
-static ConfigModule                                    *_config_module              = 0;
-static ConfigPointer                                    _config;
-static BackEndPointer                                   _backend;
-
-static EcoreIMFContextISF                              *_focused_ic                 = 0;
-
-static bool                                             _scim_initialized           = false;
-
-static int                                              _instance_count             = 0;
-static int                                              _context_count              = 0;
-
-static IMEngineFactoryPointer                           _fallback_factory;
-static IMEngineInstancePointer                          _fallback_instance;
-static PanelClient                                      _panel_client;
-
-static Ecore_Fd_Handler                                *_panel_iochannel_read_handler = 0;
-static Ecore_Fd_Handler                                *_panel_iochannel_err_handler  = 0;
-
-static Ecore_X_Window                                  _client_window               = 0;
-
-static bool                                             _on_the_spot                = true;
-static bool                                             _shared_input_method        = false;
-
-static Eina_Bool                                        autocap_allow = EINA_FALSE;
-
-static Display *__current_display      = 0;
-static int      __current_alt_mask     = Mod1Mask;
-static int      __current_meta_mask    = 0;
-static int      __current_super_mask   = 0;
-static int      __current_hyper_mask   = 0;
-static int      __current_numlock_mask = Mod2Mask;
-
-// A hack to shutdown the immodule cleanly even if im_module_exit() is not called when exiting.
-class FinalizeHandler
-{
-public:
-   FinalizeHandler()
-     {
-        SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler()\n";
-     }
-   ~FinalizeHandler()
-     {
-        SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler()\n";
-        isf_imf_context_shutdown();
-     }
-};
-
-static FinalizeHandler                                  _finalize_handler;
-
-static unsigned int
-utf8_offset_to_index(const char *str, int offset)
-{
-   int index = 0;
-   int i;
-   for (i = 0; i < offset; i++)
-     {
-        eina_unicode_utf8_get_next(str, &index);
-     }
-
-   return index;
-}
-
-static unsigned int
-get_time(void)
-{
-   unsigned int tint;
-   struct timeval tv;
-   struct timezone tz;           /* is not used since ages */
-   gettimeofday(&tv, &tz);
-   tint = tv.tv_sec * 1000;
-   tint = tint / 1000 * 1000;
-   tint = tint + tv.tv_usec / 1000;
-   return tint;
-}
-
-/* Function Implementations */
-static EcoreIMFContextISFImpl *
-new_ic_impl(EcoreIMFContextISF *parent)
-{
-   EcoreIMFContextISFImpl *impl = NULL;
-
-   if (_free_ic_impl_list != NULL)
-     {
-        impl = _free_ic_impl_list;
-        _free_ic_impl_list = _free_ic_impl_list->next;
-     }
-   else
-     {
-        impl = new EcoreIMFContextISFImpl;
-        if (impl == NULL)
-          return NULL;
-     }
-
-   impl->uppercase = false;
-   impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
-   impl->next = _used_ic_impl_list;
-   _used_ic_impl_list = impl;
-
-   impl->parent = parent;
-
-   return impl;
-}
-
-static void
-delete_ic_impl(EcoreIMFContextISFImpl *impl)
-{
-   EcoreIMFContextISFImpl *rec = _used_ic_impl_list, *last = 0;
-
-   for (; rec != 0; last = rec, rec = rec->next)
-     {
-        if (rec == impl)
-          {
-             if (last != 0)
-               last->next = rec->next;
-             else
-               _used_ic_impl_list = rec->next;
-
-             rec->next = _free_ic_impl_list;
-             _free_ic_impl_list = rec;
-
-             rec->parent = 0;
-             rec->si.reset();
-             rec->client_window = 0;
-             rec->preedit_string = WideString();
-             rec->preedit_attrlist.clear();
-
-             return;
-          }
-     }
-}
-
-static void
-delete_all_ic_impl(void)
-{
-   EcoreIMFContextISFImpl *it = _used_ic_impl_list;
-
-   while (it != 0)
-     {
-        _used_ic_impl_list = it->next;
-        delete it;
-        it = _used_ic_impl_list;
-     }
-
-   it = _free_ic_impl_list;
-   while (it != 0)
-     {
-        _free_ic_impl_list = it->next;
-        delete it;
-        it = _free_ic_impl_list;
-     }
-}
-
-static EcoreIMFContextISF *
-find_ic(int id)
-{
-   EcoreIMFContextISFImpl *rec = _used_ic_impl_list;
-
-   while (rec != 0)
-     {
-        if (rec->parent && rec->parent->id == id)
-          return rec->parent;
-        rec = rec->next;
-     }
-
-   return 0;
-}
-
-static Eina_Bool
-analyze_surrounding_text(Ecore_IMF_Context *ctx)
-{
-   char *plain_str = NULL;
-   char *markup_str = NULL;
-   const char *puncs[] = {". ", "! ", "? "};
-   Eina_Bool ret = EINA_FALSE;
-   int cursor_pos = 0;
-   int i = 0;
-   Eina_Unicode *tail = NULL;
-   Eina_Unicode *ustr = NULL;
-   const int punc_num = sizeof(puncs) / sizeof(puncs[0]);
-   Eina_Unicode *uni_puncs[punc_num];
-   EcoreIMFContextISF *context_scim;
-
-   if (!ctx) return EINA_FALSE;
-   context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-   if (!context_scim || !context_scim->impl) return EINA_FALSE;
-
-   switch (context_scim->impl->autocapital_type)
-     {
-      case ECORE_IMF_AUTOCAPITAL_TYPE_NONE:
-         return EINA_FALSE;
-      case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER:
-         return EINA_TRUE;
-      default:
-         break;
-     }
-
-   for (i = 0; i < punc_num; i++)
-     uni_puncs[i] = eina_unicode_utf8_to_unicode(puncs[i], NULL);
-
-   ecore_imf_context_surrounding_get(ctx, &markup_str, &cursor_pos);
-   if (!markup_str) goto done;
-
-   if (cursor_pos == 0)
-     {
-        ret = EINA_TRUE;
-        goto done;
-     }
-
-   // Convert into plain string
-   plain_str = evas_textblock_text_markup_to_utf8(NULL, markup_str);
-   if (!plain_str) goto done;
-
-   // Convert string from UTF-8 to unicode
-   ustr = eina_unicode_utf8_to_unicode(plain_str, NULL);
-   if (!ustr) goto done;
-
-   if (cursor_pos >= 1)
-     {
-        if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD)
-          {
-             if (ustr[cursor_pos-1] == ' ')
-               {
-                  ret = EINA_TRUE;
-                  goto done;
-               }
-          }
-
-        // Check paragraph separator <PS> and carriage return  <br>
-        if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n'))
-          {
-             ret = EINA_TRUE;
-             goto done;
-          }
-     }
-
-   // check punctuation
-   if (cursor_pos >= 2)
-     {
-        tail = eina_unicode_strndup(ustr+cursor_pos-2, 2);
-
-        if (tail)
-          {
-             for (i = 0; i < punc_num; i++)
-               {
-                  if (!eina_unicode_strcmp(tail, uni_puncs[i]))
-                    {
-                       ret = EINA_TRUE;
-                       break;
-                    }
-               }
-             free(tail);
-             tail = NULL;
-          }
-     }
-
-done:
-   if (ustr) free(ustr);
-   if (markup_str) free(markup_str);
-   if (plain_str) free(plain_str);
-
-   for (i = 0; i < punc_num; i++)
-     if (uni_puncs[i]) free(uni_puncs[i]);
-
-   return ret;
-}
-
-static void
-caps_mode_check(Ecore_IMF_Context *ctx, Eina_Bool force)
-{
-   Eina_Bool uppercase;
-   EcoreIMFContextISF *context_scim;
-
-   if (!ctx) return;
-   context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (autocap_allow == EINA_FALSE)
-     return;
-
-   // Check autocapital type
-   if (!context_scim || !context_scim->impl)
-     return;
-
-   if (analyze_surrounding_text(ctx))
-     uppercase = EINA_TRUE;
-   else
-     uppercase = EINA_FALSE;
-
-   if (force)
-     context_scim->impl->uppercase = uppercase;
-   else
-     if (context_scim->impl->uppercase != uppercase)
-       context_scim->impl->uppercase = uppercase;
-}
-
-static void
-feed_key_event(Evas *evas, const char *str, Eina_Bool fake)
-{
-   char key_string[128] = {0};
-   unsigned int timestamp = 0;
-
-   if (!fake)
-     timestamp = get_time();
-
-   if (strncmp(str, "KeyRelease+", 11) == 0)
-     {
-        strncpy(key_string, str + 11, strlen(str)-11);
-        evas_event_feed_key_up(evas, key_string, key_string, NULL, NULL, timestamp, NULL);
-        SCIM_DEBUG_FRONTEND(1) << "    evas_event_feed_key_up()...\n";
-     }
-   else
-     {
-        strncpy(key_string, str, strlen(str));
-        evas_event_feed_key_down(evas, key_string, key_string, NULL, NULL, timestamp, NULL);
-        SCIM_DEBUG_FRONTEND(1) << "    evas_event_feed_key_down()...\n";
-     }
-}
-
-static void
-window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y)
-{
-   Ecore_X_Window root_window, win;
-   int win_x, win_y;
-   int sum_x = 0, sum_y = 0;
-
-   root_window = ecore_x_window_root_get(client_win);
-   win = client_win;
-
-   while (root_window != win)
-     {
-        ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL);
-        sum_x += win_x;
-        sum_y += win_y;
-        win = ecore_x_window_parent_get(win);
-     }
-
-   if (x)
-     *x = sum_x;
-   if (y)
-     *y = sum_y;
-}
-
-/* Public functions */
-/**
- * isf_imf_context_new
- *
- * This function will be called by Ecore IMF.
- * Create a instance of type EcoreIMFContextISF.
- *
- * Return value: A pointer to the newly created EcoreIMFContextISF instance
- */
-EAPI EcoreIMFContextISF *
-isf_imf_context_new(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-   char *env;
-
-   EcoreIMFContextISF *context_scim = new EcoreIMFContextISF;
-   if (context_scim == NULL)
-     {
-        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
-        return NULL;
-     }
-
-   context_scim->id = _context_count++;
-
-   if (!_scim_initialized)
-     {
-        initialize();
-        _scim_initialized = true;
-     }
-
-   env = getenv("ECORE_IMF_AUTOCAPITAL_ALLOW");
-   if (env)
-     autocap_allow = !!atoi(env);
-
-   return context_scim;
-}
-
-/**
- * isf_imf_context_shutdown
- *
- * It will be called when the scim im module is unloaded by ecore. It will do some
- * cleanup job.
- */
-EAPI void
-isf_imf_context_shutdown(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (_scim_initialized)
-     {
-        _scim_initialized = false;
-        finalize();
-     }
-}
-
-EAPI void
-isf_imf_context_add(Ecore_IMF_Context *ctx)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-
-   if (!context_scim) return;
-
-   context_scim->impl = NULL;
-
-   if (_backend.null())
-     return;
-
-   IMEngineInstancePointer si;
-
-   // Use the default instance if "shared input method" mode is enabled.
-   if (_shared_input_method && !_default_instance.null())
-     {
-        si = _default_instance;
-        SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n";
-     }
-
-   // Not in "shared input method" mode, or no default instance, create an instance.
-   if (si.null())
-     {
-        IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
-        if (factory.null()) return;
-        si = factory->create_instance("UTF-8", _instance_count++);
-        if (si.null()) return;
-        attach_instance(si);
-        SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n";
-     }
-
-   // If "shared input method" mode is enabled, and there is no default instance,
-   // then store this instance as default one.
-   if (_shared_input_method && _default_instance.null())
-     {
-        SCIM_DEBUG_FRONTEND(2) << "update default instance.\n";
-        _default_instance = si;
-     }
-
-   context_scim->ctx                       = ctx;
-   context_scim->impl                      = new_ic_impl(context_scim);
-   if (context_scim->impl == NULL)
-     {
-        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
-        return;
-     }
-
-   context_scim->impl->si                  = si;
-   context_scim->impl->client_window       = 0;
-   context_scim->impl->client_canvas       = NULL;
-   context_scim->impl->preedit_caret       = 0;
-   context_scim->impl->cursor_x            = 0;
-   context_scim->impl->cursor_y            = 0;
-   context_scim->impl->cursor_pos          = -1;
-   context_scim->impl->is_on               = false;
-   context_scim->impl->shared_si           = _shared_input_method;
-   context_scim->impl->use_preedit         = _on_the_spot;
-   context_scim->impl->preedit_started     = false;
-   context_scim->impl->preedit_updating    = false;
-   context_scim->impl->need_commit_preedit = false;
-
-   if (!_ic_list)
-     context_scim->next = NULL;
-   else
-     context_scim->next = _ic_list;
-   _ic_list = context_scim;
-
-   if (_shared_input_method)
-     context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
-
-   _panel_client.prepare(context_scim->id);
-   _panel_client.register_input_context(context_scim->id, si->get_factory_uuid());
-   set_ic_capabilities(context_scim);
-   _panel_client.send();
-
-   SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n";
-}
-
-EAPI void
-isf_imf_context_del(Ecore_IMF_Context *ctx)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (!_ic_list) return;
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-
-   if (context_scim)
-     {
-        if (context_scim->id != _ic_list->id)
-          {
-             EcoreIMFContextISF * pre = _ic_list;
-             EcoreIMFContextISF * cur = _ic_list->next;
-             while (cur != NULL)
-               {
-                  if (cur->id == context_scim->id)
-                    {
-                       pre->next = cur->next;
-                       break;
-                    }
-                  pre = cur;
-                  cur = cur->next;
-               }
-          }
-        else
-          _ic_list = _ic_list->next;
-     }
-
-   if (context_scim && context_scim->impl)
-     {
-        _panel_client.prepare(context_scim->id);
-
-        if (context_scim == _focused_ic)
-          context_scim->impl->si->focus_out();
-
-        // Delete the instance.
-        EcoreIMFContextISF *old_focused = _focused_ic;
-        _focused_ic = context_scim;
-        context_scim->impl->si.reset();
-        _focused_ic = old_focused;
-
-        if (context_scim == _focused_ic)
-          {
-             _panel_client.turn_off(context_scim->id);
-             _panel_client.focus_out(context_scim->id);
-          }
-
-        _panel_client.remove_input_context(context_scim->id);
-        _panel_client.send();
-
-        if (context_scim->impl->client_window)
-          isf_imf_context_client_window_set(ctx, NULL);
-
-        if (context_scim->impl)
-          {
-             delete_ic_impl(context_scim->impl);
-             context_scim->impl = 0;
-          }
-     }
-
-   if (context_scim == _focused_ic)
-     _focused_ic = 0;
-
-   if (context_scim)
-     {
-        delete context_scim;
-        context_scim = 0;
-     }
-}
-
-/**
- * isf_imf_context_client_canvas_set
- * @ctx: a #Ecore_IMF_Context
- * @canvas: the client canvas
- *
- * This function will be called by Ecore IMF.
- *
- * Set the client canvas for the Input Method Context; this is the canvas
- * in which the input appears.
- *
- * The canvas type can be determined by using the context canvas type.
- * Actually only canvas with type "evas" (Evas *) is supported. This canvas
- * may be used in order to correctly position status windows, and may also
- * be used for purposes internal to the Input Method Context.
- */
-EAPI void
-isf_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->client_canvas != (Evas*) canvas)
-     context_scim->impl->client_canvas = (Evas*)canvas;
-}
-
-/**
- * isf_imf_context_client_window_set
- * @ctx: a #Ecore_IMF_Context
- * @window: the client window
- *
- * This function will be called by Ecore IMF.
- *
- * Set the client window for the Input Method Context; this is the Ecore_X_Window
- * when using X11, Ecore_Win32_Window when using Win32, etc.
- *
- * This window is used in order to correctly position status windows,
- * and may also be used for purposes internal to the Input Method Context.
- */
-EAPI void
-isf_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->client_window != (Ecore_X_Window)((Ecore_Window)window))
-     {
-        context_scim->impl->client_window = (Ecore_X_Window)((Ecore_Window)window);
-
-        if ((context_scim->impl->client_window != 0) &&
-            (context_scim->impl->client_window != _client_window))
-          _client_window = context_scim->impl->client_window;
-     }
-}
-
-/**
- * isf_imf_context_reset
- * @ctx: a #Ecore_IMF_Context
- *
- * This function will be called by Ecore IMF.
- *
- * Notify the Input Method Context that a change such as a change in cursor
- * position has been made. This will typically cause the Input Method Context
- * to clear the preedit state.
- */
-EAPI void
-isf_imf_context_reset(Ecore_IMF_Context *ctx)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim == _focused_ic)
-     {
-        WideString wstr = context_scim->impl->preedit_string;
-
-        _panel_client.prepare(context_scim->id);
-        context_scim->impl->si->reset();
-        _panel_client.send();
-
-        if (context_scim->impl->need_commit_preedit)
-          {
-             if (wstr.length())
-               {
-                  ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str());
-                  ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
-               }
-             _panel_client.prepare(context_scim->id);
-             _panel_client.send();
-          }
-     }
-}
-
-/**
- * isf_imf_context_focus_in
- * @ctx: a #Ecore_IMF_Context
- *
- * This function will be called by Ecore IMF.
- *
- * Notify the Input Method Context that the widget to which its correspond has gained focus.
- */
-EAPI void
-isf_imf_context_focus_in(Ecore_IMF_Context *ctx)
-{
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (!context_scim)
-     return;
-
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n";
-
-   if (_focused_ic)
-     {
-        if (_focused_ic == context_scim)
-          {
-             SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n";
-             return;
-          }
-        SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n";
-        if (_focused_ic->ctx)
-          isf_imf_context_focus_out(_focused_ic->ctx);
-     }
-
-   bool need_cap   = false;
-   bool need_reset = false;
-   bool need_reg   = false;
-
-   if (context_scim && context_scim->impl)
-     {
-        _focused_ic = context_scim;
-        _panel_client.prepare(context_scim->id);
-
-        // Handle the "Shared Input Method" mode.
-        if (_shared_input_method)
-          {
-             SCIM_DEBUG_FRONTEND(2) << "shared input method.\n";
-             IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
-             if (!factory.null())
-               {
-                  if (_default_instance.null() || _default_instance->get_factory_uuid() != factory->get_uuid())
-                    {
-                       _default_instance = factory->create_instance("UTF-8", _default_instance.null() ? _instance_count++ : _default_instance->get_id());
-                       attach_instance(_default_instance);
-                       SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id() << " " << _default_instance->get_factory_uuid() << "\n";
-                    }
-
-                  context_scim->impl->shared_si = true;
-                  context_scim->impl->si = _default_instance;
-
-                  context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
-                  context_scim->impl->preedit_string.clear();
-                  context_scim->impl->preedit_attrlist.clear();
-                  context_scim->impl->preedit_caret = 0;
-                  context_scim->impl->preedit_started = false;
-                  need_cap = true;
-                  need_reset = true;
-                  need_reg = true;
-               }
-          }
-        else if (context_scim->impl->shared_si)
-          {
-             SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n";
-             IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
-             if (!factory.null())
-               {
-                  context_scim->impl->si = factory->create_instance("UTF-8", _instance_count++);
-                  context_scim->impl->preedit_string.clear();
-                  context_scim->impl->preedit_attrlist.clear();
-                  context_scim->impl->preedit_caret = 0;
-                  context_scim->impl->preedit_started = false;
-                  attach_instance(context_scim->impl->si);
-                  need_cap = true;
-                  need_reg = true;
-                  context_scim->impl->shared_si = false;
-                  SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id() << " " << context_scim->impl->si->get_factory_uuid() << "\n";
-               }
-          }
-
-        context_scim->impl->si->set_frontend_data(static_cast <void*>(context_scim));
-
-        if (need_reg) _panel_client.register_input_context(context_scim->id, context_scim->impl->si->get_factory_uuid());
-        if (need_cap) set_ic_capabilities(context_scim);
-        if (need_reset) context_scim->impl->si->reset();
-
-        panel_req_focus_in(context_scim);
-        panel_req_update_spot_location(context_scim);
-        panel_req_update_factory_info(context_scim);
-
-        if (context_scim->impl->is_on)
-          {
-             _panel_client.turn_on(context_scim->id);
-             _panel_client.hide_preedit_string(context_scim->id);
-             _panel_client.hide_aux_string(context_scim->id);
-             _panel_client.hide_lookup_table(context_scim->id);
-             context_scim->impl->si->focus_in();
-          }
-        else
-          {
-             _panel_client.turn_off(context_scim->id);
-          }
-
-        _panel_client.send();
-     }
-
-   if (ecore_imf_context_input_panel_enabled_get(ctx))
-     ecore_imf_context_input_panel_show(ctx);
-}
-
-/**
- * isf_imf_context_focus_out
- * @ctx: a #Ecore_IMF_Context
- *
- * This function will be called by Ecore IMF.
- *
- * Notify the Input Method Context that the widget to which its correspond has lost focus.
- */
-EAPI void
-isf_imf_context_focus_out(Ecore_IMF_Context *ctx)
-{
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (!context_scim) return;
-
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n";
-
-   if (context_scim && context_scim->impl && context_scim == _focused_ic)
-     {
-        WideString wstr = context_scim->impl->preedit_string;
-
-        if (context_scim->impl->need_commit_preedit)
-          {
-             if (wstr.length())
-               {
-                  ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str());
-                  ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
-               }
-             _panel_client.prepare(context_scim->id);
-             _panel_client.send();
-          }
-
-        _panel_client.prepare(context_scim->id);
-        context_scim->impl->si->focus_out();
-        context_scim->impl->si->reset();
-        _panel_client.turn_off(context_scim->id);
-        _panel_client.focus_out(context_scim->id);
-        _panel_client.send();
-        _focused_ic = 0;
-     }
-
-   if (ecore_imf_context_input_panel_enabled_get(ctx))
-     ecore_imf_context_input_panel_hide(ctx);
-}
-
-/**
- * isf_imf_context_cursor_location_set
- * @ctx: a #Ecore_IMF_Context
- * @x: x position of New cursor.
- * @y: y position of New cursor.
- * @w: the width of New cursor.
- * @h: the height of New cursor.
- *
- * This function will be called by Ecore IMF.
- *
- * Notify the Input Method Context that a change in the cursor location has been made.
- */
-EAPI void
-isf_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int cx, int cy, int cw, int ch)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-   Ecore_Evas *ee;
-   int canvas_x, canvas_y;
-   int new_cursor_x, new_cursor_y;
-
-   if (cw == 0 && ch == 0)
-     return;
-
-   if (context_scim && context_scim->impl && context_scim == _focused_ic)
-     {
-        if (context_scim->impl->client_canvas)
-          {
-             ee = ecore_evas_ecore_evas_get(context_scim->impl->client_canvas);
-             if (!ee) return;
-
-             ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
-          }
-        else
-          {
-             if (context_scim->impl->client_window)
-               window_to_screen_geometry_get(context_scim->impl->client_window, &canvas_x, &canvas_y);
-             else
-               return;
-          }
-
-        new_cursor_x = canvas_x + cx;
-        new_cursor_y = canvas_y + cy + ch;
-
-        // Don't update spot location while updating preedit string.
-        if (context_scim->impl->preedit_updating && (context_scim->impl->cursor_y == new_cursor_y))
-          return;
-
-        if (context_scim->impl->cursor_x != new_cursor_x || context_scim->impl->cursor_y != new_cursor_y)
-          {
-             context_scim->impl->cursor_x     = new_cursor_x;
-             context_scim->impl->cursor_y     = new_cursor_y;
-             _panel_client.prepare(context_scim->id);
-             panel_req_update_spot_location(context_scim);
-             _panel_client.send();
-             SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n";
-          }
-     }
-}
-
-/**
- * isf_imf_context_use_preedit_set
- * @ctx: a #Ecore_IMF_Context
- * @use_preedit: Whether the IM context should use the preedit string.
- *
- * This function will be called by Ecore IMF.
- *
- * Set whether the IM context should use the preedit string to display feedback.
- * If is 0 (default is 1), then the IM context may use some other method to
- * display feedback, such as displaying it in a child of the root window.
- */
-EAPI void
-isf_imf_context_use_preedit_set(Ecore_IMF_Context* ctx, Eina_Bool use_preedit)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (use_preedit ? "true" : "false") << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-
-   if (!_on_the_spot) return;
-
-   if (context_scim && context_scim->impl)
-     {
-        bool old = context_scim->impl->use_preedit;
-        context_scim->impl->use_preedit = use_preedit;
-        if (context_scim == _focused_ic)
-          {
-             _panel_client.prepare(context_scim->id);
-
-             if (old != use_preedit)
-               set_ic_capabilities(context_scim);
-
-             if (context_scim->impl->preedit_string.length())
-               slot_show_preedit_string(context_scim->impl->si);
-
-             _panel_client.send();
-          }
-     }
-}
-
-EAPI void
-isf_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->is_on)
-     {
-        String mbs = utf8_wcstombs(context_scim->impl->preedit_string);
-
-        if (str)
-          {
-             if (mbs.length())
-               *str = strdup(mbs.c_str());
-             else
-               *str = strdup("");
-          }
-
-        if (cursor_pos)
-          {
-             *cursor_pos = context_scim->impl->preedit_caret;
-          }
-
-        if (attrs)
-          {
-             if (mbs.length())
-               {
-                  int start_index, end_index;
-                  int wlen = context_scim->impl->preedit_string.length();
-
-                  Ecore_IMF_Preedit_Attr *attr = NULL;
-                  AttributeList::const_iterator i;
-                  bool *attrs_flag = new bool [mbs.length()];
-                  memset(attrs_flag, 0, mbs.length() *sizeof(bool));
-
-                  for (i = context_scim->impl->preedit_attrlist.begin();
-                       i != context_scim->impl->preedit_attrlist.end(); ++i)
-                    {
-                       start_index = i->get_start();
-                       end_index = i->get_end();
-
-                       if (end_index <= wlen && start_index < end_index && i->get_type() != SCIM_ATTR_DECORATE_NONE)
-                         {
-                            start_index = utf8_offset_to_index(mbs.c_str(), i->get_start());
-                            end_index = utf8_offset_to_index(mbs.c_str(), i->get_end());
-
-                            if (i->get_type() == SCIM_ATTR_DECORATE)
-                              {
-                                 attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
-                                 if (attr == NULL)
-                                   continue;
-                                 attr->start_index = start_index;
-                                 attr->end_index = end_index;
-
-                                 if (i->get_value() == SCIM_ATTR_DECORATE_UNDERLINE)
-                                   {
-                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
-                                      *attrs = eina_list_append(*attrs, (void *)attr);
-                                   }
-                                 else if (i->get_value() == SCIM_ATTR_DECORATE_REVERSE)
-                                   {
-                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
-                                      *attrs = eina_list_append(*attrs, (void *)attr);
-                                   }
-                                 else if (i->get_value() == SCIM_ATTR_DECORATE_HIGHLIGHT)
-                                   {
-                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
-                                      *attrs = eina_list_append(*attrs, (void *)attr);
-                                   }
-                                 else
-                                   {
-                                      free(attr);
-                                   }
-
-                                 switch(i->get_value())
-                                   {
-                                    case SCIM_ATTR_DECORATE_UNDERLINE:
-                                    case SCIM_ATTR_DECORATE_REVERSE:
-                                    case SCIM_ATTR_DECORATE_HIGHLIGHT:
-                                       // Record which character has attribute.
-                                       for (int pos = start_index; pos < end_index; ++pos)
-                                         attrs_flag [pos] = 1;
-                                       break;
-                                    default:
-                                       break;
-                                   }
-                            }
-                            else if (i->get_type() == SCIM_ATTR_FOREGROUND)
-                              {
-                                 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n";
-                              }
-                            else if (i->get_type() == SCIM_ATTR_BACKGROUND)
-                              {
-                                 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n";
-                              }
-                         }
-                    }
-
-                  // Add underline for all characters which don't have attribute.
-                  for (unsigned int pos = 0; pos < mbs.length(); ++pos)
-                    {
-                       if (!attrs_flag [pos])
-                         {
-                            int begin_pos = pos;
-
-                            while (pos < mbs.length() && !attrs_flag[pos])
-                              ++pos;
-
-                            // use REVERSE style as default
-                            attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
-                            if (attr == NULL)
-                              continue;
-                            attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
-                            attr->start_index = begin_pos;
-                            attr->end_index = pos;
-                            *attrs = eina_list_append(*attrs, (void *)attr);
-                         }
-                    }
-
-                  delete [] attrs_flag;
-               }
-          }
-     }
-   else
-     {
-        if (str)
-          *str = strdup("");
-
-        if (cursor_pos)
-          *cursor_pos = 0;
-
-        if (attrs)
-          *attrs = NULL;
-     }
-}
-
-/**
- * isf_imf_context_preedit_string_get
- * @ctx: a #Ecore_IMF_Context
- * @str: the preedit string
- * @cursor_pos: the cursor position
- *
- * This function will be called by Ecore IMF.
- *
- * To get the preedit string of the input method.
- */
-EAPI void
-isf_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char** str, int *cursor_pos)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->is_on)
-     {
-        String mbs = utf8_wcstombs(context_scim->impl->preedit_string);
-
-        if (str)
-          {
-             if (mbs.length())
-               *str = strdup(mbs.c_str());
-             else
-               *str = strdup("");
-          }
-
-        if (cursor_pos)
-          *cursor_pos = context_scim->impl->preedit_caret;
-     }
-   else
-     {
-        if (str)
-          *str = strdup("");
-
-        if (cursor_pos)
-          *cursor_pos = 0;
-     }
-}
-
-/**
- * isf_imf_context_cursor_position_set
- * @ctx: a #Ecore_IMF_Context
- * @cursor_pos: New cursor position in characters.
- *
- * This function will be called by Ecore IMF.
- *
- * Notify the Input Method Context that a change in the cursor position has been made.
- */
-EAPI void
-isf_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim == _focused_ic)
-     {
-        // Don't update spot location while updating preedit string.
-        if (context_scim->impl->preedit_updating)
-          return;
-
-        if (context_scim->impl->cursor_pos != cursor_pos)
-          {
-             context_scim->impl->cursor_pos = cursor_pos;
-             caps_mode_check(ctx, EINA_FALSE);
-          }
-     }
-}
-
-/**
- * isf_imf_context_input_mode_set
- * @ctx: a #Ecore_IMF_Context
- * @input_mode: the input mode
- *
- * This function will be called by Ecore IMF.
- *
- * To set the input mode of input method. The definition of Ecore_IMF_Input_Mode
- * is in Ecore_IMF.h.
- */
-EAPI void
-isf_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-   if (context_scim && context_scim->impl)
-     context_scim->impl->input_mode = input_mode;
-}
-
-/**
- * isf_imf_context_prediction_allow_set
- * @ctx: a #Ecore_IMF_Context
- * @use_prediction: Whether the IM context should use the prediction.
- *
- * This function will be called by Ecore IMF.
- *
- * Set whether the IM context should use the prediction.
- */
-EAPI void
-isf_imf_context_prediction_allow_set(Ecore_IMF_Context* ctx, Eina_Bool prediction)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction ? "true" : "false") << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction)
-     context_scim->impl->prediction_allow = prediction;
-}
-
-EAPI void
-isf_imf_context_autocapital_type_set(Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << autocapital_type << "...\n";
-
-   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
-
-   if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type)
-     context_scim->impl->autocapital_type = autocapital_type;
-}
-
-/**
- * isf_imf_context_filter_event
- * @ctx: a #Ecore_IMF_Context
- * @type: The type of event defined by Ecore_IMF_Event_Type.
- * @event: The event itself.
- * Return value: %TRUE if the input method handled the key event.
- *
- * This function will be called by Ecore IMF.
- *
- * Allow an Ecore Input Context to internally handle an event. If this function
- * returns 1, then no further processing should be done for this event. Input
- * methods must be able to accept all types of events (simply returning 0 if
- * the event was not handled), but there is no obligation of any events to be
- * submitted to this function.
- */
-EAPI Eina_Bool
-isf_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-   Eina_Bool ret = EINA_FALSE;
-
-   if (ic == NULL || ic->impl == NULL)
-     return ret;
-
-   KeyEvent key;
-
-   if (type == ECORE_IMF_EVENT_KEY_DOWN)
-     {
-        Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
-        scim_string_to_key(key, ev->key);
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask;
-        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask;
-        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask;
-     }
-   else if (type == ECORE_IMF_EVENT_KEY_UP)
-     {
-        Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event;
-        scim_string_to_key(key, ev->key);
-        key.mask = SCIM_KEY_ReleaseMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask;
-        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask;
-        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask;
-        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask;
-     }
-   else
-     {
-        return ret;
-     }
-
-   key.mask &= _valid_key_mask;
-
-   _panel_client.prepare(ic->id);
-
-   ret = EINA_TRUE;
-   if (!filter_hotkeys(ic, key))
-     {
-        if (!_focused_ic || !_focused_ic->impl->is_on ||
-            !_focused_ic->impl->si->process_key_event(key))
-          ret = EINA_FALSE;
-     }
-
-   _panel_client.send();
-
-   return ret;
-}
-
-EAPI void
-isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-   if (ic == NULL || ic->impl == NULL)
-     return;
-
-   ecore_x_e_virtual_keyboard_state_set
-        (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
-}
-
-EAPI void
-isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
-   if (ic == NULL || ic->impl == NULL)
-     return;
-
-   ecore_x_e_virtual_keyboard_state_set
-        (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
-}
-
-/* Panel Slot functions */
-static void
-panel_slot_reload_config(int context EINA_UNUSED)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-   _config->reload();
-}
-
-static void
-panel_slot_exit(int /* context */)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   finalize();
-}
-
-static void
-panel_slot_update_lookup_table_page_size(int context, int page_size)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " page_size=" << page_size << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->update_lookup_table_page_size(page_size);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_lookup_table_page_up(int context)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->lookup_table_page_up();
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_lookup_table_page_down(int context)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->lookup_table_page_down();
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_trigger_property(int context, const String &property)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " property=" << property << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->trigger_property(property);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_process_helper_event(int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid
-      << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic ? ic->impl : 0) << " ic-uuid="
-      << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid() : "" ) << "\n";
-   if (ic && ic->impl && ic->impl->si->get_factory_uuid() == target_uuid)
-     {
-        _panel_client.prepare(ic->id);
-        SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n";
-        ic->impl->si->process_helper_event(helper_uuid, trans);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_move_preedit_caret(int context, int caret_pos)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->move_preedit_caret(caret_pos);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_select_candidate(int context, int cand_index)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n";
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        ic->impl->si->select_candidate(cand_index);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_process_key_event(int context, const KeyEvent &key)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n";
-
-   if (key.is_key_press())
-     ecore_x_test_fake_key_press(key.get_key_string().c_str());
-}
-
-static void
-panel_slot_commit_string(int context, const WideString &wstr)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs(wstr) << " ic=" << ic << "\n";
-
-   if (ic && ic->impl)
-     {
-        if (_focused_ic != ic)
-          return;
-
-        ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(wstr).c_str());
-        ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
-     }
-}
-
-static void
-panel_slot_forward_key_event(int context, const KeyEvent &key)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n";
-
-   if (ic && ic->impl && ic->impl->client_canvas)
-     feed_key_event(ic->impl->client_canvas, key.get_key_string().c_str(), EINA_TRUE);
-}
-
-static void
-panel_slot_request_help(int context)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
-
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        panel_req_show_help(ic);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_request_factory_menu(int context)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
-
-   if (ic && ic->impl)
-     {
-        _panel_client.prepare(ic->id);
-        panel_req_show_factory_menu(ic);
-        _panel_client.send();
-     }
-}
-
-static void
-panel_slot_change_factory(int context, const String &uuid)
-{
-   EcoreIMFContextISF *ic = find_ic(context);
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n";
-
-   if (ic && ic->impl)
-     {
-        ic->impl->si->reset();
-        _panel_client.prepare(ic->id);
-        open_specific_factory(ic, uuid);
-        _panel_client.send();
-     }
-}
-
-/* Panel Requestion functions. */
-static void
-panel_req_show_help(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   String help;
-
-   help =  String("Smart Common Input Method platform ") +
-      //String(SCIM_VERSION) +
-      String("\n(C) 2002-2005 James Su <suzhe@tsinghua.org.cn>\n\n");
-
-   if (ic && ic->impl)
-     {
-        IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid());
-        if (sf)
-          {
-             help += utf8_wcstombs(sf->get_name());
-             help += String(":\n\n");
-
-             help += utf8_wcstombs(sf->get_help());
-             help += String("\n\n");
-
-             help += utf8_wcstombs(sf->get_credits());
-          }
-        _panel_client.show_help(ic->id, help);
-     }
-}
-
-static void
-panel_req_show_factory_menu(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   std::vector<IMEngineFactoryPointer> factories;
-   std::vector <PanelFactoryInfo> menu;
-
-   _backend->get_factories_for_encoding(factories, "UTF-8");
-
-   for (size_t i = 0; i < factories.size(); ++ i)
-     {
-        menu.push_back(PanelFactoryInfo(
-              factories [i]->get_uuid(),
-              utf8_wcstombs(factories [i]->get_name()),
-              factories [i]->get_language(),
-              factories [i]->get_icon_file()));
-     }
-
-   if (menu.size())
-     _panel_client.show_factory_menu(ic->id, menu);
-}
-
-static void
-panel_req_update_factory_info(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (ic && ic->impl && ic == _focused_ic)
-     {
-        PanelFactoryInfo info;
-        if (ic->impl->is_on)
-          {
-             IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid());
-             if (sf)
-               info = PanelFactoryInfo(sf->get_uuid(), utf8_wcstombs(sf->get_name()), sf->get_language(), sf->get_icon_file());
-          }
-        else
-          {
-             info = PanelFactoryInfo(String(""), String("English/Keyboard"), String("C"), "");
-          }
-        _panel_client.update_factory_info(ic->id, info);
-     }
-}
-
-static void
-panel_req_focus_in(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   _panel_client.focus_in(ic->id, ic->impl->si->get_factory_uuid());
-}
-
-static void
-panel_req_update_spot_location(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   _panel_client.update_spot_location(ic->id, ic->impl->cursor_x, ic->impl->cursor_y);
-}
-
-static bool
-filter_hotkeys(EcoreIMFContextISF *ic, const KeyEvent &key)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   bool ret = false;
-
-   _frontend_hotkey_matcher.push_key_event(key);
-   _imengine_hotkey_matcher.push_key_event(key);
-
-   FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result();
-
-   if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER)
-     {
-        if (!ic->impl->is_on)
-          turn_on_ic(ic);
-        else
-          turn_off_ic(ic);
-        ret = true;
-     }
-   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON)
-     {
-        if (!ic->impl->is_on)
-          turn_on_ic(ic);
-        ret = true;
-     }
-   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF)
-     {
-        if (ic->impl->is_on)
-          turn_off_ic(ic);
-        ret = true;
-     }
-   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY)
-     {
-        open_next_factory(ic);
-        ret = true;
-     }
-   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY)
-     {
-        open_previous_factory(ic);
-        ret = true;
-     }
-   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU)
-     {
-        panel_req_show_factory_menu(ic);
-        ret = true;
-     }
-   else if (_imengine_hotkey_matcher.is_matched())
-     {
-        String sfid = _imengine_hotkey_matcher.get_match_result();
-        open_specific_factory(ic, sfid);
-        ret = true;
-     }
-   return ret;
-}
-
-static bool
-panel_initialize(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   String display_name;
-     {
-        const char *p = getenv("DISPLAY");
-        if (p) display_name = String(p);
-     }
-
-   if (_panel_client.open_connection(_config->get_name(), display_name) >= 0)
-     {
-        int fd = _panel_client.get_connection_number();
-
-        _panel_iochannel_read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, panel_iochannel_handler, NULL, NULL, NULL);
-
-        SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n";
-
-        return true;
-   }
-   std::cerr << "panel_initialize() failed!!!\n";
-   return false;
-}
-
-static void
-panel_finalize(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   _panel_client.close_connection();
-
-   if (_panel_iochannel_read_handler)
-     {
-        ecore_main_fd_handler_del(_panel_iochannel_read_handler);
-        _panel_iochannel_read_handler = 0;
-     }
-
-   if (_panel_iochannel_err_handler)
-     {
-        ecore_main_fd_handler_del(_panel_iochannel_err_handler);
-        _panel_iochannel_err_handler = 0;
-     }
-}
-
-static Eina_Bool
-panel_iochannel_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (fd_handler == _panel_iochannel_read_handler)
-     {
-        if (!_panel_client.filter_event())
-          {
-             panel_finalize();
-             panel_initialize();
-             return ECORE_CALLBACK_CANCEL;
-          }
-     }
-   else if (fd_handler == _panel_iochannel_err_handler)
-     {
-        panel_finalize();
-        panel_initialize();
-        return ECORE_CALLBACK_CANCEL;
-     }
-   return ECORE_CALLBACK_RENEW;
-}
-
-static void
-turn_on_ic(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (ic && ic->impl && !ic->impl->is_on)
-     {
-        ic->impl->is_on = true;
-
-        if (ic == _focused_ic)
-          {
-             panel_req_focus_in(ic);
-             panel_req_update_spot_location(ic);
-             panel_req_update_factory_info(ic);
-             _panel_client.turn_on(ic->id);
-             _panel_client.hide_preedit_string(ic->id);
-             _panel_client.hide_aux_string(ic->id);
-             _panel_client.hide_lookup_table(ic->id);
-             ic->impl->si->focus_in();
-          }
-
-        //Record the IC on/off status
-        if (_shared_input_method)
-          _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true);
-
-        if (ic->impl->use_preedit && ic->impl->preedit_string.length())
-          {
-             ecore_imf_context_preedit_start_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-             ecore_imf_context_preedit_changed_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-             ic->impl->preedit_started = true;
-          }
-     }
-}
-
-static void
-turn_off_ic(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (ic && ic->impl && ic->impl->is_on)
-     {
-        ic->impl->is_on = false;
-
-        if (ic == _focused_ic)
-          {
-             ic->impl->si->focus_out();
-
-             panel_req_update_factory_info(ic);
-             _panel_client.turn_off(ic->id);
-          }
-
-        //Record the IC on/off status
-        if (_shared_input_method)
-          _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false);
-
-        if (ic->impl->use_preedit && ic->impl->preedit_string.length())
-          {
-             ecore_imf_context_preedit_changed_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-             ecore_imf_context_preedit_end_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-             ic->impl->preedit_started = false;
-          }
-     }
-}
-
-static void
-set_ic_capabilities(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (ic && ic->impl)
-     {
-        unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES;
-
-        if (!_on_the_spot || !ic->impl->use_preedit)
-          cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT;
-
-        ic->impl->si->update_client_capabilities(cap);
-     }
-}
-
-static bool
-check_socket_frontend(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   SocketAddress address;
-   SocketClient client;
-
-   uint32 magic;
-
-   address.set_address(scim_get_default_socket_frontend_address());
-
-   if (!client.connect(address))
-     return false;
-
-   if (!scim_socket_open_connection(magic,
-                                    String("ConnectionTester"),
-                                    String("SocketFrontEnd"),
-                                    client,
-                                    1000))
-        return false;
-
-   return true;
-}
-
-void
-initialize(void)
-{
-   std::vector<String>     config_list;
-   std::vector<String>     engine_list;
-   std::vector<String>     load_engine_list;
-
-   std::vector<String>::iterator it;
-
-   bool                    manual = false;
-
-   bool                    socket = true;
-
-   String                  config_module_name = "simple";
-
-   printf("Initializing Ecore SCIM IMModule...\n");
-
-   SCIM_DEBUG_FRONTEND(1) << "Initializing Ecore SCIM IMModule...\n";
-
-   // Get system language.
-   _language = scim_get_locale_language(scim_get_current_locale());
-
-   if (socket)
-     {
-        // If no Socket FrontEnd is running, then launch one.
-        // And set manual to false.
-        bool check_result = check_socket_frontend();
-        if (!check_result)
-          {
-             std::cerr << "Launching a SCIM daemon with Socket FrontEnd...\n";
-             //get modules list
-             scim_get_imengine_module_list(engine_list);
-
-             for (it = engine_list.begin(); it != engine_list.end(); it++)
-               {
-                  if (*it != "socket")
-                    load_engine_list.push_back(*it);
-               }
-
-             const char *new_argv [] = { "--no-stay", 0 };
-             scim_launch(true,
-                         config_module_name,
-                         (load_engine_list.size() ? scim_combine_string_list(load_engine_list, ',') : "none"),
-                         "socket",
-                         (char **)new_argv);
-             manual = false;
-          }
-
-        // If there is one Socket FrontEnd running and it's not manual mode,
-        // then just use this Socket Frontend.
-        if (!manual)
-          {
-             for (int i = 0; i < 200; ++i)
-               {
-                  if (check_result)
-                    {
-                       config_module_name = "socket";
-                       load_engine_list.clear();
-                       load_engine_list.push_back("socket");
-                       break;
-                    }
-                  scim_usleep(50000);
-                  check_result = check_socket_frontend();
-               }
-          }
-     }
-
-   if (config_module_name != "dummy")
-     {
-        //load config module
-        SCIM_DEBUG_FRONTEND(1) << "Loading Config module: " << config_module_name << "...\n";
-        _config_module = new ConfigModule(config_module_name);
-
-        //create config instance
-        if (_config_module != NULL && _config_module->valid())
-          _config = _config_module->create_config();
-     }
-
-   if (_config.null())
-     {
-        SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n";
-
-        if (_config_module) delete _config_module;
-        _config_module = NULL;
-
-        _config = new DummyConfig();
-        config_module_name = "dummy";
-     }
-
-   reload_config_callback(_config);
-   _config->signal_connect_reload(slot(reload_config_callback));
-
-   // create backend
-   _backend = new CommonBackEnd(_config, load_engine_list.size() ? load_engine_list : engine_list);
-
-   if (_backend.null())
-     std::cerr << "Cannot create BackEnd Object!\n";
-   else
-     _fallback_factory = _backend->get_factory(SCIM_COMPOSE_KEY_FACTORY_UUID);
-
-   if (_fallback_factory.null())
-     _fallback_factory = new DummyIMEngineFactory();
-
-   _fallback_instance = _fallback_factory->create_instance(String("UTF-8"), 0);
-   _fallback_instance->signal_connect_commit_string(slot(fallback_commit_string_cb));
-
-   // Attach Panel Client signal.
-   _panel_client.signal_connect_reload_config                (slot(panel_slot_reload_config));
-   _panel_client.signal_connect_exit                         (slot(panel_slot_exit));
-   _panel_client.signal_connect_update_lookup_table_page_size(slot(panel_slot_update_lookup_table_page_size));
-   _panel_client.signal_connect_lookup_table_page_up         (slot(panel_slot_lookup_table_page_up));
-   _panel_client.signal_connect_lookup_table_page_down       (slot(panel_slot_lookup_table_page_down));
-   _panel_client.signal_connect_trigger_property             (slot(panel_slot_trigger_property));
-   _panel_client.signal_connect_process_helper_event         (slot(panel_slot_process_helper_event));
-   _panel_client.signal_connect_move_preedit_caret           (slot(panel_slot_move_preedit_caret));
-   _panel_client.signal_connect_select_candidate             (slot(panel_slot_select_candidate));
-   _panel_client.signal_connect_process_key_event            (slot(panel_slot_process_key_event));
-   _panel_client.signal_connect_commit_string                (slot(panel_slot_commit_string));
-   _panel_client.signal_connect_forward_key_event            (slot(panel_slot_forward_key_event));
-   _panel_client.signal_connect_request_help                 (slot(panel_slot_request_help));
-   _panel_client.signal_connect_request_factory_menu         (slot(panel_slot_request_factory_menu));
-   _panel_client.signal_connect_change_factory               (slot(panel_slot_change_factory));
-
-   if (!panel_initialize())
-     std::cerr << "Ecore IM Module: Cannot connect to Panel!\n";
-}
-
-static void
-finalize(void)
-{
-   SCIM_DEBUG_FRONTEND(1) << "Finalizing Ecore ISF IMModule...\n";
-
-   // Reset this first so that the shared instance could be released correctly afterwards.
-   _default_instance.reset();
-
-   SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n";
-   while (_used_ic_impl_list)
-     {
-        // In case in "shared input method" mode,
-        // all contexts share only one instance,
-        // so we need point the reference pointer correctly before finalizing.
-        _used_ic_impl_list->si->set_frontend_data(static_cast <void*>(_used_ic_impl_list->parent));
-        isf_imf_context_del(_used_ic_impl_list->parent->ctx);
-     }
-
-   delete_all_ic_impl();
-
-   _fallback_instance.reset();
-   _fallback_factory.reset();
-
-   SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n";
-   _backend.reset();
-
-   SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n";
-   _config.reset();
-
-   if (_config_module)
-     {
-        SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n";
-        delete _config_module;
-        _config_module = 0;
-     }
-
-   _focused_ic = NULL;
-   _ic_list = NULL;
-
-   _scim_initialized = false;
-
-   panel_finalize();
-}
-
-static void
-open_next_factory(EcoreIMFContextISF *ic)
-{
-   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
-   IMEngineFactoryPointer sf = _backend->get_next_factory("", "UTF-8", ic->impl->si->get_factory_uuid());
-
-   if (!sf.null())
-     {
-        turn_off_ic(ic);
-        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
-        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
-        ic->impl->preedit_string = WideString();
-        ic->impl->preedit_caret = 0;
-        attach_instance(ic->impl->si);
-        _backend->set_default_factory(_language, sf->get_uuid());
-        _panel_client.register_input_context(ic->id, sf->get_uuid());
-        set_ic_capabilities(ic);
-        turn_on_ic(ic);
-
-        if (_shared_input_method)
-          {
-             _default_instance = ic->impl->si;
-             ic->impl->shared_si = true;
-          }
-     }
-}
-
-static void
-open_previous_factory(EcoreIMFContextISF *ic)
-{
-   if (ic == NULL)
-     return;
-
-   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
-   IMEngineFactoryPointer sf = _backend->get_previous_factory("", "UTF-8", ic->impl->si->get_factory_uuid());
-
-   if (!sf.null())
-     {
-        turn_off_ic(ic);
-        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
-        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
-        ic->impl->preedit_string = WideString();
-        ic->impl->preedit_caret = 0;
-        attach_instance(ic->impl->si);
-        _backend->set_default_factory(_language, sf->get_uuid());
-        _panel_client.register_input_context(ic->id, sf->get_uuid());
-        set_ic_capabilities(ic);
-        turn_on_ic(ic);
-
-        if (_shared_input_method)
-          {
-             _default_instance = ic->impl->si;
-             ic->impl->shared_si = true;
-          }
-     }
-}
-
-static void
-open_specific_factory(EcoreIMFContextISF *ic,
-                       const String     &uuid)
-{
-   if (ic == NULL)
-     return;
-
-   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
-
-   // The same input method is selected, just turn on the IC.
-   if (ic->impl->si->get_factory_uuid() == uuid)
-     {
-        turn_on_ic(ic);
-        return;
-     }
-
-   IMEngineFactoryPointer sf = _backend->get_factory(uuid);
-
-   if (uuid.length() && !sf.null())
-     {
-        turn_off_ic(ic);
-        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
-        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
-        ic->impl->preedit_string = WideString();
-        ic->impl->preedit_caret = 0;
-        attach_instance(ic->impl->si);
-        _backend->set_default_factory(_language, sf->get_uuid());
-        _panel_client.register_input_context(ic->id, sf->get_uuid());
-        set_ic_capabilities(ic);
-        turn_on_ic(ic);
-
-        if (_shared_input_method)
-          {
-             _default_instance = ic->impl->si;
-             ic->impl->shared_si = true;
-          }
-     }
-   else
-     {
-        // turn_off_ic comment out panel_req_update_factory_info()
-        turn_off_ic(ic);
-        if (ic && ic->impl->is_on)
-          {
-             ic->impl->is_on = false;
-
-             if (ic == _focused_ic)
-               {
-                  ic->impl->si->focus_out();
-
-                  panel_req_update_factory_info(ic);
-                  _panel_client.turn_off(ic->id);
-               }
-
-             //Record the IC on/off status
-             if (_shared_input_method)
-               _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false);
-
-             if (ic->impl->use_preedit && ic->impl->preedit_string.length())
-               {
-                  ecore_imf_context_preedit_changed_event_add(ic->ctx);
-                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-                  ecore_imf_context_preedit_end_event_add(ic->ctx);
-                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-                  ic->impl->preedit_started = false;
-               }
-          }
-     }
-}
-
-static void initialize_modifier_bits(Display *display)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (__current_display == display)
-     return;
-
-   __current_display = display;
-
-   if (display == 0)
-     {
-        __current_alt_mask     = Mod1Mask;
-        __current_meta_mask    = ShiftMask | Mod1Mask;
-        __current_super_mask   = 0;
-        __current_hyper_mask   = 0;
-        __current_numlock_mask = Mod2Mask;
-        return;
-     }
-
-   XModifierKeymap *mods = NULL;
-
-   ::KeyCode ctrl_l  = XKeysymToKeycode(display, XK_Control_L);
-   ::KeyCode ctrl_r  = XKeysymToKeycode(display, XK_Control_R);
-   ::KeyCode meta_l  = XKeysymToKeycode(display, XK_Meta_L);
-   ::KeyCode meta_r  = XKeysymToKeycode(display, XK_Meta_R);
-   ::KeyCode alt_l   = XKeysymToKeycode(display, XK_Alt_L);
-   ::KeyCode alt_r   = XKeysymToKeycode(display, XK_Alt_R);
-   ::KeyCode super_l = XKeysymToKeycode(display, XK_Super_L);
-   ::KeyCode super_r = XKeysymToKeycode(display, XK_Super_R);
-   ::KeyCode hyper_l = XKeysymToKeycode(display, XK_Hyper_L);
-   ::KeyCode hyper_r = XKeysymToKeycode(display, XK_Hyper_R);
-   ::KeyCode numlock = XKeysymToKeycode(display, XK_Num_Lock);
-
-   int i, j;
-
-   mods = XGetModifierMapping(display);
-   if (mods == NULL)
-     return;
-
-   __current_alt_mask     = 0;
-   __current_meta_mask    = 0;
-   __current_super_mask   = 0;
-   __current_hyper_mask   = 0;
-   __current_numlock_mask = 0;
-
-   /* We skip the first three sets for Shift, Lock, and Control.  The
-      remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5.  */
-   for (i = 3; i < 8; i++)
-     {
-        for (j = 0; j < mods->max_keypermod; j++)
-          {
-             ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j];
-             if (! code) continue;
-             if (code == alt_l || code == alt_r)
-               __current_alt_mask |= (1 << i);
-             else if (code == meta_l || code == meta_r)
-               __current_meta_mask |= (1 << i);
-             else if (code == super_l || code == super_r)
-               __current_super_mask |= (1 << i);
-             else if (code == hyper_l || code == hyper_r)
-               __current_hyper_mask |= (1 << i);
-             else if (code == numlock)
-               __current_numlock_mask |= (1 << i);
-          }
-     }
-
-   /* Check whether there is a combine keys mapped to Meta */
-   if (__current_meta_mask == 0)
-     {
-        char buf [32];
-        XKeyEvent xkey;
-        KeySym keysym_l, keysym_r;
-
-        xkey.type = KeyPress;
-        xkey.display = display;
-        xkey.serial = 0L;
-        xkey.send_event = False;
-        xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0;
-        xkey.time = 0;
-        xkey.same_screen = False;
-        xkey.subwindow = None;
-        xkey.window = None;
-        xkey.root = DefaultRootWindow(display);
-        xkey.state = ShiftMask;
-
-        xkey.keycode = meta_l;
-        XLookupString(&xkey, buf, 32, &keysym_l, 0);
-        xkey.keycode = meta_r;
-        XLookupString(&xkey, buf, 32, &keysym_r, 0);
-
-        if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R))
-          __current_meta_mask = ShiftMask + __current_alt_mask;
-        else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R))
-          __current_meta_mask = ShiftMask + ControlMask;
-     }
-
-   XFreeModifiermap(mods);
-}
-
-static unsigned int scim_x11_keymask_scim_to_x11(Display *display, uint16 scimkeymask)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   unsigned int state = 0;
-
-   initialize_modifier_bits(display);
-
-   if (scimkeymask & SCIM_KEY_ShiftMask)    state |= ShiftMask;
-   if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask;
-   if (scimkeymask & SCIM_KEY_ControlMask)  state |= ControlMask;
-   if (scimkeymask & SCIM_KEY_AltMask)      state |= __current_alt_mask;
-   if (scimkeymask & SCIM_KEY_MetaMask)     state |= __current_meta_mask;
-   if (scimkeymask & SCIM_KEY_SuperMask)    state |= __current_super_mask;
-   if (scimkeymask & SCIM_KEY_HyperMask)    state |= __current_hyper_mask;
-   if (scimkeymask & SCIM_KEY_NumLockMask)  state |= __current_numlock_mask;
-
-   return state;
-}
-
-static XKeyEvent createKeyEvent(Display *display, Window &win,
-                                Window &winRoot, bool press,
-                                int keysym, int modifiers)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   XKeyEvent event;
-
-   event.display     = display;
-   event.window      = win;
-   event.root        = winRoot;
-   event.subwindow   = None;
-   event.time        = CurrentTime;
-   event.x           = 1;
-   event.y           = 1;
-   event.x_root      = 1;
-   event.y_root      = 1;
-   event.same_screen = EINA_TRUE;
-   event.state       = modifiers;
-   event.keycode     = XKeysymToKeycode(display, keysym);
-   if (press)
-     event.type = KeyPress;
-   else
-     event.type = KeyRelease;
-   event.send_event  = EINA_FALSE;
-   event.serial = 0;
-
-   return event;
-}
-
-static void _x_send_key_event(const KeyEvent &key)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   // Obtain the X11 display.
-   Display *display = (Display *)ecore_x_display_get();
-   if (display == NULL)
-     {
-        std::cerr << "ecore_x_display_get() failed\n";
-        return;
-     }
-
-   // Get the root window for the current display.
-   Window winRoot = 0;
-
-   // Find the window which has the current keyboard focus.
-   Window winFocus = 0;
-   int revert = RevertToParent;
-
-   XGetInputFocus(display, &winFocus, &revert);
-
-   unsigned int modifier = scim_x11_keymask_scim_to_x11(display, key.mask);
-   XKeyEvent event;
-   if (key.is_key_press())
-     {
-        event = createKeyEvent(display, winFocus, winRoot, true, key.code, modifier);
-        XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
-     }
-   else
-     {
-        event = createKeyEvent(display, winFocus, winRoot, false, key.code, modifier);
-        XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event);
-     }
-}
-
-static void
-attach_instance(const IMEngineInstancePointer &si)
-{
-   si->signal_connect_show_preedit_string(
-      slot(slot_show_preedit_string));
-   si->signal_connect_show_aux_string(
-      slot(slot_show_aux_string));
-   si->signal_connect_show_lookup_table(
-      slot(slot_show_lookup_table));
-
-   si->signal_connect_hide_preedit_string(
-      slot(slot_hide_preedit_string));
-   si->signal_connect_hide_aux_string(
-      slot(slot_hide_aux_string));
-   si->signal_connect_hide_lookup_table(
-      slot(slot_hide_lookup_table));
-
-   si->signal_connect_update_preedit_caret(
-      slot(slot_update_preedit_caret));
-   si->signal_connect_update_preedit_string(
-      slot(slot_update_preedit_string));
-   si->signal_connect_update_aux_string(
-      slot(slot_update_aux_string));
-   si->signal_connect_update_lookup_table(
-      slot(slot_update_lookup_table));
-
-   si->signal_connect_commit_string(
-      slot(slot_commit_string));
-
-   si->signal_connect_forward_key_event(
-      slot(slot_forward_key_event));
-
-   si->signal_connect_register_properties(
-      slot(slot_register_properties));
-
-   si->signal_connect_update_property(
-      slot(slot_update_property));
-
-   si->signal_connect_beep(
-      slot(slot_beep));
-
-   si->signal_connect_start_helper(
-      slot(slot_start_helper));
-
-   si->signal_connect_stop_helper(
-      slot(slot_stop_helper));
-
-   si->signal_connect_send_helper_event(
-      slot(slot_send_helper_event));
-
-   si->signal_connect_get_surrounding_text(
-      slot(slot_get_surrounding_text));
-
-   si->signal_connect_delete_surrounding_text(
-      slot(slot_delete_surrounding_text));
-}
-
-// Implementation of slot functions
-static void
-slot_show_preedit_string(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     {
-        if (ic->impl->use_preedit)
-          {
-             if (!ic->impl->preedit_started)
-               {
-                  ecore_imf_context_preedit_start_event_add(_focused_ic->ctx);
-                  ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-                  ic->impl->preedit_started = true;
-               }
-          }
-        else
-          _panel_client.show_preedit_string(ic->id);
-     }
-}
-
-static void
-slot_show_aux_string(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.show_aux_string(ic->id);
-}
-
-static void
-slot_show_lookup_table(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.show_lookup_table(ic->id);
-}
-
-static void
-slot_hide_preedit_string(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     {
-        bool emit = false;
-        if (ic->impl->preedit_string.length())
-          {
-             ic->impl->preedit_string = WideString();
-             ic->impl->preedit_caret = 0;
-             ic->impl->preedit_attrlist.clear();
-             emit = true;
-          }
-        if (ic->impl->use_preedit)
-          {
-             if (emit)
-               {
-                  ecore_imf_context_preedit_changed_event_add(ic->ctx);
-                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-               }
-             if (ic->impl->preedit_started)
-               {
-                  ecore_imf_context_preedit_end_event_add(ic->ctx);
-                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-                  ic->impl->preedit_started = false;
-               }
-          }
-        else
-          _panel_client.hide_preedit_string(ic->id);
-     }
-}
-
-static void
-slot_hide_aux_string(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.hide_aux_string(ic->id);
-}
-
-static void
-slot_hide_lookup_table(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.hide_lookup_table(ic->id);
-}
-
-static void
-slot_update_preedit_caret(IMEngineInstanceBase *si, int caret)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret)
-     {
-        ic->impl->preedit_caret = caret;
-        if (ic->impl->use_preedit)
-          {
-             if (!ic->impl->preedit_started)
-               {
-                  ecore_imf_context_preedit_start_event_add(ic->ctx);
-                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-                  ic->impl->preedit_started = true;
-               }
-             ecore_imf_context_preedit_changed_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-          }
-        else
-          _panel_client.update_preedit_caret(ic->id, caret);
-     }
-}
-
-static void
-slot_update_preedit_string(IMEngineInstanceBase *si,
-                            const WideString & str,
-                            const AttributeList & attrs)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length()))
-     {
-        ic->impl->preedit_string   = str;
-        ic->impl->preedit_attrlist = attrs;
-        if (ic->impl->use_preedit)
-          {
-             if (!ic->impl->preedit_started)
-               {
-                  ecore_imf_context_preedit_start_event_add(_focused_ic->ctx);
-                  ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-                  ic->impl->preedit_started = true;
-               }
-             ic->impl->preedit_caret    = str.length();
-             ic->impl->preedit_updating = true;
-             ecore_imf_context_preedit_changed_event_add(ic->ctx);
-             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-             ic->impl->preedit_updating = false;
-          }
-        else
-          {
-             _panel_client.update_preedit_string(ic->id, str, attrs);
-          }
-     }
-}
-
-static void
-slot_update_aux_string(IMEngineInstanceBase *si,
-                        const WideString & str,
-                        const AttributeList & attrs)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.update_aux_string(ic->id, str, attrs);
-}
-
-static void
-slot_commit_string(IMEngineInstanceBase *si,
-                    const WideString & str)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->ctx)
-     {
-        ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(str).c_str());
-        ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str());
-     }
-}
-
-static void
-slot_forward_key_event(IMEngineInstanceBase *si,
-                        const KeyEvent & key)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && _focused_ic == ic)
-     {
-        if (!_fallback_instance->process_key_event(key))
-          _x_send_key_event(key);
-     }
-}
-
-static void
-slot_update_lookup_table(IMEngineInstanceBase *si,
-                          const LookupTable & table)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.update_lookup_table(ic->id, table);
-}
-
-static void
-slot_register_properties(IMEngineInstanceBase *si,
-                         const PropertyList & properties)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.register_properties(ic->id, properties);
-}
-
-static void
-slot_update_property(IMEngineInstanceBase *si,
-                     const Property & property)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     _panel_client.update_property(ic->id, property);
-}
-
-static void
-slot_beep(IMEngineInstanceBase *si)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     ecore_x_bell(0);
-}
-
-static void
-slot_start_helper(IMEngineInstanceBase *si,
-                  const String &helper_uuid)
-{
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
-      << (ic ? ic->id : -1) << " ic=" << ic
-      << " ic-uuid=" << ((ic ) ? ic->impl->si->get_factory_uuid() : "") << "...\n";
-
-   if (ic && ic->impl)
-     _panel_client.start_helper(ic->id, helper_uuid);
-}
-
-static void
-slot_stop_helper(IMEngineInstanceBase *si,
-                 const String &helper_uuid)
-{
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic ? ic->id : -1) << " ic=" << ic << "...\n";
-
-   if (ic && ic->impl)
-     _panel_client.stop_helper(ic->id, helper_uuid);
-}
-
-static void
-slot_send_helper_event(IMEngineInstanceBase *si,
-                       const String      &helper_uuid,
-                       const Transaction &trans)
-{
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
-      << (ic ? ic->id : -1) << " ic=" << ic
-      << " ic-uuid=" << ((ic) ? ic->impl->si->get_factory_uuid() : "") << "...\n";
-
-   if (ic && ic->impl)
-     _panel_client.send_helper_event(ic->id, helper_uuid, trans);
-}
-
-static bool
-slot_get_surrounding_text(IMEngineInstanceBase *si,
-                          WideString            &text,
-                          int                   &cursor,
-                          int                    maxlen_before,
-                          int                    maxlen_after)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     {
-        char *surrounding = NULL;
-        int   cursor_index;
-        if (ecore_imf_context_surrounding_get(_focused_ic->ctx, &surrounding, &cursor_index))
-          {
-             SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n";
-             SCIM_DEBUG_FRONTEND(2) << "Cursor Index    : " << cursor_index <<"\n";
-             WideString before(utf8_mbstowcs(String(surrounding, surrounding + cursor_index)));
-             WideString after(utf8_mbstowcs(String(surrounding + cursor_index)));
-             if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length())
-               before = WideString(before.begin() + (before.length() - maxlen_before), before.end());
-             else if (maxlen_before == 0) before = WideString();
-             if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length())
-               after = WideString(after.begin(), after.begin() + maxlen_after);
-             else if (maxlen_after == 0) after = WideString();
-             text = before + after;
-             cursor = before.length();
-             return true;
-          }
-     }
-   return false;
-}
-
-static bool
-slot_delete_surrounding_text(IMEngineInstanceBase *si,
-                             int                   offset,
-                             int                   len)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
-
-   if (ic && ic->impl && _focused_ic == ic)
-     {
-        Ecore_IMF_Event_Delete_Surrounding ev;
-        ev.ctx = _focused_ic->ctx;
-        ev.n_chars = len;
-        ev.offset = offset;
-        ecore_imf_context_delete_surrounding_event_add(_focused_ic->ctx, offset, len);
-        ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
-        return true;
-     }
-   return false;
-}
-
-static void
-reload_config_callback(const ConfigPointer &config)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   _frontend_hotkey_matcher.load_hotkeys(config);
-   _imengine_hotkey_matcher.load_hotkeys(config);
-
-   KeyEvent key;
-
-   scim_string_to_key(key,
-                      config->read(String(SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK),
-                                     String("Shift+Control+Alt+Lock")));
-
-   _valid_key_mask = (key.mask > 0)?(key.mask):0xFFFF;
-   _valid_key_mask |= SCIM_KEY_ReleaseMask;
-   // Special treatment for two backslash keys on jp106 keyboard.
-   _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask;
-
-   _on_the_spot = config->read(String(SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot);
-   _shared_input_method = config->read(String(SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method);
-
-   // Get keyboard layout setting
-   // Flush the global config first, in order to load the new configs from disk.
-   scim_global_config_flush();
-
-   _keyboard_layout = scim_get_default_keyboard_layout();
-}
-
-static void
-fallback_commit_string_cb(IMEngineInstanceBase  *si EINA_UNUSED,
-                          const WideString      &str)
-{
-   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-   if (_focused_ic && _focused_ic->impl)
-     {
-        ecore_imf_context_commit_event_add(_focused_ic->ctx, utf8_wcstombs(str).c_str());
-        ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str());
-     }
-}
-
diff --git a/src/modules/ecore/immodules/scim/scim_imcontext.h b/src/modules/ecore/immodules/scim/scim_imcontext.h
deleted file mode 100644 (file)
index 72533e2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __ISF_IMF_CONTEXT_H
-#define __ISF_IMF_CONTEXT_H
-
-#include <Ecore_IMF.h>
-
-typedef struct _EcoreIMFContextISF      EcoreIMFContextISF;
-typedef struct _EcoreIMFContextISFImpl  EcoreIMFContextISFImpl;
-
-struct _EcoreIMFContextISF {
-    Ecore_IMF_Context *ctx;
-
-    EcoreIMFContextISFImpl *impl;
-
-    int id; /* Input Context id*/
-    struct _EcoreIMFContextISF *next;
-};
-
-void isf_imf_context_add (Ecore_IMF_Context *ctx);
-void isf_imf_context_del (Ecore_IMF_Context *ctx);
-void isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window);
-void isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *window);
-void isf_imf_context_focus_in (Ecore_IMF_Context *ctx);
-void isf_imf_context_focus_out (Ecore_IMF_Context *ctx);
-void isf_imf_context_reset (Ecore_IMF_Context *ctx);
-void isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos);
-void isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int x, int y, int w, int h);
-void isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode);
-void isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos);
-void isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos);
-void isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit);
-Eina_Bool  isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
-void isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction);
-void isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type);
-void isf_imf_context_input_panel_layout_set (Ecore_IMF_Context* ctx, Ecore_IMF_Input_Panel_Layout layout);
-void isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx);
-void isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx);
-
-EcoreIMFContextISF* isf_imf_context_new      (void);
-void                isf_imf_context_shutdown (void);
-
-#endif  /* __ISF_IMF_CONTEXT_H */
-
diff --git a/src/modules/ecore/immodules/scim/scim_module.cpp b/src/modules/ecore/immodules/scim/scim_module.cpp
deleted file mode 100644 (file)
index d77fb11..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <stdio.h>
-#include "scim_imcontext.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-   static const Ecore_IMF_Context_Info isf_imf_info = {
-        "scim",                                 /* ID */
-        "SCIM immodule for Ecore",              /* Description */
-        "*",                                    /* Default locales */
-        NULL,                                   /* Canvas type */
-        0                                       /* Canvas required */
-   };
-
-   static Ecore_IMF_Context_Class isf_imf_class = {
-        isf_imf_context_add,                    /* add */
-        isf_imf_context_del,                    /* del */
-        isf_imf_context_client_window_set,      /* client_window_set */
-        isf_imf_context_client_canvas_set,      /* client_canvas_set */
-        isf_imf_context_input_panel_show,       /* input_panel_show, - show */
-        isf_imf_context_input_panel_hide,       /* input_panel_hide, - hide */
-        isf_imf_context_preedit_string_get,     /* get_preedit_string */
-        isf_imf_context_focus_in,               /* focus_in */
-        isf_imf_context_focus_out,              /* focus_out */
-        isf_imf_context_reset,                  /* reset */
-        isf_imf_context_cursor_position_set,    /* cursor_position_set */
-        isf_imf_context_use_preedit_set,        /* use_preedit_set */
-        isf_imf_context_input_mode_set,         /* input_mode_set */
-        isf_imf_context_filter_event,           /* filter_event */
-        isf_imf_context_preedit_string_with_attributes_get,  /* preedit_string_with_attribute_get */
-        isf_imf_context_prediction_allow_set,   /* prediction_allow_set */
-        isf_imf_context_autocapital_type_set,   /* autocapital_type_set */
-        NULL,                                   /* control panel show */
-        NULL,                                   /* control panel hide */
-        NULL,                                   /* input_panel_layout_set */
-        NULL,                                   /* isf_imf_context_input_panel_layout_get, */
-        NULL,                                   /* isf_imf_context_input_panel_language_set, */
-        NULL,                                   /* isf_imf_context_input_panel_language_get, */
-        isf_imf_context_cursor_location_set,    /* cursor_location_set */
-        NULL,                                   /* input_panel_imdata_set */
-        NULL,                                   /* input_panel_imdata_get */
-        NULL,                                   /* input_panel_return_key_type_set */
-        NULL,                                   /* input_panel_return_key_disabled_set */
-        NULL,                                   /* input_panel_caps_lock_mode_set */
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        NULL,
-        NULL
-   };
-
-   static Ecore_IMF_Context *imf_module_create (void);
-   static Ecore_IMF_Context *imf_module_exit (void);
-
-   static Eina_Bool imf_module_init (void)
-     {
-        ecore_imf_module_register (&isf_imf_info, imf_module_create, imf_module_exit);
-        return EINA_TRUE;
-     }
-
-   static void imf_module_shutdown (void)
-     {
-        isf_imf_context_shutdown ();
-     }
-
-   static Ecore_IMF_Context *imf_module_create (void)
-     {
-        Ecore_IMF_Context  *ctx = NULL;
-        EcoreIMFContextISF *ctxd = NULL;
-
-        ctxd = isf_imf_context_new ();
-        if (!ctxd)
-          {
-             printf ("isf_imf_context_new () failed!!!\n");
-             return NULL;
-          }
-
-        ctx = ecore_imf_context_new (&isf_imf_class);
-        if (!ctx)
-          {
-             delete ctxd;
-             return NULL;
-          }
-
-        ecore_imf_context_data_set (ctx, ctxd);
-
-        return ctx;
-     }
-
-   static Ecore_IMF_Context *imf_module_exit (void)
-     {
-        return NULL;
-     }
-
-   EINA_MODULE_INIT(imf_module_init);
-   EINA_MODULE_SHUTDOWN(imf_module_shutdown);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
diff --git a/src/modules/ecore/immodules/xim/ecore_imf_xim.c b/src/modules/ecore/immodules/xim/ecore_imf_xim.c
deleted file mode 100644 (file)
index a115b90..0000000
+++ /dev/null
@@ -1,1444 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <Eina.h>
-#include <Ecore.h>
-#include <Ecore_Input.h>
-#include <Ecore_IMF.h>
-#include <Ecore_X.h>
-#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
-#include <X11/Xutil.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <langinfo.h>
-#include <assert.h>
-
-static int _ecore_imf_xim_log_dom = -1;
-
-#ifdef CRITICAL
-#undef CRITICAL
-#endif
-#define CRITICAL(...) EINA_LOG_DOM_CRIT(_ecore_imf_xim_log_dom, __VA_ARGS__)
-
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_ecore_imf_xim_log_dom, __VA_ARGS__)
-
-#ifdef WRN
-#undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_ecore_imf_xim_log_dom, __VA_ARGS__)
-
-#ifdef DBG
-#undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_ecore_imf_xim_log_dom, __VA_ARGS__)
-
-
-static Eina_List *open_ims = NULL;
-
-#define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight)
-
-typedef struct _XIM_Im_Info XIM_Im_Info;
-
-typedef struct _Ecore_IMF_Context_Data Ecore_IMF_Context_Data;
-
-struct _XIM_Im_Info
-{
-   Ecore_X_Window win;
-   Ecore_IMF_Context_Data *user;
-   char          *locale;
-   XIM            im;
-   Eina_List     *ics;
-   Eina_Bool      reconnecting;
-   XIMStyles     *xim_styles;
-   Eina_Bool      supports_string_conversion : 1;
-   Eina_Bool      supports_cursor : 1;
-};
-
-struct _Ecore_IMF_Context_Data
-{
-   Ecore_X_Window win;
-   long           mask;
-   XIC            ic; /* Input context for composed characters */
-   char          *locale;
-   XIM_Im_Info   *im_info;
-   int            preedit_length;
-   int            preedit_cursor;
-   Eina_Unicode  *preedit_chars;
-   Eina_Bool      use_preedit;
-   Eina_Bool      finalizing;
-   Eina_Bool      has_focus;
-   Eina_Bool      in_toplevel;
-   XIMFeedback   *feedbacks;
-
-   XIMCallback    destroy_cb;
-
-   XIMCallback    preedit_start_cb;
-   XIMCallback    preedit_done_cb;
-   XIMCallback    preedit_draw_cb;
-   XIMCallback    preedit_caret_cb;
-};
-
-/* prototype */
-static Ecore_IMF_Context_Data *_ecore_imf_xim_context_data_new(void);
-static void                    _ecore_imf_xim_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data);
-
-static void          _ecore_imf_xim_feedback_attr_add(Eina_List **attrs,
-                                                     const char *str,
-                                                     XIMFeedback feedback,
-                                                     int start_pos,
-                                                     int end_pos);
-
-static void          _ecore_imf_xim_ic_reinitialize(Ecore_IMF_Context *ctx);
-static void          _ecore_imf_xim_ic_client_window_set(Ecore_IMF_Context *ctx,
-                                                        Ecore_X_Window window);
-static int           _ecore_imf_xim_preedit_start_call(XIC xic,
-                                                      XPointer client_data,
-                                                      XPointer call_data);
-static void          _ecore_imf_xim_preedit_done_call(XIC xic,
-                                                     XPointer client_data,
-                                                     XPointer call_data);
-static void          _ecore_imf_xim_preedit_draw_call(XIC xic,
-                                                     XPointer client_data,
-                                                     XIMPreeditDrawCallbackStruct *call_data);
-static void          _ecore_imf_xim_preedit_caret_call(XIC xic,
-                                                      XPointer client_data,
-                                                      XIMPreeditCaretCallbackStruct *call_data);
-
-static int           _ecore_imf_xim_text_to_utf8(Ecore_IMF_Context *ctx,
-                                                XIMText *xim_text,
-                                                char **text);
-
-static XVaNestedList _ecore_imf_xim_preedit_callback_set(Ecore_IMF_Context *ctx);
-static XIC           _ecore_imf_xim_ic_get(Ecore_IMF_Context *ctx);
-static XIM_Im_Info  *_ecore_imf_xim_im_get(Ecore_X_Window window,
-                                          char *locale);
-static void          _ecore_imf_xim_info_im_init(XIM_Im_Info *info);
-static void          _ecore_imf_xim_info_im_shutdown(Ecore_X_Display *display,
-                                             int is_error,
-                                             XIM_Im_Info *info);
-static void          _ecore_imf_xim_instantiate_cb(Display *display,
-                                                  XPointer client_data,
-                                                  XPointer call_data);
-static void          _ecore_imf_xim_destroy_cb(XIM xim,
-                                              XPointer client_data,
-                                              XPointer call_data);
-static void          _ecore_imf_xim_im_setup(XIM_Im_Info *info);
-
-static unsigned int
-_ecore_imf_xim_utf8_offset_to_index(const char *str, int offset)
-{
-   int idx = 0;
-   int i;
-   for (i = 0; i < offset; i++)
-     {
-        eina_unicode_utf8_get_next(str, &idx);
-     }
-
-   return idx;
-}
-
-static void
-_ecore_imf_context_xim_add(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = _ecore_imf_xim_context_data_new();
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   imf_context_data->use_preedit = EINA_TRUE;
-   imf_context_data->finalizing = EINA_FALSE;
-   imf_context_data->has_focus = EINA_FALSE;
-   imf_context_data->in_toplevel = EINA_FALSE;
-
-   ecore_imf_context_data_set(ctx, imf_context_data);
-}
-
-static void
-_ecore_imf_context_xim_del(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   imf_context_data->finalizing = EINA_TRUE;
-   if (imf_context_data->im_info && !imf_context_data->im_info->ics->next)
-     {
-        if (imf_context_data->im_info->reconnecting == EINA_TRUE)
-          {
-             Ecore_X_Display *dsp;
-             dsp = ecore_x_display_get();
-             XUnregisterIMInstantiateCallback(dsp,
-                                              NULL, NULL, NULL,
-                                              _ecore_imf_xim_instantiate_cb,
-                                              (XPointer)imf_context_data->im_info);
-          }
-        else if (imf_context_data->im_info->im)
-          {
-             XIMCallback im_destroy_callback;
-             im_destroy_callback.client_data = NULL;
-             im_destroy_callback.callback = NULL;
-             XSetIMValues(imf_context_data->im_info->im,
-                          XNDestroyCallback, &im_destroy_callback,
-                          NULL);
-          }
-     }
-
-   _ecore_imf_xim_ic_client_window_set(ctx, 0);
-
-   _ecore_imf_xim_context_data_destroy(imf_context_data);
-}
-
-static void
-_ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx,
-                                         void *window)
-{
-   DBG("ctx=%p, window=%p", ctx, window);
-   _ecore_imf_xim_ic_client_window_set(ctx, (Ecore_X_Window)((unsigned long)window));
-}
-
-static void
-_ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx,
-                                          char **str,
-                                          int *cursor_pos)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   char *utf8;
-   int len;
-
-   DBG("ctx=%p, imf_context_data=%p, str=%p, cursor_pos=%p",
-       ctx, imf_context_data, str, cursor_pos);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   if (imf_context_data->preedit_chars)
-     {
-        utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars,
-                                            &len);
-        if (str)
-          *str = utf8;
-        else
-          free(utf8);
-     }
-   else
-     {
-        if (str)
-          *str = NULL;
-        if (cursor_pos)
-          *cursor_pos = 0;
-     }
-
-   if (cursor_pos)
-     *cursor_pos = imf_context_data->preedit_cursor;
-}
-
-static void
-_ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
-                                                          char **str,
-                                                          Eina_List **attrs,
-                                                          int *cursor_pos)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-
-   DBG("ctx=%p, imf_context_data=%p, str=%p, attrs=%p, cursor_pos=%p",
-       ctx, imf_context_data, str, attrs, cursor_pos);
-
-   _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos);
-
-   if (!attrs) return;
-   if (!imf_context_data || !imf_context_data->feedbacks) return;
-
-   int i = 0;
-   XIMFeedback last_feedback = 0;
-   int start = -1;
-
-   for (i = 0; i < imf_context_data->preedit_length; i++)
-     {
-        XIMFeedback new_feedback = imf_context_data->feedbacks[i] & FEEDBACK_MASK;
-
-        if (new_feedback != last_feedback)
-          {
-             if (start >= 0)
-               _ecore_imf_xim_feedback_attr_add(attrs, *str, last_feedback, start, i);
-
-             last_feedback = new_feedback;
-             start = i;
-          }
-     }
-
-   if (start >= 0)
-     _ecore_imf_xim_feedback_attr_add(attrs, *str, last_feedback, start, i);
-}
-
-static void
-_ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data  = ecore_imf_context_data_get(ctx);
-   XIC ic;
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   ic = imf_context_data->ic;
-   imf_context_data->has_focus = EINA_TRUE;
-
-   if (ecore_imf_context_input_panel_enabled_get(ctx))
-     ecore_imf_context_input_panel_show(ctx);
-
-   if (ic)
-     {
-        char *str;
-
-#ifdef X_HAVE_UTF8_STRING
-        if ((str = Xutf8ResetIC(ic)))
-#else
-        if ((str = XmbResetIC(ic)))
-#endif
-          XFree(str);
-
-        XSetICFocus(ic);
-     }
-}
-
-static void
-_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   XIC ic;
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   if (imf_context_data->has_focus == EINA_TRUE)
-     {
-        imf_context_data->has_focus = EINA_FALSE;
-        ic = imf_context_data->ic;
-        if (ic)
-          XUnsetICFocus(ic);
-
-        if (ecore_imf_context_input_panel_enabled_get(ctx))
-          ecore_imf_context_input_panel_hide(ctx);
-     }
-}
-
-static void
-_ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   XIC ic;
-   char *result;
-   /* restore conversion state after resetting ic later */
-   XIMPreeditState preedit_state = XIMPreeditUnKnown;
-   XVaNestedList preedit_attr;
-   Eina_Bool have_preedit_state = EINA_FALSE;
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   ic = imf_context_data->ic;
-   if (!ic)
-     return;
-
-   if (imf_context_data->preedit_length == 0)
-     return;
-
-   preedit_attr = XVaCreateNestedList(0,
-                                      XNPreeditState, &preedit_state,
-                                      NULL);
-   if (!XGetICValues(ic,
-                     XNPreeditAttributes, preedit_attr,
-                     NULL))
-     have_preedit_state = EINA_TRUE;
-
-   XFree(preedit_attr);
-
-   result = XmbResetIC(ic);
-
-   preedit_attr = XVaCreateNestedList(0,
-                                      XNPreeditState, preedit_state,
-                                      NULL);
-   if (have_preedit_state)
-     XSetICValues(ic,
-                  XNPreeditAttributes, preedit_attr,
-                  NULL);
-
-   XFree(preedit_attr);
-
-   if (imf_context_data->feedbacks)
-     {
-        free(imf_context_data->feedbacks);
-        imf_context_data->feedbacks = NULL;
-     }
-
-   if (imf_context_data->preedit_length)
-     {
-        imf_context_data->preedit_length = 0;
-        free(imf_context_data->preedit_chars);
-        imf_context_data->preedit_chars = NULL;
-
-        ecore_imf_context_preedit_changed_event_add(ctx);
-        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-     }
-
-   if (result)
-     {
-        char *result_utf8 = strdup(result);
-        if (result_utf8)
-          {
-             ecore_imf_context_commit_event_add(ctx, result_utf8);
-             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8);
-             free(result_utf8);
-          }
-     }
-
-   XFree(result);
-}
-
-static void
-_ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx,
-                                       Eina_Bool use_preedit)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-
-   DBG("ctx=%p, imf_context_data=%p, use_preedit=%hhu", ctx, imf_context_data, use_preedit);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   use_preedit = use_preedit != EINA_FALSE;
-
-   if (imf_context_data->use_preedit != use_preedit)
-     {
-        imf_context_data->use_preedit = use_preedit;
-        _ecore_imf_xim_ic_reinitialize(ctx);
-     }
-}
-
-static void
-_ecore_imf_xim_feedback_attr_add(Eina_List **attrs,
-                                const char *str,
-                                XIMFeedback feedback,
-                                int start_pos,
-                                int end_pos)
-{
-   Ecore_IMF_Preedit_Attr *attr;
-   unsigned int start_index = _ecore_imf_xim_utf8_offset_to_index(str, start_pos);
-   unsigned int end_index = _ecore_imf_xim_utf8_offset_to_index(str, end_pos);
-
-   if (feedback & FEEDBACK_MASK)
-     {
-        attr = calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
-        attr->start_index = start_index;
-        attr->end_index = end_index;
-        *attrs = eina_list_append(*attrs, attr);
-     }
-   else
-     return;
-
-   if (feedback & XIMUnderline)
-     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
-
-   if (feedback & XIMReverse)
-     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
-
-   if (feedback & XIMHighlight)
-     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
-}
-
-static void
-_ecore_imf_context_xim_cursor_location_set(Ecore_IMF_Context *ctx,
-                                           int x, int y, int w, int h)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   XIC ic;
-   XVaNestedList preedit_attr;
-   XPoint spot;
-
-   DBG("ctx=%p, imf_context_data=%p, location=(%d, %d, %d, %d)",
-       ctx, imf_context_data, x, y, w, h);
-
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-   ic = imf_context_data->ic;
-   if (!ic)
-     return;
-
-   spot.x = x;
-   spot.y = y + h;
-
-   preedit_attr = XVaCreateNestedList(0,
-                                      XNSpotLocation, &spot,
-                                      NULL);
-   XSetICValues(ic,
-                XNPreeditAttributes, preedit_attr,
-                NULL);
-
-   XFree(preedit_attr);
-}
-
-static void
-_ecore_imf_context_xim_input_panel_show(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   ecore_x_e_virtual_keyboard_state_set
-        (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
-}
-
-static void
-_ecore_imf_context_xim_input_panel_hide(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   ecore_x_e_virtual_keyboard_state_set
-        (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
-}
-
-static unsigned int
-_ecore_x_event_reverse_modifiers(unsigned int state)
-{
-   unsigned int modifiers = 0;
-
-   /**< "Control" is pressed */
-   if (state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
-     modifiers |= ECORE_X_MODIFIER_CTRL;
-
-   /**< "Alt" is pressed */
-   if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
-     modifiers |= ECORE_X_MODIFIER_ALT;
-
-   /**< "Shift" is pressed */
-   if (state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
-     modifiers |= ECORE_X_MODIFIER_SHIFT;
-
-   /**< "Win" (between "Ctrl" and "Alt") is pressed */
-   if (state & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
-     modifiers |= ECORE_X_MODIFIER_WIN;
-
-   /**< "AltGr" is pressed */
-   if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
-     modifiers |= ECORE_X_MODIFIER_ALTGR;
-
-   return modifiers;
-}
-
-static unsigned int
-_ecore_x_event_reverse_locks(unsigned int state)
-{
-   unsigned int locks = 0;
-
-   /**< "Num" lock is active */
-   if (state & ECORE_IMF_KEYBOARD_LOCK_NUM)
-     locks |= ECORE_X_LOCK_NUM;
-
-   if (state & ECORE_IMF_KEYBOARD_LOCK_CAPS)
-     locks |= ECORE_X_LOCK_CAPS;
-
-   if (state & ECORE_IMF_KEYBOARD_LOCK_SCROLL)
-     locks |= ECORE_X_LOCK_SCROLL;
-
-   return locks;
-}
-
-static KeyCode
-_ecore_imf_xim_keycode_get(Ecore_X_Display *dsp,
-                           const char *keyname)
-{
-   KeyCode keycode;
-
-   //DBG("keyname=%s keysym=%lu", keyname, XStringToKeysym(keyname));
-   if (strcmp(keyname, "Keycode-0") == 0)
-     keycode = 0;
-   else
-     keycode = XKeysymToKeycode(dsp, XStringToKeysym(keyname));
-
-   return keycode;
-}
-
-static Eina_Bool
-_ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx,
-                                    Ecore_IMF_Event_Type type,
-                                    Ecore_IMF_Event *event)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   XIC ic;
-   Ecore_X_Display *dsp;
-   Ecore_X_Window win;
-
-   int val;
-   char compose_buffer[256];
-   KeySym sym;
-   char *compose = NULL;
-   char *tmp = NULL;
-   Eina_Bool result = EINA_FALSE;
-
-   DBG("ctx=%p, imf_context_data=%p, type=%d, event=%p",
-       ctx, imf_context_data, type, event);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, EINA_FALSE);
-   ic = imf_context_data->ic;
-   if (!ic)
-     ic = _ecore_imf_xim_ic_get(ctx);
-
-   if (type == ECORE_IMF_EVENT_KEY_DOWN)
-     {
-        XKeyPressedEvent xev;
-        Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
-        DBG("ECORE_IMF_EVENT_KEY_DOWN");
-
-        dsp = ecore_x_display_get();
-        win = imf_context_data->win;
-
-        xev.type = KeyPress;
-        xev.serial = 0; /* hope it doesn't matter */
-        xev.send_event = 0;
-        xev.display = dsp;
-        xev.window = win;
-        xev.root = ecore_x_window_root_get(win);
-        xev.subwindow = win;
-        xev.time = ev->timestamp;
-        xev.x = xev.x_root = 0;
-        xev.y = xev.y_root = 0;
-        xev.state = 0;
-        xev.state |= _ecore_x_event_reverse_modifiers(ev->modifiers);
-        xev.state |= _ecore_x_event_reverse_locks(ev->locks);
-        xev.keycode = _ecore_imf_xim_keycode_get(dsp, ev->keyname);
-        xev.same_screen = True;
-
-        if (ic)
-          {
-             Status mbstatus;
-#ifdef X_HAVE_UTF8_STRING
-             val = Xutf8LookupString(ic,
-                                     &xev,
-                                     compose_buffer,
-                                     sizeof(compose_buffer) - 1,
-                                     &sym,
-                                     &mbstatus);
-#else /* ifdef X_HAVE_UTF8_STRING */
-             val = XmbLookupString(ic,
-                                   &xev,
-                                   compose_buffer,
-                                   sizeof(compose_buffer) - 1,
-                                   &sym,
-                                   &mbstatus);
-#endif /* ifdef X_HAVE_UTF8_STRING */
-             if (mbstatus == XBufferOverflow)
-               {
-                  tmp = malloc(sizeof (char) * (val + 1));
-                  if (!tmp)
-                    return EINA_FALSE;
-
-                  compose = tmp;
-
-#ifdef X_HAVE_UTF8_STRING
-                  val = Xutf8LookupString(ic,
-                                          &xev,
-                                          tmp,
-                                          val,
-                                          &sym,
-                                          &mbstatus);
-#else /* ifdef X_HAVE_UTF8_STRING */
-                  val = XmbLookupString(ic,
-                                        &xev,
-                                        tmp,
-                                        val,
-                                        &sym,
-                                        &mbstatus);
-#endif /* ifdef X_HAVE_UTF8_STRING */
-                  if (val > 0)
-                    {
-                       tmp[val] = '\0';
-#ifndef X_HAVE_UTF8_STRING
-                       compose = eina_str_convert(nl_langinfo(CODESET),
-                                                  "UTF-8", tmp);
-                       free(tmp);
-                       tmp = compose;
-#endif /* ifndef X_HAVE_UTF8_STRING */
-                    }
-                  else
-                    compose = NULL;
-               }
-             else if (val > 0)
-               {
-                  compose_buffer[val] = '\0';
-#ifdef X_HAVE_UTF8_STRING
-                  compose = strdup(compose_buffer);
-#else /* ifdef X_HAVE_UTF8_STRING */
-                  compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8",
-                                             compose_buffer);
-#endif /* ifdef X_HAVE_UTF8_STRING */
-               }
-          }
-        else
-          {
-             compose = strdup(ev->compose);
-          }
-
-        if (compose)
-          {
-             Eina_Unicode *unicode;
-             int len;
-             unicode = eina_unicode_utf8_to_unicode(compose, &len);
-             if (!unicode) abort();
-             if (unicode[0] >= 0x20 && unicode[0] != 0x7f)
-               {
-                  ecore_imf_context_commit_event_add(ctx, compose);
-                  ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose);
-                  result = EINA_TRUE;
-               }
-             free(compose);
-             free(unicode);
-          }
-     }
-
-   return result;
-}
-
-static const Ecore_IMF_Context_Info xim_info = {
-   .id = "xim",
-   .description = "X input method",
-   .default_locales = "ko:ja:th:zh",
-   .canvas_type = "evas",
-   .canvas_required = 1,
-};
-
-static Ecore_IMF_Context_Class xim_class = {
-   .add = _ecore_imf_context_xim_add,
-   .del = _ecore_imf_context_xim_del,
-   .client_window_set = _ecore_imf_context_xim_client_window_set,
-   .client_canvas_set = NULL,
-   .show = _ecore_imf_context_xim_input_panel_show,
-   .hide = _ecore_imf_context_xim_input_panel_hide,
-   .preedit_string_get = _ecore_imf_context_xim_preedit_string_get,
-   .focus_in = _ecore_imf_context_xim_focus_in,
-   .focus_out = _ecore_imf_context_xim_focus_out,
-   .reset = _ecore_imf_context_xim_reset,
-   .cursor_position_set = NULL,
-   .use_preedit_set = _ecore_imf_context_xim_use_preedit_set,
-   .input_mode_set = NULL,
-   .filter_event = _ecore_imf_context_xim_filter_event,
-   .preedit_string_with_attributes_get = _ecore_imf_context_xim_preedit_string_with_attributes_get,
-   .prediction_allow_set = NULL,
-   .autocapital_type_set = NULL,
-   .control_panel_show = NULL,
-   .control_panel_hide = NULL,
-   .input_panel_layout_set = NULL,
-   .input_panel_layout_get = NULL,
-   .input_panel_language_set = NULL,
-   .input_panel_language_get = NULL,
-   .cursor_location_set = _ecore_imf_context_xim_cursor_location_set,
-   .input_panel_imdata_set = NULL,
-   .input_panel_imdata_get = NULL,
-   .input_panel_return_key_type_set = NULL,
-   .input_panel_return_key_disabled_set = NULL,
-   .input_panel_caps_lock_mode_set = NULL
-};
-
-static Ecore_IMF_Context *
-xim_imf_module_create(void)
-{
-   Ecore_IMF_Context *ctx = ecore_imf_context_new(&xim_class);
-   DBG("ctx=%p", ctx);
-   return ctx;
-}
-
-static Ecore_IMF_Context *
-xim_imf_module_exit(void)
-{
-   DBG(" ");
-   return NULL;
-}
-
-static Eina_Bool
-_ecore_imf_xim_init(void)
-{
-   eina_init();
-
-   _ecore_imf_xim_log_dom = eina_log_domain_register("ecore_imf_xim", NULL);
-   if (_ecore_imf_xim_log_dom < 0)
-     {
-        EINA_LOG_ERR("Could not register log domain: ecore_imf_xim");
-        return EINA_FALSE;
-     }
-
-   DBG(" ");
-
-   ecore_x_init(NULL);
-   ecore_imf_module_register(&xim_info,
-                             xim_imf_module_create,
-                             xim_imf_module_exit);
-
-   return EINA_TRUE;
-}
-
-static void
-_ecore_imf_xim_shutdown(void)
-{
-   while (open_ims)
-     {
-        XIM_Im_Info *info = open_ims->data;
-        Ecore_X_Display *display = ecore_x_display_get();
-
-        _ecore_imf_xim_info_im_shutdown(display, EINA_FALSE, info);
-     }
-
-   ecore_x_shutdown();
-
-   if (_ecore_imf_xim_log_dom > 0)
-     {
-        eina_log_domain_unregister(_ecore_imf_xim_log_dom);
-        _ecore_imf_xim_log_dom = -1;
-     }
-
-   eina_shutdown();
-}
-
-EINA_MODULE_INIT(_ecore_imf_xim_init);
-EINA_MODULE_SHUTDOWN(_ecore_imf_xim_shutdown);
-
-/*
- * internal functions
- */
-static Ecore_IMF_Context_Data *
-_ecore_imf_xim_context_data_new(void)
-{
-   Ecore_IMF_Context_Data *imf_context_data = NULL;
-   char *locale;
-
-   locale = setlocale(LC_CTYPE, "");
-   if (!locale) return NULL;
-
-   if (!XSupportsLocale()) return NULL;
-
-   imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data));
-   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL);
-
-   imf_context_data->locale = strdup(locale);
-   if (!imf_context_data->locale) goto error;
-
-   return imf_context_data;
-error:
-   _ecore_imf_xim_context_data_destroy(imf_context_data);
-   return NULL;
-}
-
-static void
-_ecore_imf_xim_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data)
-{
-   if (!imf_context_data)
-     return;
-
-   if (imf_context_data->ic)
-     XDestroyIC(imf_context_data->ic);
-
-   free(imf_context_data->preedit_chars);
-
-   if (imf_context_data->feedbacks)
-     {
-        free(imf_context_data->feedbacks);
-        imf_context_data->feedbacks = NULL;
-     }
-
-   free(imf_context_data->locale);
-   free(imf_context_data);
-}
-
-static int
-_ecore_imf_xim_preedit_start_call(XIC xic EINA_UNUSED,
-                                 XPointer client_data,
-                                 XPointer call_data EINA_UNUSED)
-{
-   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, -1);
-
-   if (imf_context_data->finalizing == EINA_FALSE)
-     {
-        ecore_imf_context_preedit_start_event_add(ctx);
-        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
-     }
-   return -1;
-}
-
-static void
-_ecore_imf_xim_preedit_done_call(XIC xic EINA_UNUSED,
-                                XPointer client_data,
-                                XPointer call_data EINA_UNUSED)
-{
-   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   if (imf_context_data->preedit_length)
-     {
-        imf_context_data->preedit_length = 0;
-        free(imf_context_data->preedit_chars);
-        imf_context_data->preedit_chars = NULL;
-        ecore_imf_context_preedit_changed_event_add(ctx);
-        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-     }
-
-   if (imf_context_data->finalizing == EINA_FALSE)
-     {
-        ecore_imf_context_preedit_end_event_add(ctx);
-        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
-     }
-}
-
-/* FIXME */
-static int
-_ecore_imf_xim_text_to_utf8(Ecore_IMF_Context *ctx EINA_UNUSED,
-                           XIMText *xim_text,
-                           char **text)
-{
-   int text_length = 0;
-   char *result = NULL;
-
-   if (xim_text && xim_text->string.multi_byte)
-     {
-        if (xim_text->encoding_is_wchar)
-          {
-             WRN("Wide character return from Xlib not currently supported");
-             *text = NULL;
-             return 0;
-          }
-
-        /* XXX Convert to UTF-8 */
-        result = strdup(xim_text->string.multi_byte);
-        if (result)
-          {
-             text_length = eina_unicode_utf8_get_len(result);
-             if (text_length != xim_text->length)
-               {
-                  WRN("Size mismatch when converting text from input method: supplied length = %d, result length = %d",
-                      xim_text->length, text_length);
-               }
-          }
-        else
-          {
-             WRN("Error converting text from IM to UCS-4");
-             *text = NULL;
-             return 0;
-          }
-
-        *text = result;
-        return text_length;
-     }
-   else
-     {
-        *text = NULL;
-        return 0;
-     }
-}
-
-static void
-_ecore_imf_xim_preedit_draw_call(XIC xic EINA_UNUSED,
-                                XPointer client_data,
-                                XIMPreeditDrawCallbackStruct *call_data)
-{
-   Eina_Bool ret = EINA_FALSE;
-   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   XIMText *t = call_data->text;
-   char *tmp;
-   Eina_Unicode *new_text = NULL;
-   Eina_UStrbuf *preedit_bufs = NULL;
-   int new_text_length;
-   int i = 0;
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   preedit_bufs = eina_ustrbuf_new();
-   if (imf_context_data->preedit_chars)
-     {
-        ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars);
-        if (ret == EINA_FALSE) goto done;
-     }
-
-   new_text_length = _ecore_imf_xim_text_to_utf8(ctx, t, &tmp);
-   if (tmp)
-     {
-        int tmp_len;
-        new_text = eina_unicode_utf8_to_unicode(tmp, &tmp_len);
-        free(tmp);
-     }
-
-   if (t == NULL)
-     {
-        /* delete string */
-        ret = eina_ustrbuf_remove(preedit_bufs,
-                                  call_data->chg_first, call_data->chg_length);
-     }
-   else if (call_data->chg_length == 0)
-     {
-        /* insert string */
-        ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first);
-     }
-   else if (call_data->chg_length > 0)
-     {
-        /* replace string */
-        ret = eina_ustrbuf_remove(preedit_bufs,
-                                  call_data->chg_first, call_data->chg_length);
-        if (ret == EINA_FALSE) goto done;
-
-        ret = eina_ustrbuf_insert_n(preedit_bufs, new_text,
-                                    new_text_length, call_data->chg_first);
-        if (ret == EINA_FALSE) goto done;
-     }
-   else
-     {
-        ret = EINA_FALSE;
-     }
-
-done:
-   if (ret == EINA_TRUE)
-     {
-        free(imf_context_data->preedit_chars);
-        imf_context_data->preedit_chars =
-          eina_ustrbuf_string_steal(preedit_bufs);
-        imf_context_data->preedit_length =
-          eina_unicode_strlen(imf_context_data->preedit_chars);
-
-        if (imf_context_data->feedbacks)
-          {
-             free(imf_context_data->feedbacks);
-             imf_context_data->feedbacks = NULL;
-          }
-
-        if (imf_context_data->preedit_length > 0)
-          {
-             imf_context_data->feedbacks = calloc(imf_context_data->preedit_length, sizeof(XIMFeedback));
-
-             for (i = 0; i < imf_context_data->preedit_length; i++)
-               imf_context_data->feedbacks[i] = t->feedback[i];
-          }
-
-        ecore_imf_context_preedit_changed_event_add(ctx);
-        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-     }
-
-   free(new_text);
-   eina_ustrbuf_free(preedit_bufs);
-}
-
-static void
-_ecore_imf_xim_preedit_caret_call(XIC xic EINA_UNUSED,
-                                 XPointer client_data,
-                                 XIMPreeditCaretCallbackStruct *call_data)
-{
-   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   if (call_data->direction == XIMAbsolutePosition)
-     {
-        imf_context_data->preedit_cursor = call_data->position;
-        if (imf_context_data->finalizing == EINA_FALSE)
-          {
-             ecore_imf_context_preedit_changed_event_add(ctx);
-             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-          }
-     }
-}
-
-static XVaNestedList
-_ecore_imf_xim_preedit_callback_set(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data;
-   imf_context_data = ecore_imf_context_data_get(ctx);
-
-   imf_context_data->preedit_start_cb.client_data = (XPointer)ctx;
-   imf_context_data->preedit_start_cb.callback = (XIMProc)_ecore_imf_xim_preedit_start_call;
-
-   imf_context_data->preedit_done_cb.client_data = (XPointer)ctx;
-   imf_context_data->preedit_done_cb.callback = (XIMProc)_ecore_imf_xim_preedit_done_call;
-
-   imf_context_data->preedit_draw_cb.client_data = (XPointer)ctx;
-   imf_context_data->preedit_draw_cb.callback = (XIMProc)_ecore_imf_xim_preedit_draw_call;
-
-   imf_context_data->preedit_caret_cb.client_data = (XPointer)ctx;
-   imf_context_data->preedit_caret_cb.callback = (XIMProc)_ecore_imf_xim_preedit_caret_call;
-
-   return XVaCreateNestedList(0,
-                              XNPreeditStartCallback,
-                              &imf_context_data->preedit_start_cb,
-                              XNPreeditDoneCallback,
-                              &imf_context_data->preedit_done_cb,
-                              XNPreeditDrawCallback,
-                              &imf_context_data->preedit_draw_cb,
-                              XNPreeditCaretCallback,
-                              &imf_context_data->preedit_caret_cb,
-                              NULL);
-}
-
-static XIC
-_ecore_imf_xim_ic_get(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data;
-   XIC ic;
-   imf_context_data = ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL);
-
-   ic = imf_context_data->ic;
-   if (!ic)
-     {
-        XIM_Im_Info *im_info = imf_context_data->im_info;
-        XVaNestedList preedit_attr = NULL;
-        XIMStyle im_style = 0;
-        XPoint spot = { 0, 0 };
-        char *name = NULL;
-
-        if (!im_info)
-          {
-             WRN("Could not open XIM.");
-             return NULL;
-          }
-
-        // supported styles
-        // "OverTheSpot" = XIMPreeditPosition | XIMStatusNothing
-        // "OffTheSpot" = XIMPreeditArea | XIMStatusArea
-        // "Root" = XIMPreeditNothing | XIMStatusNothing
-
-        if (imf_context_data->use_preedit == EINA_TRUE)
-          {
-             if (im_info->supports_cursor)
-               {
-                  // kinput2 DOES do this...
-                  XFontSet fs;
-                  char **missing_charset_list;
-                  int missing_charset_count;
-                  char *def_string;
-
-                  im_style |= XIMPreeditPosition;
-                  im_style |= XIMStatusNothing;
-                  fs = XCreateFontSet(ecore_x_display_get(),
-                                      "fixed",
-                                      &missing_charset_list,
-                                      &missing_charset_count,
-                                      &def_string);
-                  preedit_attr = XVaCreateNestedList(0,
-                                                     XNSpotLocation, &spot,
-                                                     XNFontSet, fs,
-                                                     NULL);
-               }
-             else
-               {
-                  im_style |= XIMPreeditCallbacks;
-                  im_style |= XIMStatusNothing;
-                  preedit_attr = _ecore_imf_xim_preedit_callback_set(ctx);
-               }
-             name = XNPreeditAttributes;
-          }
-        else
-          {
-             im_style |= XIMPreeditNothing;
-             im_style |= XIMStatusNothing;
-          }
-
-        if (!im_info->xim_styles)
-          {
-             WRN("No XIM styles supported! Wanted %#llx",
-                 (unsigned long long)im_style);
-             im_style = 0;
-          }
-        else
-          {
-             XIMStyle fallback = 0;
-             int i;
-
-             for (i = 0; i < im_info->xim_styles->count_styles; i++)
-               {
-                  XIMStyle cur = im_info->xim_styles->supported_styles[i];
-                  if (cur == im_style)
-                    break;
-                  else if (cur == (XIMPreeditNothing | XIMStatusNothing))
-                    /* TODO: fallback is just that or the anyone? */
-                    fallback = cur;
-               }
-
-             if (i == im_info->xim_styles->count_styles)
-               {
-                  if (fallback)
-                    {
-                       WRN("Wanted XIM style %#llx not found, using fallback %#llx instead.",
-                           (unsigned long long)im_style,
-                           (unsigned long long)fallback);
-                       im_style = fallback;
-                    }
-                  else
-                    {
-                       WRN("Wanted XIM style %#llx not found, no fallback supported.",
-                           (unsigned long long)im_style);
-                       im_style = 0;
-                    }
-               }
-          }
-
-        if ((im_info->im) && (im_style))
-          {
-             ic = XCreateIC(im_info->im,
-                            XNInputStyle, im_style,
-                            XNClientWindow, imf_context_data->win,
-                            name, preedit_attr, NULL);
-          }
-        XFree(preedit_attr);
-        if (ic)
-          {
-             unsigned long mask = 0xaaaaaaaa;
-             XGetICValues(ic,
-                          XNFilterEvents, &mask,
-                          NULL);
-             imf_context_data->mask = mask;
-             ecore_x_event_mask_set(imf_context_data->win, mask);
-          }
-
-        imf_context_data->ic = ic;
-        if (ic && imf_context_data->has_focus == EINA_TRUE)
-          XSetICFocus(ic);
-     }
-
-   return ic;
-}
-
-static void
-_ecore_imf_xim_ic_reinitialize(Ecore_IMF_Context *ctx)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   XIC ic = imf_context_data->ic;
-   if (ic)
-     {
-        XDestroyIC(ic);
-        imf_context_data->ic = NULL;
-        if (imf_context_data->preedit_length)
-          {
-             imf_context_data->preedit_length = 0;
-             free(imf_context_data->preedit_chars);
-             imf_context_data->preedit_chars = NULL;
-             ecore_imf_context_preedit_changed_event_add(ctx);
-             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
-          }
-     }
-}
-
-static void
-_ecore_imf_xim_ic_client_window_set(Ecore_IMF_Context *ctx,
-                                    Ecore_X_Window window)
-{
-   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
-   Ecore_X_Window old_win;
-
-   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
-   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
-
-   /* reinitialize IC */
-   _ecore_imf_xim_ic_reinitialize(ctx);
-
-   old_win = imf_context_data->win;
-   DBG("old_win=%#x, window=%#x", old_win, window);
-   if (old_win != 0 && old_win != window)   /* XXX how do check window... */
-     {
-        XIM_Im_Info *info;
-        info = imf_context_data->im_info;
-        info->ics = eina_list_remove(info->ics, imf_context_data);
-        if (imf_context_data->im_info)
-          imf_context_data->im_info->user = NULL;
-        imf_context_data->im_info = NULL;
-     }
-
-   imf_context_data->win = window;
-
-   if (window) /* XXX */
-     {
-        XIM_Im_Info *info = NULL;
-        info = _ecore_imf_xim_im_get(window, imf_context_data->locale);
-        imf_context_data->im_info = info;
-        imf_context_data->im_info->ics =
-          eina_list_prepend(imf_context_data->im_info->ics,
-                            imf_context_data);
-        if (imf_context_data->im_info)
-          imf_context_data->im_info->user = imf_context_data;
-     }
-}
-
-static XIM_Im_Info *
-_ecore_imf_xim_im_get(Ecore_X_Window window,
-                     char *locale)
-{
-   Eina_List *l;
-   XIM_Im_Info *im_info = NULL;
-   XIM_Im_Info *info = NULL;
-
-   DBG(" ");
-   EINA_LIST_FOREACH (open_ims, l, im_info)
-     {
-        if (strcmp(im_info->locale, locale) == 0)
-          {
-             if (im_info->im)
-               {
-                  return im_info;
-               }
-             else
-               {
-                  info = im_info;
-                  break;
-               }
-          }
-     }
-
-   if (!info)
-     {
-        info = calloc(1, sizeof(XIM_Im_Info));
-        if (!info) return NULL;
-        open_ims = eina_list_prepend(open_ims, info);
-        info->win = window;
-        info->locale = strdup(locale);
-        info->reconnecting = EINA_FALSE;
-     }
-
-   _ecore_imf_xim_info_im_init(info);
-   return info;
-}
-
-/* initialize info->im */
-static void
-_ecore_imf_xim_info_im_init(XIM_Im_Info *info)
-{
-   Ecore_X_Display *dsp;
-
-   assert(info->im == NULL);
-   if (info->reconnecting == EINA_TRUE)
-     return;
-
-   if (XSupportsLocale())
-     {
-        if (!XSetLocaleModifiers(""))
-          WRN("Unable to set locale modifiers with XSetLocaleModifiers()");
-        dsp = ecore_x_display_get();
-        info->im = XOpenIM(dsp, NULL, NULL, NULL);
-        if (!info->im)
-          {
-             XRegisterIMInstantiateCallback(dsp,
-                                            NULL, NULL, NULL,
-                                            _ecore_imf_xim_instantiate_cb,
-                                            (XPointer)info);
-             info->reconnecting = EINA_TRUE;
-             return;
-          }
-        _ecore_imf_xim_im_setup(info);
-     }
-}
-
-static void
-_ecore_imf_xim_info_im_shutdown(Ecore_X_Display *display EINA_UNUSED,
-                               int is_error EINA_UNUSED,
-                               XIM_Im_Info *info)
-{
-   Eina_List *ics, *tmp_list;
-   Ecore_IMF_Context *ctx;
-
-   open_ims = eina_list_remove(open_ims, info);
-
-   ics = info->ics;
-   info->ics = NULL;
-
-   EINA_LIST_FOREACH (ics, tmp_list, ctx)
-     _ecore_imf_xim_ic_client_window_set(ctx, 0);
-
-   EINA_LIST_FREE (ics, ctx)
-     {
-        Ecore_IMF_Context_Data *imf_context_data;
-        imf_context_data = ecore_imf_context_data_get(ctx);
-        _ecore_imf_xim_context_data_destroy(imf_context_data);
-     }
-
-   free(info->locale);
-
-   if (info->im)
-     XCloseIM(info->im);
-
-   free(info);
-}
-
-static void
-_ecore_imf_xim_instantiate_cb(Display *display,
-                             XPointer client_data,
-                             XPointer call_data EINA_UNUSED)
-{
-   XIM_Im_Info *info = (XIM_Im_Info *)client_data;
-   XIM im = XOpenIM(display, NULL, NULL, NULL);
-   EINA_SAFETY_ON_NULL_RETURN(im);
-
-   info->im = im;
-   _ecore_imf_xim_im_setup(info);
-
-   XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL,
-                                    _ecore_imf_xim_instantiate_cb,
-                                    (XPointer)info);
-   info->reconnecting = EINA_FALSE;
-}
-
-static void
-_ecore_imf_xim_im_setup(XIM_Im_Info *info)
-{
-   XIMValuesList *ic_values = NULL;
-   XIMCallback im_destroy_callback;
-
-   if (!info->im)
-     return;
-
-   im_destroy_callback.client_data = (XPointer)info;
-   im_destroy_callback.callback = (XIMProc)_ecore_imf_xim_destroy_cb;
-   XSetIMValues(info->im,
-                XNDestroyCallback, &im_destroy_callback,
-                NULL);
-
-   XGetIMValues(info->im,
-                XNQueryInputStyle, &info->xim_styles,
-                XNQueryICValuesList, &ic_values,
-                NULL);
-
-   if (ic_values)
-     {
-        int i;
-
-        for (i = 0; i < ic_values->count_values; i++)
-          {
-             if (!strcmp(ic_values->supported_values[i],
-                         XNStringConversionCallback))
-               info->supports_string_conversion = EINA_TRUE;
-             if (!strcmp(ic_values->supported_values[i],
-                         XNCursor))
-               info->supports_cursor = EINA_TRUE;
-          }
-
-        XFree(ic_values);
-     }
-}
-
-static void
-_ecore_imf_xim_destroy_cb(XIM xim EINA_UNUSED,
-                         XPointer client_data,
-                         XPointer call_data EINA_UNUSED)
-{
-   XIM_Im_Info *info = (XIM_Im_Info *)client_data;
-
-   if (info->user) info->user->ic = NULL;
-   info->im = NULL;
-//   _ecore_imf_xim_ic_reinitialize(ctx);
-   _ecore_imf_xim_info_im_init(info);
-
-   return;
-}
diff --git a/src/modules/ecore_imf/ibus/ibus_imcontext.c b/src/modules/ecore_imf/ibus/ibus_imcontext.c
new file mode 100644 (file)
index 0000000..02f4fce
--- /dev/null
@@ -0,0 +1,822 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+
+#include <X11/Xlib.h>
+#include <Ecore_X.h>
+#include <Ecore_Evas.h>
+
+#include <ibus.h>
+#include "ibus_imcontext.h"
+
+struct _IBusIMContext
+{
+   /* instance members */
+   Ecore_IMF_Context *ctx;
+
+   /* enabled */
+   Eina_Bool        enable;
+   IBusInputContext *ibuscontext;
+
+   /* preedit status */
+   char            *preedit_string;
+   Eina_List       *preedit_attrs;
+   int              preedit_cursor_pos;
+   Eina_Bool        preedit_visible;
+
+   int              cursor_x;
+   int              cursor_y;
+   int              cursor_w;
+   int              cursor_h;
+
+   Eina_Bool        has_focus;
+
+   Ecore_X_Window   client_window;
+   Evas            *client_canvas;
+
+   int              caps;
+};
+
+typedef struct _KeyEvent KeyEvent;
+
+struct _KeyEvent
+{
+   int keysym;
+   int state;
+};
+
+static Eina_Bool _use_sync_mode = EINA_FALSE;
+
+static Ecore_IMF_Context *_focus_im_context = NULL;
+static IBusBus           *_bus = NULL;
+
+/* functions prototype */
+/* static methods*/
+static void     _create_input_context       (IBusIMContext      *context);
+static void     _set_cursor_location_internal
+(Ecore_IMF_Context  *ctx);
+static void     _bus_connected_cb           (IBusBus            *bus,
+                                             IBusIMContext      *context);
+static XKeyEvent createXKeyEvent            (Window win, Eina_Bool press, int keysym, int modifiers);
+
+static void
+_window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y)
+{
+   Ecore_X_Window root_window, win;
+   int win_x, win_y;
+   int sum_x = 0, sum_y = 0;
+
+   root_window = ecore_x_window_root_get(client_win);
+   win = client_win;
+
+   while (root_window != win)
+     {
+        ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL);
+        sum_x += win_x;
+        sum_y += win_y;
+        win = ecore_x_window_parent_get(win);
+     }
+
+   if (x)
+     *x = sum_x;
+   if (y)
+     *y = sum_y;
+}
+
+static unsigned int
+_ecore_imf_modifier_to_ibus_modifier(unsigned int modifier)
+{
+   unsigned int state = 0;
+
+   /**< "Control" is pressed */
+   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
+     state |= IBUS_CONTROL_MASK;
+
+   /**< "Alt" is pressed */
+   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
+     state |= IBUS_MOD1_MASK;
+
+   /**< "Shift" is pressed */
+   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
+     state |= IBUS_SHIFT_MASK;
+
+   /**< "Win" (between "Ctrl" and "Alt") */
+   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
+     state |= IBUS_SUPER_MASK;
+
+   /**< "AltGr" is pressed */
+   if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
+     state |= IBUS_MOD5_MASK;
+
+   return state;
+}
+
+static void
+key_event_put(int keysym, int state)
+{
+   // Find the window which has the current keyboard focus.
+   Window winFocus = 0;
+   int revert = RevertToParent;
+
+   XGetInputFocus(ecore_x_display_get(), &winFocus, &revert);
+
+   XKeyEvent event;
+   if (state & IBUS_RELEASE_MASK)
+     {
+        event = createXKeyEvent(winFocus, EINA_FALSE, keysym, state);
+        XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event);
+     }
+   else
+     {
+        event = createXKeyEvent(winFocus, EINA_TRUE, keysym, state);
+        XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
+     }
+}
+
+static KeyEvent *
+key_event_copy(int keysym, int state)
+{
+   KeyEvent *kev = calloc(1, sizeof(KeyEvent));
+   kev->keysym = keysym;
+   kev->state = state;
+
+   return kev;
+}
+
+IBusIMContext *
+ibus_im_context_new(void)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+
+   IBusIMContext *context = calloc(1, sizeof(IBusIMContext));
+
+   /* init bus object */
+   if (_bus == NULL)
+     {
+        char *display_name = NULL;
+
+        if ((display_name = getenv("DISPLAY")))
+          ibus_set_display(display_name);
+        else
+          ibus_set_display(":0.0");
+
+        _bus = ibus_bus_new();
+     }
+
+   return context;
+}
+
+static void
+_process_key_event_done(GObject      *object,
+                        GAsyncResult *res,
+                        gpointer      user_data)
+{
+    IBusInputContext *context = (IBusInputContext *)object;
+    KeyEvent *event = (KeyEvent *)user_data;
+
+    GError *error = NULL;
+    Eina_Bool retval = ibus_input_context_process_key_event_async_finish(context,
+                                                                         res,
+                                                                         &error);
+
+    if (error != NULL)
+      {
+         g_warning("Process Key Event failed: %s.", error->message);
+         g_error_free(error);
+      }
+
+    if (retval == EINA_FALSE)
+      {
+         key_event_put(event->keysym, event->state);
+      }
+    free(event);
+}
+
+EAPI void
+ibus_im_context_add(Ecore_IMF_Context *ctx)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+
+   char *s = NULL;
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   ibusimcontext->client_window = 0;
+
+   // Init ibus status
+   ibusimcontext->enable = EINA_FALSE;
+
+   // Init preedit status
+   ibusimcontext->preedit_string = NULL;
+   ibusimcontext->preedit_attrs = NULL;
+   ibusimcontext->preedit_cursor_pos = 0;
+   ibusimcontext->preedit_visible = EINA_FALSE;
+
+   // Init cursor area
+   ibusimcontext->cursor_x = -1;
+   ibusimcontext->cursor_y = -1;
+   ibusimcontext->cursor_w = 0;
+   ibusimcontext->cursor_h = 0;
+
+   ibusimcontext->ibuscontext = NULL;
+   ibusimcontext->has_focus = EINA_FALSE;
+   ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
+   ibusimcontext->ctx = ctx;
+
+   s = getenv("IBUS_ENABLE_SYNC_MODE");
+   if (s)
+     _use_sync_mode = !!atoi(s);
+
+   if (ibus_bus_is_connected(_bus))
+     _create_input_context (ibusimcontext);
+
+   g_signal_connect(_bus, "connected", G_CALLBACK (_bus_connected_cb), ctx);
+}
+
+EAPI void
+ibus_im_context_del(Ecore_IMF_Context *ctx)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   g_signal_handlers_disconnect_by_func(_bus, G_CALLBACK(_bus_connected_cb), ctx);
+
+   if (ibusimcontext->ibuscontext)
+     ibus_proxy_destroy((IBusProxy *)ibusimcontext->ibuscontext);
+
+   // release preedit
+   if (ibusimcontext->preedit_string)
+     free(ibusimcontext->preedit_string);
+   if (_focus_im_context == ctx)
+     _focus_im_context = NULL;
+}
+
+EAPI Eina_Bool
+ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
+{
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ibusimcontext, EINA_FALSE);
+
+   if (type != ECORE_IMF_EVENT_KEY_UP && type != ECORE_IMF_EVENT_KEY_DOWN)
+     return EINA_FALSE;
+
+   EINA_LOG_DBG("%s", __FUNCTION__);
+
+   if (G_LIKELY(ibusimcontext->ibuscontext && ibusimcontext->has_focus))
+     {
+        /* If context does not have focus, ibus will process key event in sync mode.
+         * It is a workaround for increase search in treeview.
+         */
+        Eina_Bool retval = EINA_FALSE;
+        int keycode;
+        int keysym;
+        unsigned int state = 0;
+
+        if (type == ECORE_IMF_EVENT_KEY_UP)
+          {
+             Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event;
+             if (ev->timestamp == 0)
+               return EINA_FALSE;
+
+             keycode = ecore_x_keysym_keycode_get(ev->key);
+             keysym = XStringToKeysym(ev->key);
+             state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | IBUS_RELEASE_MASK;
+
+             if (_use_sync_mode)
+               {
+                  retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext,
+                                                                keysym,
+                                                                keycode - 8,
+                                                                state);
+               }
+             else
+               {
+                  ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext,
+                                                             keysym,
+                                                             keycode - 8,
+                                                             state,
+                                                             -1,
+                                                             NULL,
+                                                             _process_key_event_done,
+                                                             key_event_copy(keysym, state));
+                  retval = EINA_TRUE;
+               }
+          }
+        else if (type == ECORE_IMF_EVENT_KEY_DOWN)
+          {
+             Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
+             if (ev->timestamp == 0)
+               return EINA_FALSE;
+
+             keycode = ecore_x_keysym_keycode_get(ev->key);
+             keysym = XStringToKeysym(ev->key);
+             state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers);
+             if (_use_sync_mode)
+               {
+                  retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext,
+                                                                keysym,
+                                                                keycode - 8,
+                                                                state);
+               }
+             else
+               {
+                  ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext,
+                                                             keysym,
+                                                             keycode - 8,
+                                                             state,
+                                                             -1,
+                                                             NULL,
+                                                             _process_key_event_done,
+                                                             key_event_copy(keysym, state));
+                  retval = EINA_TRUE;
+               }
+          }
+        else
+          retval = EINA_FALSE;
+
+        if (retval)
+          return EINA_TRUE;
+        else
+          return EINA_FALSE;
+     }
+   else
+     return EINA_FALSE;
+}
+
+EAPI void
+ibus_im_context_focus_in(Ecore_IMF_Context *ctx)
+{
+   EINA_LOG_DBG("ctx : %p", ctx);
+
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->has_focus)
+     return;
+
+   if (_focus_im_context != NULL)
+     ecore_imf_context_focus_out(_focus_im_context);
+
+   ibusimcontext->has_focus = EINA_TRUE;
+   if (ibusimcontext->ibuscontext)
+     ibus_input_context_focus_in(ibusimcontext->ibuscontext);
+
+   if (_focus_im_context != ctx)
+     _focus_im_context = ctx;
+}
+
+EAPI void
+ibus_im_context_focus_out(Ecore_IMF_Context *ctx)
+{
+   EINA_LOG_DBG("ctx : %p", ctx);
+
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->has_focus == EINA_FALSE)
+     return;
+
+   if (_focus_im_context == ctx)
+     _focus_im_context = NULL;
+
+   ibusimcontext->has_focus = EINA_FALSE;
+   if (ibusimcontext->ibuscontext)
+     ibus_input_context_focus_out(ibusimcontext->ibuscontext);
+}
+
+EAPI void
+ibus_im_context_reset(Ecore_IMF_Context *ctx)
+{
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->ibuscontext)
+     ibus_input_context_reset(ibusimcontext->ibuscontext);
+}
+
+EAPI void
+ibus_im_context_preedit_string_get(Ecore_IMF_Context *ctx,
+                                   char          **str,
+                                   int            *cursor_pos)
+{
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->enable && ibusimcontext->preedit_visible)
+     {
+        if (str)
+          *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: "");
+
+        if (cursor_pos)
+          *cursor_pos = ibusimcontext->preedit_cursor_pos;
+     }
+   else
+     {
+        if (str)
+          *str = strdup("");
+
+        if (cursor_pos)
+          *cursor_pos = 0;
+     }
+   EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos);
+}
+
+EAPI void
+ibus_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context   *ctx,
+                                                   char          **str,
+                                                   Eina_List     **attr EINA_UNUSED,
+                                                   int            *cursor_pos)
+{
+   IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->enable && ibusimcontext->preedit_visible)
+     {
+        if (str)
+          *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: "");
+
+        if (cursor_pos)
+          *cursor_pos = ibusimcontext->preedit_cursor_pos;
+     }
+   else
+     {
+        if (str)
+          *str = strdup("");
+
+        if (cursor_pos)
+          *cursor_pos = 0;
+     }
+   EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos);
+}
+
+EAPI void
+ibus_im_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
+{
+   EINA_LOG_DBG("canvas : %p", window);
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (window != NULL)
+     ibusimcontext->client_window = (Ecore_X_Window)(Ecore_Window)window;
+}
+
+EAPI void
+ibus_im_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
+{
+   EINA_LOG_DBG("canvas : %p", canvas);
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (canvas != NULL)
+     ibusimcontext->client_canvas = canvas;
+}
+
+static void
+_set_cursor_location_internal(Ecore_IMF_Context *ctx)
+{
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   Ecore_Evas *ee;
+   int canvas_x, canvas_y;
+
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->ibuscontext == NULL)
+     return;
+
+   if (ibusimcontext->client_canvas)
+     {
+        ee = ecore_evas_ecore_evas_get(ibusimcontext->client_canvas);
+        if (!ee) return;
+
+        ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
+     }
+   else
+     {
+        if (ibusimcontext->client_window)
+          _window_to_screen_geometry_get(ibusimcontext->client_window, &canvas_x, &canvas_y);
+        else
+          return;
+     }
+
+   ibus_input_context_set_cursor_location(ibusimcontext->ibuscontext,
+                                          ibusimcontext->cursor_x + canvas_x,
+                                          ibusimcontext->cursor_y + canvas_y,
+                                          ibusimcontext->cursor_w,
+                                          ibusimcontext->cursor_h);
+}
+
+EAPI void
+ibus_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h)
+{
+   EINA_LOG_DBG("x : %d, y : %d, w, %d, h :%d", x, y, w, h);
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->cursor_x != x ||
+       ibusimcontext->cursor_y != y ||
+       ibusimcontext->cursor_w != w ||
+       ibusimcontext->cursor_h != h)
+     {
+        ibusimcontext->cursor_x = x;
+        ibusimcontext->cursor_y = y;
+        ibusimcontext->cursor_w = w;
+        ibusimcontext->cursor_h = h;
+
+        _set_cursor_location_internal(ctx);
+     }
+}
+
+EAPI void
+ibus_im_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit)
+{
+   EINA_LOG_DBG("preedit : %d", use_preedit);
+   IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->ibuscontext)
+     {
+        if (use_preedit)
+          ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT;
+        else
+          ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT;
+
+        ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps);
+     }
+}
+
+static void
+_bus_connected_cb(IBusBus          *bus EINA_UNUSED,
+                  IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("ibus is connected");
+
+   if (ibusimcontext)
+     _create_input_context(ibusimcontext);
+}
+
+static void
+_ibus_context_commit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                             IBusText         *text,
+                             IBusIMContext    *ibusimcontext)
+{
+   if (!ibusimcontext || !text) return;
+   char *commit_str = text->text ? text->text : "";
+
+   EINA_LOG_DBG("commit string : %s", commit_str);
+
+   if (ibusimcontext->ctx)
+     {
+        ecore_imf_context_commit_event_add(ibusimcontext->ctx, text->text);
+        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit_str);
+     }
+}
+
+static XKeyEvent createXKeyEvent(Window win, Eina_Bool press, int keysym, int modifiers)
+{
+   XKeyEvent event;
+   Display *display = ecore_x_display_get();
+
+   event.display     = display;
+   event.window      = win;
+   event.root        = ecore_x_window_root_get(win);
+   event.subwindow   = None;
+   event.time        = 0;
+   event.x           = 1;
+   event.y           = 1;
+   event.x_root      = 1;
+   event.y_root      = 1;
+   event.same_screen = EINA_TRUE;
+   event.state       = modifiers;
+   event.keycode     = XKeysymToKeycode(display, keysym);
+   if (press)
+     event.type = KeyPress;
+   else
+     event.type = KeyRelease;
+   event.send_event  = EINA_FALSE;
+   event.serial = 0;
+
+   return event;
+}
+
+static void
+_ibus_context_forward_key_event_cb(IBusInputContext  *ibuscontext EINA_UNUSED,
+                                   guint              keyval,
+                                   guint              state,
+                                   IBusIMContext     *ibusimcontext EINA_UNUSED)
+{
+   EINA_LOG_DBG("keyval : %d, state : %d", keyval, state);
+
+   key_event_put(keyval, state);
+}
+
+static void
+_ibus_context_update_preedit_text_cb(IBusInputContext  *ibuscontext EINA_UNUSED,
+                                     IBusText          *text,
+                                     gint               cursor_pos,
+                                     gboolean           visible,
+                                     IBusIMContext     *ibusimcontext)
+{
+   if (!ibusimcontext || !text) return;
+
+   const char *str;
+   gboolean flag;
+
+   if (ibusimcontext->preedit_string)
+     free (ibusimcontext->preedit_string);
+
+   str = text->text;
+
+   if (str)
+     ibusimcontext->preedit_string = strdup(str);
+   else
+     ibusimcontext->preedit_string = strdup("");
+
+   ibusimcontext->preedit_cursor_pos = cursor_pos;
+
+   EINA_LOG_DBG("string : %s, cursor : %d", ibusimcontext->preedit_string, ibusimcontext->preedit_cursor_pos);
+
+   flag = ibusimcontext->preedit_visible != visible;
+   ibusimcontext->preedit_visible = visible;
+
+   if (ibusimcontext->preedit_visible)
+     {
+        if (flag)
+          {
+             ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx);
+             ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+          }
+
+        ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+     }
+   else
+     {
+        if (flag)
+          {
+             ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+             ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+          }
+
+        ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
+        ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+     }
+}
+
+static void
+_ibus_context_show_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                                   IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("preedit visible : %d", ibusimcontext->preedit_visible);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->preedit_visible == EINA_TRUE)
+     return;
+
+   ibusimcontext->preedit_visible = EINA_TRUE;
+
+   // call preedit start
+   ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+
+   // call preedit changed
+   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+}
+
+static void
+_ibus_context_hide_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                                   IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   if (ibusimcontext->preedit_visible == EINA_FALSE)
+     return;
+
+   ibusimcontext->preedit_visible = EINA_FALSE;
+
+   // call preedit changed
+   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+
+   // call preedit end
+   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+}
+
+static void
+_ibus_context_enabled_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                         IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   ibusimcontext->enable = EINA_TRUE;
+}
+
+static void
+_ibus_context_disabled_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                          IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   ibusimcontext->enable = EINA_FALSE;
+
+   /* clear preedit */
+   ibusimcontext->preedit_visible = EINA_FALSE;
+   ibusimcontext->preedit_cursor_pos = 0;
+   free (ibusimcontext->preedit_string);
+   ibusimcontext->preedit_string = NULL;
+
+   // call preedit changed
+   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+
+   // call preedit end
+   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+}
+
+static void
+_ibus_context_destroy_cb(IBusInputContext *ibuscontext EINA_UNUSED,
+                         IBusIMContext    *ibusimcontext)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   ibusimcontext->ibuscontext = NULL;
+   ibusimcontext->enable = EINA_FALSE;
+
+   /* clear preedit */
+   ibusimcontext->preedit_visible = EINA_FALSE;
+   ibusimcontext->preedit_cursor_pos = 0;
+   free (ibusimcontext->preedit_string);
+   ibusimcontext->preedit_string = NULL;
+
+   // call preedit changed
+   ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+
+   // call preedit end
+   ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx);
+   ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+}
+
+static void
+_create_input_context(IBusIMContext *ibusimcontext)
+{
+   EINA_LOG_DBG("%s", __FUNCTION__);
+   EINA_SAFETY_ON_NULL_RETURN(ibusimcontext);
+
+   ibusimcontext->ibuscontext = ibus_bus_create_input_context(_bus, "ecore");
+
+   g_return_if_fail(ibusimcontext->ibuscontext != NULL);
+
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "commit-text",
+                    G_CALLBACK (_ibus_context_commit_text_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "forward-key-event",
+                    G_CALLBACK (_ibus_context_forward_key_event_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "update-preedit-text",
+                    G_CALLBACK (_ibus_context_update_preedit_text_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "show-preedit-text",
+                    G_CALLBACK (_ibus_context_show_preedit_text_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "hide-preedit-text",
+                    G_CALLBACK (_ibus_context_hide_preedit_text_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "enabled",
+                    G_CALLBACK (_ibus_context_enabled_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext,
+                    "disabled",
+                    G_CALLBACK (_ibus_context_disabled_cb),
+                    ibusimcontext);
+   g_signal_connect(ibusimcontext->ibuscontext, "destroy",
+                    G_CALLBACK (_ibus_context_destroy_cb),
+                    ibusimcontext);
+
+   ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps);
+
+   if (ibusimcontext->has_focus)
+     ibus_input_context_focus_in(ibusimcontext->ibuscontext);
+}
diff --git a/src/modules/ecore_imf/ibus/ibus_imcontext.h b/src/modules/ecore_imf/ibus/ibus_imcontext.h
new file mode 100644 (file)
index 0000000..ce5c075
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __IBUS_IM_CONTEXT_H_
+#define __IBUS_IM_CONTEXT_H_
+
+#include <Ecore_IMF.h>
+
+typedef struct _IBusIMContext IBusIMContext;
+
+EAPI void ibus_im_context_add     (Ecore_IMF_Context *ctx);
+EAPI void ibus_im_context_del     (Ecore_IMF_Context *ctx);
+EAPI void ibus_im_context_reset   (Ecore_IMF_Context *context);
+EAPI void ibus_im_context_focus_in(Ecore_IMF_Context *context);
+EAPI void ibus_im_context_focus_out(Ecore_IMF_Context *context);
+EAPI void ibus_im_context_preedit_string_get
+                                            (Ecore_IMF_Context     *context,
+                                             char                  **str,
+                                             int                   *cursor_pos);
+EAPI void ibus_im_context_preedit_string_with_attributes_get
+                                            (Ecore_IMF_Context     *context,
+                                             char                  **str,
+                                             Eina_List             **attr,
+                                             int                   *cursor_pos);
+
+EAPI void ibus_im_context_cursor_location_set(Ecore_IMF_Context *context,
+                                              int x, int y, int w, int h);
+EAPI void ibus_im_context_use_preedit_set(Ecore_IMF_Context *context,
+                                          Eina_Bool use_preedit);
+EAPI void
+ibus_im_context_client_window_set(Ecore_IMF_Context   *context, void *window);
+EAPI void
+ibus_im_context_client_canvas_set(Ecore_IMF_Context   *context, void *canvas);
+EAPI Eina_Bool
+ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
+
+IBusIMContext
+        *ibus_im_context_new      (void);
+#endif
diff --git a/src/modules/ecore_imf/ibus/ibus_module.c b/src/modules/ecore_imf/ibus/ibus_module.c
new file mode 100644 (file)
index 0000000..8ac1bf3
--- /dev/null
@@ -0,0 +1,109 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <Ecore.h>
+#include <Ecore_IMF.h>
+
+#include <ibus.h>
+#include "ibus_imcontext.h"
+
+#define IBUS_LOCALDIR ""
+static const Ecore_IMF_Context_Info ibus_im_info = {
+    "ibus",
+    "IBus (Intelligent Input Bus)",
+    "*",
+    NULL,
+    0
+};
+
+static Ecore_IMF_Context_Class ibus_imf_class = {
+    ibus_im_context_add,                    /* add */
+    ibus_im_context_del,                    /* del */
+    ibus_im_context_client_window_set,      /* client_window_set */
+    ibus_im_context_client_canvas_set,      /* client_canvas_set */
+    NULL,                                   /* input_panel_show */
+    NULL,                                   /* input_panel_hide */
+    ibus_im_context_preedit_string_get,     /* get_preedit_string */
+    ibus_im_context_focus_in,               /* focus_in */
+    ibus_im_context_focus_out,              /* focus_out */
+    ibus_im_context_reset,                  /* reset */
+    NULL,                                   /* cursor_position_set */
+    ibus_im_context_use_preedit_set,        /* use_preedit_set */
+    NULL,                                   /* input_mode_set */
+    ibus_im_context_filter_event,           /* filter_event */
+    ibus_im_context_preedit_string_with_attributes_get,  /* preedit_string_with_attribute_get */
+    NULL,                                   /* prediction_allow_set */
+    NULL,                                   /* autocapital_type_set */
+    NULL,                                   /* control panel show */
+    NULL,                                   /* control panel hide */
+    NULL,                                   /* input_panel_layout_set */
+    NULL,                                   /* ibus_im_context_input_panel_layout_get, */
+    NULL,                                   /* ibus_im_context_input_panel_language_set, */
+    NULL,                                   /* ibus_im_context_input_panel_language_get, */
+    ibus_im_context_cursor_location_set,    /* cursor_location_set */
+    NULL,                                   /* input_panel_imdata_set */
+    NULL,                                   /* input_panel_imdata_get */
+    NULL,                                   /* input_panel_return_key_type_set */
+    NULL,                                   /* input_panel_return_key_disabled_set */
+    NULL,                                   /* input_panel_caps_lock_mode_set */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+static Ecore_IMF_Context *im_module_create (void);
+static Ecore_IMF_Context *im_module_exit (void);
+
+static Eina_Bool
+im_module_init(void)
+{
+    ecore_main_loop_glib_integrate();
+    ibus_init();
+    ecore_imf_module_register(&ibus_im_info, im_module_create, im_module_exit);
+
+    return EINA_TRUE;
+}
+
+static void im_module_shutdown(void)
+{
+}
+
+static Ecore_IMF_Context *
+im_module_exit(void)
+{
+    return NULL;
+}
+
+static Ecore_IMF_Context *
+im_module_create(void)
+{
+    Ecore_IMF_Context *ctx = NULL;
+    IBusIMContext *ctxd = NULL;
+
+    ctxd = ibus_im_context_new();
+    if (!ctxd)
+      {
+         return NULL;
+      }
+
+    ctx = ecore_imf_context_new(&ibus_imf_class);
+    if (!ctx)
+      {
+         free(ctxd);
+         return NULL;
+      }
+
+    ecore_imf_context_data_set(ctx, ctxd);
+
+    return ctx;
+}
+
+EINA_MODULE_INIT(im_module_init);
+EINA_MODULE_SHUTDOWN(im_module_shutdown);
+
diff --git a/src/modules/ecore_imf/scim/scim_imcontext.cpp b/src/modules/ecore_imf/scim/scim_imcontext.cpp
new file mode 100644 (file)
index 0000000..80fd295
--- /dev/null
@@ -0,0 +1,2899 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define Uses_SCIM_DEBUG
+#define Uses_SCIM_BACKEND
+#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_HOTKEY
+#define Uses_SCIM_PANEL_CLIENT
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <Ecore_Evas.h>
+#include <Ecore_X.h>
+#include <Ecore.h>
+#include <Evas.h>
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+
+#include <scim.h>
+#include "scim_imcontext.h"
+
+using namespace scim;
+
+struct _EcoreIMFContextISFImpl
+{
+    EcoreIMFContextISF      *parent;
+    IMEngineInstancePointer  si;
+    Ecore_X_Window           client_window;
+    Evas                    *client_canvas;
+    Ecore_IMF_Input_Mode     input_mode;
+    WideString               preedit_string;
+    AttributeList            preedit_attrlist;
+    Ecore_IMF_Autocapital_Type autocapital_type;
+    int                      preedit_caret;
+    int                      cursor_x;
+    int                      cursor_y;
+    int                      cursor_pos;
+    bool                     use_preedit;
+    bool                     is_on;
+    bool                     shared_si;
+    bool                     preedit_started;
+    bool                     preedit_updating;
+    bool                     need_commit_preedit;
+    bool                     uppercase;
+    bool                     prediction_allow;
+
+    EcoreIMFContextISFImpl  *next;
+};
+
+/* Input Context handling functions. */
+static EcoreIMFContextISFImpl *new_ic_impl              (EcoreIMFContextISF     *parent);
+static void                    delete_ic_impl           (EcoreIMFContextISFImpl *impl);
+static void                    delete_all_ic_impl       (void);
+
+static EcoreIMFContextISF     *find_ic                  (int                     id);
+
+
+/* private functions */
+static void     panel_slot_reload_config                (int                     context);
+static void     panel_slot_exit                         (int                     context);
+static void     panel_slot_update_lookup_table_page_size(int                     context,
+                                                         int                     page_size);
+static void     panel_slot_lookup_table_page_up         (int                     context);
+static void     panel_slot_lookup_table_page_down       (int                     context);
+static void     panel_slot_trigger_property             (int                     context,
+                                                         const String           &property);
+static void     panel_slot_process_helper_event         (int                     context,
+                                                         const String           &target_uuid,
+                                                         const String           &helper_uuid,
+                                                         const Transaction      &trans);
+static void     panel_slot_move_preedit_caret           (int                     context,
+                                                         int                     caret_pos);
+static void     panel_slot_select_candidate             (int                     context,
+                                                         int                     cand_index);
+static void     panel_slot_process_key_event            (int                     context,
+                                                         const KeyEvent         &key);
+static void     panel_slot_commit_string                (int                     context,
+                                                         const WideString       &wstr);
+static void     panel_slot_forward_key_event            (int                     context,
+                                                         const KeyEvent         &key);
+static void     panel_slot_request_help                 (int                     context);
+static void     panel_slot_request_factory_menu         (int                     context);
+static void     panel_slot_change_factory               (int                     context,
+                                                         const String           &uuid);
+
+static void     panel_req_focus_in                      (EcoreIMFContextISF     *ic);
+static void     panel_req_update_factory_info           (EcoreIMFContextISF     *ic);
+static void     panel_req_update_spot_location          (EcoreIMFContextISF     *ic);
+static void     panel_req_show_help                     (EcoreIMFContextISF     *ic);
+static void     panel_req_show_factory_menu             (EcoreIMFContextISF     *ic);
+
+/* Panel iochannel handler*/
+static bool     panel_initialize                        (void);
+static void     panel_finalize                          (void);
+static Eina_Bool panel_iochannel_handler                (void                   *data,
+                                                         Ecore_Fd_Handler       *fd_handler);
+
+/* utility functions */
+static bool     filter_hotkeys                          (EcoreIMFContextISF     *ic,
+                                                         const KeyEvent         &key);
+static void     turn_on_ic                              (EcoreIMFContextISF     *ic);
+static void     turn_off_ic                             (EcoreIMFContextISF     *ic);
+static void     set_ic_capabilities                     (EcoreIMFContextISF     *ic);
+
+static void     initialize                              (void);
+static void     finalize                                (void);
+
+static void     open_next_factory                       (EcoreIMFContextISF     *ic);
+static void     open_previous_factory                   (EcoreIMFContextISF     *ic);
+static void     open_specific_factory                   (EcoreIMFContextISF     *ic,
+                                                         const String           &uuid);
+static void     initialize_modifier_bits                (Display *display);
+static unsigned int scim_x11_keymask_scim_to_x11        (Display *display, uint16 scimkeymask);
+static XKeyEvent createKeyEvent                         (Display *display, Window &win,
+                                                         Window &winRoot, bool press,
+                                                         int keysym, int modifiers);
+static void     _x_send_key_event                       (const KeyEvent &key);
+
+static void     attach_instance                         (const IMEngineInstancePointer &si);
+
+/* slot functions */
+static void     slot_show_preedit_string                (IMEngineInstanceBase   *si);
+static void     slot_show_aux_string                    (IMEngineInstanceBase   *si);
+static void     slot_show_lookup_table                  (IMEngineInstanceBase   *si);
+
+static void     slot_hide_preedit_string                (IMEngineInstanceBase   *si);
+static void     slot_hide_aux_string                    (IMEngineInstanceBase   *si);
+static void     slot_hide_lookup_table                  (IMEngineInstanceBase   *si);
+
+static void     slot_update_preedit_caret               (IMEngineInstanceBase   *si,
+                                                         int                     caret);
+static void     slot_update_preedit_string              (IMEngineInstanceBase   *si,
+                                                         const WideString       &str,
+                                                         const AttributeList    &attrs);
+static void     slot_update_aux_string                  (IMEngineInstanceBase   *si,
+                                                         const WideString       &str,
+                                                         const AttributeList    &attrs);
+static void     slot_commit_string                      (IMEngineInstanceBase   *si,
+                                                         const WideString       &str);
+static void     slot_forward_key_event                  (IMEngineInstanceBase   *si,
+                                                         const KeyEvent         &key);
+static void     slot_update_lookup_table                (IMEngineInstanceBase   *si,
+                                                         const LookupTable      &table);
+
+static void     slot_register_properties                (IMEngineInstanceBase   *si,
+                                                         const PropertyList     &properties);
+static void     slot_update_property                    (IMEngineInstanceBase   *si,
+                                                         const Property         &property);
+static void     slot_beep                               (IMEngineInstanceBase   *si);
+static void     slot_start_helper                       (IMEngineInstanceBase   *si,
+                                                         const String           &helper_uuid);
+static void     slot_stop_helper                        (IMEngineInstanceBase   *si,
+                                                         const String           &helper_uuid);
+static void     slot_send_helper_event                  (IMEngineInstanceBase   *si,
+                                                         const String           &helper_uuid,
+                                                         const Transaction      &trans);
+static bool     slot_get_surrounding_text               (IMEngineInstanceBase   *si,
+                                                         WideString             &text,
+                                                         int                    &cursor,
+                                                         int                     maxlen_before,
+                                                         int                     maxlen_after);
+static bool     slot_delete_surrounding_text            (IMEngineInstanceBase   *si,
+                                                         int                     offset,
+                                                         int                     len);
+
+static void     reload_config_callback                  (const ConfigPointer    &config);
+
+static void     fallback_commit_string_cb               (IMEngineInstanceBase   *si,
+                                                         const WideString       &str);
+
+static void     caps_mode_check                         (Ecore_IMF_Context *ctx, Eina_Bool force);
+
+/* Local variables declaration */
+static String                                           _language;
+static EcoreIMFContextISFImpl                          *_used_ic_impl_list          = 0;
+static EcoreIMFContextISFImpl                          *_free_ic_impl_list          = 0;
+static EcoreIMFContextISF                              *_ic_list                    = 0;
+
+static KeyboardLayout                                   _keyboard_layout            = SCIM_KEYBOARD_Default;
+static int                                              _valid_key_mask             = SCIM_KEY_AllMasks;
+
+static FrontEndHotkeyMatcher                            _frontend_hotkey_matcher;
+static IMEngineHotkeyMatcher                            _imengine_hotkey_matcher;
+
+static IMEngineInstancePointer                          _default_instance;
+
+static ConfigModule                                    *_config_module              = 0;
+static ConfigPointer                                    _config;
+static BackEndPointer                                   _backend;
+
+static EcoreIMFContextISF                              *_focused_ic                 = 0;
+
+static bool                                             _scim_initialized           = false;
+
+static int                                              _instance_count             = 0;
+static int                                              _context_count              = 0;
+
+static IMEngineFactoryPointer                           _fallback_factory;
+static IMEngineInstancePointer                          _fallback_instance;
+static PanelClient                                      _panel_client;
+
+static Ecore_Fd_Handler                                *_panel_iochannel_read_handler = 0;
+static Ecore_Fd_Handler                                *_panel_iochannel_err_handler  = 0;
+
+static Ecore_X_Window                                  _client_window               = 0;
+
+static bool                                             _on_the_spot                = true;
+static bool                                             _shared_input_method        = false;
+
+static Eina_Bool                                        autocap_allow = EINA_FALSE;
+
+static Display *__current_display      = 0;
+static int      __current_alt_mask     = Mod1Mask;
+static int      __current_meta_mask    = 0;
+static int      __current_super_mask   = 0;
+static int      __current_hyper_mask   = 0;
+static int      __current_numlock_mask = Mod2Mask;
+
+// A hack to shutdown the immodule cleanly even if im_module_exit() is not called when exiting.
+class FinalizeHandler
+{
+public:
+   FinalizeHandler()
+     {
+        SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler()\n";
+     }
+   ~FinalizeHandler()
+     {
+        SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler()\n";
+        isf_imf_context_shutdown();
+     }
+};
+
+static FinalizeHandler                                  _finalize_handler;
+
+static unsigned int
+utf8_offset_to_index(const char *str, int offset)
+{
+   int index = 0;
+   int i;
+   for (i = 0; i < offset; i++)
+     {
+        eina_unicode_utf8_get_next(str, &index);
+     }
+
+   return index;
+}
+
+static unsigned int
+get_time(void)
+{
+   unsigned int tint;
+   struct timeval tv;
+   struct timezone tz;           /* is not used since ages */
+   gettimeofday(&tv, &tz);
+   tint = tv.tv_sec * 1000;
+   tint = tint / 1000 * 1000;
+   tint = tint + tv.tv_usec / 1000;
+   return tint;
+}
+
+/* Function Implementations */
+static EcoreIMFContextISFImpl *
+new_ic_impl(EcoreIMFContextISF *parent)
+{
+   EcoreIMFContextISFImpl *impl = NULL;
+
+   if (_free_ic_impl_list != NULL)
+     {
+        impl = _free_ic_impl_list;
+        _free_ic_impl_list = _free_ic_impl_list->next;
+     }
+   else
+     {
+        impl = new EcoreIMFContextISFImpl;
+        if (impl == NULL)
+          return NULL;
+     }
+
+   impl->uppercase = false;
+   impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
+   impl->next = _used_ic_impl_list;
+   _used_ic_impl_list = impl;
+
+   impl->parent = parent;
+
+   return impl;
+}
+
+static void
+delete_ic_impl(EcoreIMFContextISFImpl *impl)
+{
+   EcoreIMFContextISFImpl *rec = _used_ic_impl_list, *last = 0;
+
+   for (; rec != 0; last = rec, rec = rec->next)
+     {
+        if (rec == impl)
+          {
+             if (last != 0)
+               last->next = rec->next;
+             else
+               _used_ic_impl_list = rec->next;
+
+             rec->next = _free_ic_impl_list;
+             _free_ic_impl_list = rec;
+
+             rec->parent = 0;
+             rec->si.reset();
+             rec->client_window = 0;
+             rec->preedit_string = WideString();
+             rec->preedit_attrlist.clear();
+
+             return;
+          }
+     }
+}
+
+static void
+delete_all_ic_impl(void)
+{
+   EcoreIMFContextISFImpl *it = _used_ic_impl_list;
+
+   while (it != 0)
+     {
+        _used_ic_impl_list = it->next;
+        delete it;
+        it = _used_ic_impl_list;
+     }
+
+   it = _free_ic_impl_list;
+   while (it != 0)
+     {
+        _free_ic_impl_list = it->next;
+        delete it;
+        it = _free_ic_impl_list;
+     }
+}
+
+static EcoreIMFContextISF *
+find_ic(int id)
+{
+   EcoreIMFContextISFImpl *rec = _used_ic_impl_list;
+
+   while (rec != 0)
+     {
+        if (rec->parent && rec->parent->id == id)
+          return rec->parent;
+        rec = rec->next;
+     }
+
+   return 0;
+}
+
+static Eina_Bool
+analyze_surrounding_text(Ecore_IMF_Context *ctx)
+{
+   char *plain_str = NULL;
+   char *markup_str = NULL;
+   const char *puncs[] = {". ", "! ", "? "};
+   Eina_Bool ret = EINA_FALSE;
+   int cursor_pos = 0;
+   int i = 0;
+   Eina_Unicode *tail = NULL;
+   Eina_Unicode *ustr = NULL;
+   const int punc_num = sizeof(puncs) / sizeof(puncs[0]);
+   Eina_Unicode *uni_puncs[punc_num];
+   EcoreIMFContextISF *context_scim;
+
+   if (!ctx) return EINA_FALSE;
+   context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+   if (!context_scim || !context_scim->impl) return EINA_FALSE;
+
+   switch (context_scim->impl->autocapital_type)
+     {
+      case ECORE_IMF_AUTOCAPITAL_TYPE_NONE:
+         return EINA_FALSE;
+      case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER:
+         return EINA_TRUE;
+      default:
+         break;
+     }
+
+   for (i = 0; i < punc_num; i++)
+     uni_puncs[i] = eina_unicode_utf8_to_unicode(puncs[i], NULL);
+
+   ecore_imf_context_surrounding_get(ctx, &markup_str, &cursor_pos);
+   if (!markup_str) goto done;
+
+   if (cursor_pos == 0)
+     {
+        ret = EINA_TRUE;
+        goto done;
+     }
+
+   // Convert into plain string
+   plain_str = evas_textblock_text_markup_to_utf8(NULL, markup_str);
+   if (!plain_str) goto done;
+
+   // Convert string from UTF-8 to unicode
+   ustr = eina_unicode_utf8_to_unicode(plain_str, NULL);
+   if (!ustr) goto done;
+
+   if (cursor_pos >= 1)
+     {
+        if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD)
+          {
+             if (ustr[cursor_pos-1] == ' ')
+               {
+                  ret = EINA_TRUE;
+                  goto done;
+               }
+          }
+
+        // Check paragraph separator <PS> and carriage return  <br>
+        if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n'))
+          {
+             ret = EINA_TRUE;
+             goto done;
+          }
+     }
+
+   // check punctuation
+   if (cursor_pos >= 2)
+     {
+        tail = eina_unicode_strndup(ustr+cursor_pos-2, 2);
+
+        if (tail)
+          {
+             for (i = 0; i < punc_num; i++)
+               {
+                  if (!eina_unicode_strcmp(tail, uni_puncs[i]))
+                    {
+                       ret = EINA_TRUE;
+                       break;
+                    }
+               }
+             free(tail);
+             tail = NULL;
+          }
+     }
+
+done:
+   if (ustr) free(ustr);
+   if (markup_str) free(markup_str);
+   if (plain_str) free(plain_str);
+
+   for (i = 0; i < punc_num; i++)
+     if (uni_puncs[i]) free(uni_puncs[i]);
+
+   return ret;
+}
+
+static void
+caps_mode_check(Ecore_IMF_Context *ctx, Eina_Bool force)
+{
+   Eina_Bool uppercase;
+   EcoreIMFContextISF *context_scim;
+
+   if (!ctx) return;
+   context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (autocap_allow == EINA_FALSE)
+     return;
+
+   // Check autocapital type
+   if (!context_scim || !context_scim->impl)
+     return;
+
+   if (analyze_surrounding_text(ctx))
+     uppercase = EINA_TRUE;
+   else
+     uppercase = EINA_FALSE;
+
+   if (force)
+     context_scim->impl->uppercase = uppercase;
+   else
+     if (context_scim->impl->uppercase != uppercase)
+       context_scim->impl->uppercase = uppercase;
+}
+
+static void
+feed_key_event(Evas *evas, const char *str, Eina_Bool fake)
+{
+   char key_string[128] = {0};
+   unsigned int timestamp = 0;
+
+   if (!fake)
+     timestamp = get_time();
+
+   if (strncmp(str, "KeyRelease+", 11) == 0)
+     {
+        strncpy(key_string, str + 11, strlen(str)-11);
+        evas_event_feed_key_up(evas, key_string, key_string, NULL, NULL, timestamp, NULL);
+        SCIM_DEBUG_FRONTEND(1) << "    evas_event_feed_key_up()...\n";
+     }
+   else
+     {
+        strncpy(key_string, str, strlen(str));
+        evas_event_feed_key_down(evas, key_string, key_string, NULL, NULL, timestamp, NULL);
+        SCIM_DEBUG_FRONTEND(1) << "    evas_event_feed_key_down()...\n";
+     }
+}
+
+static void
+window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y)
+{
+   Ecore_X_Window root_window, win;
+   int win_x, win_y;
+   int sum_x = 0, sum_y = 0;
+
+   root_window = ecore_x_window_root_get(client_win);
+   win = client_win;
+
+   while (root_window != win)
+     {
+        ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL);
+        sum_x += win_x;
+        sum_y += win_y;
+        win = ecore_x_window_parent_get(win);
+     }
+
+   if (x)
+     *x = sum_x;
+   if (y)
+     *y = sum_y;
+}
+
+/* Public functions */
+/**
+ * isf_imf_context_new
+ *
+ * This function will be called by Ecore IMF.
+ * Create a instance of type EcoreIMFContextISF.
+ *
+ * Return value: A pointer to the newly created EcoreIMFContextISF instance
+ */
+EAPI EcoreIMFContextISF *
+isf_imf_context_new(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+   char *env;
+
+   EcoreIMFContextISF *context_scim = new EcoreIMFContextISF;
+   if (context_scim == NULL)
+     {
+        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
+        return NULL;
+     }
+
+   context_scim->id = _context_count++;
+
+   if (!_scim_initialized)
+     {
+        initialize();
+        _scim_initialized = true;
+     }
+
+   env = getenv("ECORE_IMF_AUTOCAPITAL_ALLOW");
+   if (env)
+     autocap_allow = !!atoi(env);
+
+   return context_scim;
+}
+
+/**
+ * isf_imf_context_shutdown
+ *
+ * It will be called when the scim im module is unloaded by ecore. It will do some
+ * cleanup job.
+ */
+EAPI void
+isf_imf_context_shutdown(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (_scim_initialized)
+     {
+        _scim_initialized = false;
+        finalize();
+     }
+}
+
+EAPI void
+isf_imf_context_add(Ecore_IMF_Context *ctx)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+
+   if (!context_scim) return;
+
+   context_scim->impl = NULL;
+
+   if (_backend.null())
+     return;
+
+   IMEngineInstancePointer si;
+
+   // Use the default instance if "shared input method" mode is enabled.
+   if (_shared_input_method && !_default_instance.null())
+     {
+        si = _default_instance;
+        SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n";
+     }
+
+   // Not in "shared input method" mode, or no default instance, create an instance.
+   if (si.null())
+     {
+        IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
+        if (factory.null()) return;
+        si = factory->create_instance("UTF-8", _instance_count++);
+        if (si.null()) return;
+        attach_instance(si);
+        SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n";
+     }
+
+   // If "shared input method" mode is enabled, and there is no default instance,
+   // then store this instance as default one.
+   if (_shared_input_method && _default_instance.null())
+     {
+        SCIM_DEBUG_FRONTEND(2) << "update default instance.\n";
+        _default_instance = si;
+     }
+
+   context_scim->ctx                       = ctx;
+   context_scim->impl                      = new_ic_impl(context_scim);
+   if (context_scim->impl == NULL)
+     {
+        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
+        return;
+     }
+
+   context_scim->impl->si                  = si;
+   context_scim->impl->client_window       = 0;
+   context_scim->impl->client_canvas       = NULL;
+   context_scim->impl->preedit_caret       = 0;
+   context_scim->impl->cursor_x            = 0;
+   context_scim->impl->cursor_y            = 0;
+   context_scim->impl->cursor_pos          = -1;
+   context_scim->impl->is_on               = false;
+   context_scim->impl->shared_si           = _shared_input_method;
+   context_scim->impl->use_preedit         = _on_the_spot;
+   context_scim->impl->preedit_started     = false;
+   context_scim->impl->preedit_updating    = false;
+   context_scim->impl->need_commit_preedit = false;
+
+   if (!_ic_list)
+     context_scim->next = NULL;
+   else
+     context_scim->next = _ic_list;
+   _ic_list = context_scim;
+
+   if (_shared_input_method)
+     context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
+
+   _panel_client.prepare(context_scim->id);
+   _panel_client.register_input_context(context_scim->id, si->get_factory_uuid());
+   set_ic_capabilities(context_scim);
+   _panel_client.send();
+
+   SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n";
+}
+
+EAPI void
+isf_imf_context_del(Ecore_IMF_Context *ctx)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (!_ic_list) return;
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+
+   if (context_scim)
+     {
+        if (context_scim->id != _ic_list->id)
+          {
+             EcoreIMFContextISF * pre = _ic_list;
+             EcoreIMFContextISF * cur = _ic_list->next;
+             while (cur != NULL)
+               {
+                  if (cur->id == context_scim->id)
+                    {
+                       pre->next = cur->next;
+                       break;
+                    }
+                  pre = cur;
+                  cur = cur->next;
+               }
+          }
+        else
+          _ic_list = _ic_list->next;
+     }
+
+   if (context_scim && context_scim->impl)
+     {
+        _panel_client.prepare(context_scim->id);
+
+        if (context_scim == _focused_ic)
+          context_scim->impl->si->focus_out();
+
+        // Delete the instance.
+        EcoreIMFContextISF *old_focused = _focused_ic;
+        _focused_ic = context_scim;
+        context_scim->impl->si.reset();
+        _focused_ic = old_focused;
+
+        if (context_scim == _focused_ic)
+          {
+             _panel_client.turn_off(context_scim->id);
+             _panel_client.focus_out(context_scim->id);
+          }
+
+        _panel_client.remove_input_context(context_scim->id);
+        _panel_client.send();
+
+        if (context_scim->impl->client_window)
+          isf_imf_context_client_window_set(ctx, NULL);
+
+        if (context_scim->impl)
+          {
+             delete_ic_impl(context_scim->impl);
+             context_scim->impl = 0;
+          }
+     }
+
+   if (context_scim == _focused_ic)
+     _focused_ic = 0;
+
+   if (context_scim)
+     {
+        delete context_scim;
+        context_scim = 0;
+     }
+}
+
+/**
+ * isf_imf_context_client_canvas_set
+ * @ctx: a #Ecore_IMF_Context
+ * @canvas: the client canvas
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Set the client canvas for the Input Method Context; this is the canvas
+ * in which the input appears.
+ *
+ * The canvas type can be determined by using the context canvas type.
+ * Actually only canvas with type "evas" (Evas *) is supported. This canvas
+ * may be used in order to correctly position status windows, and may also
+ * be used for purposes internal to the Input Method Context.
+ */
+EAPI void
+isf_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->client_canvas != (Evas*) canvas)
+     context_scim->impl->client_canvas = (Evas*)canvas;
+}
+
+/**
+ * isf_imf_context_client_window_set
+ * @ctx: a #Ecore_IMF_Context
+ * @window: the client window
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Set the client window for the Input Method Context; this is the Ecore_X_Window
+ * when using X11, Ecore_Win32_Window when using Win32, etc.
+ *
+ * This window is used in order to correctly position status windows,
+ * and may also be used for purposes internal to the Input Method Context.
+ */
+EAPI void
+isf_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->client_window != (Ecore_X_Window)((Ecore_Window)window))
+     {
+        context_scim->impl->client_window = (Ecore_X_Window)((Ecore_Window)window);
+
+        if ((context_scim->impl->client_window != 0) &&
+            (context_scim->impl->client_window != _client_window))
+          _client_window = context_scim->impl->client_window;
+     }
+}
+
+/**
+ * isf_imf_context_reset
+ * @ctx: a #Ecore_IMF_Context
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Notify the Input Method Context that a change such as a change in cursor
+ * position has been made. This will typically cause the Input Method Context
+ * to clear the preedit state.
+ */
+EAPI void
+isf_imf_context_reset(Ecore_IMF_Context *ctx)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim == _focused_ic)
+     {
+        WideString wstr = context_scim->impl->preedit_string;
+
+        _panel_client.prepare(context_scim->id);
+        context_scim->impl->si->reset();
+        _panel_client.send();
+
+        if (context_scim->impl->need_commit_preedit)
+          {
+             if (wstr.length())
+               {
+                  ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str());
+                  ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
+               }
+             _panel_client.prepare(context_scim->id);
+             _panel_client.send();
+          }
+     }
+}
+
+/**
+ * isf_imf_context_focus_in
+ * @ctx: a #Ecore_IMF_Context
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Notify the Input Method Context that the widget to which its correspond has gained focus.
+ */
+EAPI void
+isf_imf_context_focus_in(Ecore_IMF_Context *ctx)
+{
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (!context_scim)
+     return;
+
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n";
+
+   if (_focused_ic)
+     {
+        if (_focused_ic == context_scim)
+          {
+             SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n";
+             return;
+          }
+        SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n";
+        if (_focused_ic->ctx)
+          isf_imf_context_focus_out(_focused_ic->ctx);
+     }
+
+   bool need_cap   = false;
+   bool need_reset = false;
+   bool need_reg   = false;
+
+   if (context_scim && context_scim->impl)
+     {
+        _focused_ic = context_scim;
+        _panel_client.prepare(context_scim->id);
+
+        // Handle the "Shared Input Method" mode.
+        if (_shared_input_method)
+          {
+             SCIM_DEBUG_FRONTEND(2) << "shared input method.\n";
+             IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
+             if (!factory.null())
+               {
+                  if (_default_instance.null() || _default_instance->get_factory_uuid() != factory->get_uuid())
+                    {
+                       _default_instance = factory->create_instance("UTF-8", _default_instance.null() ? _instance_count++ : _default_instance->get_id());
+                       attach_instance(_default_instance);
+                       SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id() << " " << _default_instance->get_factory_uuid() << "\n";
+                    }
+
+                  context_scim->impl->shared_si = true;
+                  context_scim->impl->si = _default_instance;
+
+                  context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
+                  context_scim->impl->preedit_string.clear();
+                  context_scim->impl->preedit_attrlist.clear();
+                  context_scim->impl->preedit_caret = 0;
+                  context_scim->impl->preedit_started = false;
+                  need_cap = true;
+                  need_reset = true;
+                  need_reg = true;
+               }
+          }
+        else if (context_scim->impl->shared_si)
+          {
+             SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n";
+             IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8");
+             if (!factory.null())
+               {
+                  context_scim->impl->si = factory->create_instance("UTF-8", _instance_count++);
+                  context_scim->impl->preedit_string.clear();
+                  context_scim->impl->preedit_attrlist.clear();
+                  context_scim->impl->preedit_caret = 0;
+                  context_scim->impl->preedit_started = false;
+                  attach_instance(context_scim->impl->si);
+                  need_cap = true;
+                  need_reg = true;
+                  context_scim->impl->shared_si = false;
+                  SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id() << " " << context_scim->impl->si->get_factory_uuid() << "\n";
+               }
+          }
+
+        context_scim->impl->si->set_frontend_data(static_cast <void*>(context_scim));
+
+        if (need_reg) _panel_client.register_input_context(context_scim->id, context_scim->impl->si->get_factory_uuid());
+        if (need_cap) set_ic_capabilities(context_scim);
+        if (need_reset) context_scim->impl->si->reset();
+
+        panel_req_focus_in(context_scim);
+        panel_req_update_spot_location(context_scim);
+        panel_req_update_factory_info(context_scim);
+
+        if (context_scim->impl->is_on)
+          {
+             _panel_client.turn_on(context_scim->id);
+             _panel_client.hide_preedit_string(context_scim->id);
+             _panel_client.hide_aux_string(context_scim->id);
+             _panel_client.hide_lookup_table(context_scim->id);
+             context_scim->impl->si->focus_in();
+          }
+        else
+          {
+             _panel_client.turn_off(context_scim->id);
+          }
+
+        _panel_client.send();
+     }
+
+   if (ecore_imf_context_input_panel_enabled_get(ctx))
+     ecore_imf_context_input_panel_show(ctx);
+}
+
+/**
+ * isf_imf_context_focus_out
+ * @ctx: a #Ecore_IMF_Context
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Notify the Input Method Context that the widget to which its correspond has lost focus.
+ */
+EAPI void
+isf_imf_context_focus_out(Ecore_IMF_Context *ctx)
+{
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (!context_scim) return;
+
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n";
+
+   if (context_scim && context_scim->impl && context_scim == _focused_ic)
+     {
+        WideString wstr = context_scim->impl->preedit_string;
+
+        if (context_scim->impl->need_commit_preedit)
+          {
+             if (wstr.length())
+               {
+                  ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str());
+                  ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
+               }
+             _panel_client.prepare(context_scim->id);
+             _panel_client.send();
+          }
+
+        _panel_client.prepare(context_scim->id);
+        context_scim->impl->si->focus_out();
+        context_scim->impl->si->reset();
+        _panel_client.turn_off(context_scim->id);
+        _panel_client.focus_out(context_scim->id);
+        _panel_client.send();
+        _focused_ic = 0;
+     }
+
+   if (ecore_imf_context_input_panel_enabled_get(ctx))
+     ecore_imf_context_input_panel_hide(ctx);
+}
+
+/**
+ * isf_imf_context_cursor_location_set
+ * @ctx: a #Ecore_IMF_Context
+ * @x: x position of New cursor.
+ * @y: y position of New cursor.
+ * @w: the width of New cursor.
+ * @h: the height of New cursor.
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Notify the Input Method Context that a change in the cursor location has been made.
+ */
+EAPI void
+isf_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int cx, int cy, int cw, int ch)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+   Ecore_Evas *ee;
+   int canvas_x, canvas_y;
+   int new_cursor_x, new_cursor_y;
+
+   if (cw == 0 && ch == 0)
+     return;
+
+   if (context_scim && context_scim->impl && context_scim == _focused_ic)
+     {
+        if (context_scim->impl->client_canvas)
+          {
+             ee = ecore_evas_ecore_evas_get(context_scim->impl->client_canvas);
+             if (!ee) return;
+
+             ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
+          }
+        else
+          {
+             if (context_scim->impl->client_window)
+               window_to_screen_geometry_get(context_scim->impl->client_window, &canvas_x, &canvas_y);
+             else
+               return;
+          }
+
+        new_cursor_x = canvas_x + cx;
+        new_cursor_y = canvas_y + cy + ch;
+
+        // Don't update spot location while updating preedit string.
+        if (context_scim->impl->preedit_updating && (context_scim->impl->cursor_y == new_cursor_y))
+          return;
+
+        if (context_scim->impl->cursor_x != new_cursor_x || context_scim->impl->cursor_y != new_cursor_y)
+          {
+             context_scim->impl->cursor_x     = new_cursor_x;
+             context_scim->impl->cursor_y     = new_cursor_y;
+             _panel_client.prepare(context_scim->id);
+             panel_req_update_spot_location(context_scim);
+             _panel_client.send();
+             SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n";
+          }
+     }
+}
+
+/**
+ * isf_imf_context_use_preedit_set
+ * @ctx: a #Ecore_IMF_Context
+ * @use_preedit: Whether the IM context should use the preedit string.
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Set whether the IM context should use the preedit string to display feedback.
+ * If is 0 (default is 1), then the IM context may use some other method to
+ * display feedback, such as displaying it in a child of the root window.
+ */
+EAPI void
+isf_imf_context_use_preedit_set(Ecore_IMF_Context* ctx, Eina_Bool use_preedit)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (use_preedit ? "true" : "false") << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+
+   if (!_on_the_spot) return;
+
+   if (context_scim && context_scim->impl)
+     {
+        bool old = context_scim->impl->use_preedit;
+        context_scim->impl->use_preedit = use_preedit;
+        if (context_scim == _focused_ic)
+          {
+             _panel_client.prepare(context_scim->id);
+
+             if (old != use_preedit)
+               set_ic_capabilities(context_scim);
+
+             if (context_scim->impl->preedit_string.length())
+               slot_show_preedit_string(context_scim->impl->si);
+
+             _panel_client.send();
+          }
+     }
+}
+
+EAPI void
+isf_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->is_on)
+     {
+        String mbs = utf8_wcstombs(context_scim->impl->preedit_string);
+
+        if (str)
+          {
+             if (mbs.length())
+               *str = strdup(mbs.c_str());
+             else
+               *str = strdup("");
+          }
+
+        if (cursor_pos)
+          {
+             *cursor_pos = context_scim->impl->preedit_caret;
+          }
+
+        if (attrs)
+          {
+             if (mbs.length())
+               {
+                  int start_index, end_index;
+                  int wlen = context_scim->impl->preedit_string.length();
+
+                  Ecore_IMF_Preedit_Attr *attr = NULL;
+                  AttributeList::const_iterator i;
+                  bool *attrs_flag = new bool [mbs.length()];
+                  memset(attrs_flag, 0, mbs.length() *sizeof(bool));
+
+                  for (i = context_scim->impl->preedit_attrlist.begin();
+                       i != context_scim->impl->preedit_attrlist.end(); ++i)
+                    {
+                       start_index = i->get_start();
+                       end_index = i->get_end();
+
+                       if (end_index <= wlen && start_index < end_index && i->get_type() != SCIM_ATTR_DECORATE_NONE)
+                         {
+                            start_index = utf8_offset_to_index(mbs.c_str(), i->get_start());
+                            end_index = utf8_offset_to_index(mbs.c_str(), i->get_end());
+
+                            if (i->get_type() == SCIM_ATTR_DECORATE)
+                              {
+                                 attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
+                                 if (attr == NULL)
+                                   continue;
+                                 attr->start_index = start_index;
+                                 attr->end_index = end_index;
+
+                                 if (i->get_value() == SCIM_ATTR_DECORATE_UNDERLINE)
+                                   {
+                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
+                                      *attrs = eina_list_append(*attrs, (void *)attr);
+                                   }
+                                 else if (i->get_value() == SCIM_ATTR_DECORATE_REVERSE)
+                                   {
+                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
+                                      *attrs = eina_list_append(*attrs, (void *)attr);
+                                   }
+                                 else if (i->get_value() == SCIM_ATTR_DECORATE_HIGHLIGHT)
+                                   {
+                                      attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
+                                      *attrs = eina_list_append(*attrs, (void *)attr);
+                                   }
+                                 else
+                                   {
+                                      free(attr);
+                                   }
+
+                                 switch(i->get_value())
+                                   {
+                                    case SCIM_ATTR_DECORATE_UNDERLINE:
+                                    case SCIM_ATTR_DECORATE_REVERSE:
+                                    case SCIM_ATTR_DECORATE_HIGHLIGHT:
+                                       // Record which character has attribute.
+                                       for (int pos = start_index; pos < end_index; ++pos)
+                                         attrs_flag [pos] = 1;
+                                       break;
+                                    default:
+                                       break;
+                                   }
+                            }
+                            else if (i->get_type() == SCIM_ATTR_FOREGROUND)
+                              {
+                                 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n";
+                              }
+                            else if (i->get_type() == SCIM_ATTR_BACKGROUND)
+                              {
+                                 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n";
+                              }
+                         }
+                    }
+
+                  // Add underline for all characters which don't have attribute.
+                  for (unsigned int pos = 0; pos < mbs.length(); ++pos)
+                    {
+                       if (!attrs_flag [pos])
+                         {
+                            int begin_pos = pos;
+
+                            while (pos < mbs.length() && !attrs_flag[pos])
+                              ++pos;
+
+                            // use REVERSE style as default
+                            attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
+                            if (attr == NULL)
+                              continue;
+                            attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
+                            attr->start_index = begin_pos;
+                            attr->end_index = pos;
+                            *attrs = eina_list_append(*attrs, (void *)attr);
+                         }
+                    }
+
+                  delete [] attrs_flag;
+               }
+          }
+     }
+   else
+     {
+        if (str)
+          *str = strdup("");
+
+        if (cursor_pos)
+          *cursor_pos = 0;
+
+        if (attrs)
+          *attrs = NULL;
+     }
+}
+
+/**
+ * isf_imf_context_preedit_string_get
+ * @ctx: a #Ecore_IMF_Context
+ * @str: the preedit string
+ * @cursor_pos: the cursor position
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * To get the preedit string of the input method.
+ */
+EAPI void
+isf_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char** str, int *cursor_pos)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->is_on)
+     {
+        String mbs = utf8_wcstombs(context_scim->impl->preedit_string);
+
+        if (str)
+          {
+             if (mbs.length())
+               *str = strdup(mbs.c_str());
+             else
+               *str = strdup("");
+          }
+
+        if (cursor_pos)
+          *cursor_pos = context_scim->impl->preedit_caret;
+     }
+   else
+     {
+        if (str)
+          *str = strdup("");
+
+        if (cursor_pos)
+          *cursor_pos = 0;
+     }
+}
+
+/**
+ * isf_imf_context_cursor_position_set
+ * @ctx: a #Ecore_IMF_Context
+ * @cursor_pos: New cursor position in characters.
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Notify the Input Method Context that a change in the cursor position has been made.
+ */
+EAPI void
+isf_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim == _focused_ic)
+     {
+        // Don't update spot location while updating preedit string.
+        if (context_scim->impl->preedit_updating)
+          return;
+
+        if (context_scim->impl->cursor_pos != cursor_pos)
+          {
+             context_scim->impl->cursor_pos = cursor_pos;
+             caps_mode_check(ctx, EINA_FALSE);
+          }
+     }
+}
+
+/**
+ * isf_imf_context_input_mode_set
+ * @ctx: a #Ecore_IMF_Context
+ * @input_mode: the input mode
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * To set the input mode of input method. The definition of Ecore_IMF_Input_Mode
+ * is in Ecore_IMF.h.
+ */
+EAPI void
+isf_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+   if (context_scim && context_scim->impl)
+     context_scim->impl->input_mode = input_mode;
+}
+
+/**
+ * isf_imf_context_prediction_allow_set
+ * @ctx: a #Ecore_IMF_Context
+ * @use_prediction: Whether the IM context should use the prediction.
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Set whether the IM context should use the prediction.
+ */
+EAPI void
+isf_imf_context_prediction_allow_set(Ecore_IMF_Context* ctx, Eina_Bool prediction)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction ? "true" : "false") << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction)
+     context_scim->impl->prediction_allow = prediction;
+}
+
+EAPI void
+isf_imf_context_autocapital_type_set(Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << autocapital_type << "...\n";
+
+   EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx);
+
+   if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type)
+     context_scim->impl->autocapital_type = autocapital_type;
+}
+
+/**
+ * isf_imf_context_filter_event
+ * @ctx: a #Ecore_IMF_Context
+ * @type: The type of event defined by Ecore_IMF_Event_Type.
+ * @event: The event itself.
+ * Return value: %TRUE if the input method handled the key event.
+ *
+ * This function will be called by Ecore IMF.
+ *
+ * Allow an Ecore Input Context to internally handle an event. If this function
+ * returns 1, then no further processing should be done for this event. Input
+ * methods must be able to accept all types of events (simply returning 0 if
+ * the event was not handled), but there is no obligation of any events to be
+ * submitted to this function.
+ */
+EAPI Eina_Bool
+isf_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+   Eina_Bool ret = EINA_FALSE;
+
+   if (ic == NULL || ic->impl == NULL)
+     return ret;
+
+   KeyEvent key;
+
+   if (type == ECORE_IMF_EVENT_KEY_DOWN)
+     {
+        Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
+        scim_string_to_key(key, ev->key);
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask;
+        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask;
+        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask;
+     }
+   else if (type == ECORE_IMF_EVENT_KEY_UP)
+     {
+        Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event;
+        scim_string_to_key(key, ev->key);
+        key.mask = SCIM_KEY_ReleaseMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask;
+        if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask;
+        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask;
+        if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask;
+     }
+   else
+     {
+        return ret;
+     }
+
+   key.mask &= _valid_key_mask;
+
+   _panel_client.prepare(ic->id);
+
+   ret = EINA_TRUE;
+   if (!filter_hotkeys(ic, key))
+     {
+        if (!_focused_ic || !_focused_ic->impl->is_on ||
+            !_focused_ic->impl->si->process_key_event(key))
+          ret = EINA_FALSE;
+     }
+
+   _panel_client.send();
+
+   return ret;
+}
+
+EAPI void
+isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+   if (ic == NULL || ic->impl == NULL)
+     return;
+
+   ecore_x_e_virtual_keyboard_state_set
+        (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
+}
+
+EAPI void
+isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx);
+   if (ic == NULL || ic->impl == NULL)
+     return;
+
+   ecore_x_e_virtual_keyboard_state_set
+        (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
+}
+
+/* Panel Slot functions */
+static void
+panel_slot_reload_config(int context EINA_UNUSED)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+   _config->reload();
+}
+
+static void
+panel_slot_exit(int /* context */)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   finalize();
+}
+
+static void
+panel_slot_update_lookup_table_page_size(int context, int page_size)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " page_size=" << page_size << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->update_lookup_table_page_size(page_size);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_lookup_table_page_up(int context)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->lookup_table_page_up();
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_lookup_table_page_down(int context)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->lookup_table_page_down();
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_trigger_property(int context, const String &property)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " property=" << property << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->trigger_property(property);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_process_helper_event(int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid
+      << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic ? ic->impl : 0) << " ic-uuid="
+      << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid() : "" ) << "\n";
+   if (ic && ic->impl && ic->impl->si->get_factory_uuid() == target_uuid)
+     {
+        _panel_client.prepare(ic->id);
+        SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n";
+        ic->impl->si->process_helper_event(helper_uuid, trans);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_move_preedit_caret(int context, int caret_pos)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->move_preedit_caret(caret_pos);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_select_candidate(int context, int cand_index)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n";
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        ic->impl->si->select_candidate(cand_index);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_process_key_event(int context, const KeyEvent &key)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n";
+
+   if (key.is_key_press())
+     ecore_x_test_fake_key_press(key.get_key_string().c_str());
+}
+
+static void
+panel_slot_commit_string(int context, const WideString &wstr)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs(wstr) << " ic=" << ic << "\n";
+
+   if (ic && ic->impl)
+     {
+        if (_focused_ic != ic)
+          return;
+
+        ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(wstr).c_str());
+        ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str());
+     }
+}
+
+static void
+panel_slot_forward_key_event(int context, const KeyEvent &key)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n";
+
+   if (ic && ic->impl && ic->impl->client_canvas)
+     feed_key_event(ic->impl->client_canvas, key.get_key_string().c_str(), EINA_TRUE);
+}
+
+static void
+panel_slot_request_help(int context)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        panel_req_show_help(ic);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_request_factory_menu(int context)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+
+   if (ic && ic->impl)
+     {
+        _panel_client.prepare(ic->id);
+        panel_req_show_factory_menu(ic);
+        _panel_client.send();
+     }
+}
+
+static void
+panel_slot_change_factory(int context, const String &uuid)
+{
+   EcoreIMFContextISF *ic = find_ic(context);
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n";
+
+   if (ic && ic->impl)
+     {
+        ic->impl->si->reset();
+        _panel_client.prepare(ic->id);
+        open_specific_factory(ic, uuid);
+        _panel_client.send();
+     }
+}
+
+/* Panel Requestion functions. */
+static void
+panel_req_show_help(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   String help;
+
+   help =  String("Smart Common Input Method platform ") +
+      //String(SCIM_VERSION) +
+      String("\n(C) 2002-2005 James Su <suzhe@tsinghua.org.cn>\n\n");
+
+   if (ic && ic->impl)
+     {
+        IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid());
+        if (sf)
+          {
+             help += utf8_wcstombs(sf->get_name());
+             help += String(":\n\n");
+
+             help += utf8_wcstombs(sf->get_help());
+             help += String("\n\n");
+
+             help += utf8_wcstombs(sf->get_credits());
+          }
+        _panel_client.show_help(ic->id, help);
+     }
+}
+
+static void
+panel_req_show_factory_menu(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   std::vector<IMEngineFactoryPointer> factories;
+   std::vector <PanelFactoryInfo> menu;
+
+   _backend->get_factories_for_encoding(factories, "UTF-8");
+
+   for (size_t i = 0; i < factories.size(); ++ i)
+     {
+        menu.push_back(PanelFactoryInfo(
+              factories [i]->get_uuid(),
+              utf8_wcstombs(factories [i]->get_name()),
+              factories [i]->get_language(),
+              factories [i]->get_icon_file()));
+     }
+
+   if (menu.size())
+     _panel_client.show_factory_menu(ic->id, menu);
+}
+
+static void
+panel_req_update_factory_info(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (ic && ic->impl && ic == _focused_ic)
+     {
+        PanelFactoryInfo info;
+        if (ic->impl->is_on)
+          {
+             IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid());
+             if (sf)
+               info = PanelFactoryInfo(sf->get_uuid(), utf8_wcstombs(sf->get_name()), sf->get_language(), sf->get_icon_file());
+          }
+        else
+          {
+             info = PanelFactoryInfo(String(""), String("English/Keyboard"), String("C"), "");
+          }
+        _panel_client.update_factory_info(ic->id, info);
+     }
+}
+
+static void
+panel_req_focus_in(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   _panel_client.focus_in(ic->id, ic->impl->si->get_factory_uuid());
+}
+
+static void
+panel_req_update_spot_location(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   _panel_client.update_spot_location(ic->id, ic->impl->cursor_x, ic->impl->cursor_y);
+}
+
+static bool
+filter_hotkeys(EcoreIMFContextISF *ic, const KeyEvent &key)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   bool ret = false;
+
+   _frontend_hotkey_matcher.push_key_event(key);
+   _imengine_hotkey_matcher.push_key_event(key);
+
+   FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result();
+
+   if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER)
+     {
+        if (!ic->impl->is_on)
+          turn_on_ic(ic);
+        else
+          turn_off_ic(ic);
+        ret = true;
+     }
+   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON)
+     {
+        if (!ic->impl->is_on)
+          turn_on_ic(ic);
+        ret = true;
+     }
+   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF)
+     {
+        if (ic->impl->is_on)
+          turn_off_ic(ic);
+        ret = true;
+     }
+   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY)
+     {
+        open_next_factory(ic);
+        ret = true;
+     }
+   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY)
+     {
+        open_previous_factory(ic);
+        ret = true;
+     }
+   else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU)
+     {
+        panel_req_show_factory_menu(ic);
+        ret = true;
+     }
+   else if (_imengine_hotkey_matcher.is_matched())
+     {
+        String sfid = _imengine_hotkey_matcher.get_match_result();
+        open_specific_factory(ic, sfid);
+        ret = true;
+     }
+   return ret;
+}
+
+static bool
+panel_initialize(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   String display_name;
+     {
+        const char *p = getenv("DISPLAY");
+        if (p) display_name = String(p);
+     }
+
+   if (_panel_client.open_connection(_config->get_name(), display_name) >= 0)
+     {
+        int fd = _panel_client.get_connection_number();
+
+        _panel_iochannel_read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, panel_iochannel_handler, NULL, NULL, NULL);
+
+        SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n";
+
+        return true;
+   }
+   std::cerr << "panel_initialize() failed!!!\n";
+   return false;
+}
+
+static void
+panel_finalize(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   _panel_client.close_connection();
+
+   if (_panel_iochannel_read_handler)
+     {
+        ecore_main_fd_handler_del(_panel_iochannel_read_handler);
+        _panel_iochannel_read_handler = 0;
+     }
+
+   if (_panel_iochannel_err_handler)
+     {
+        ecore_main_fd_handler_del(_panel_iochannel_err_handler);
+        _panel_iochannel_err_handler = 0;
+     }
+}
+
+static Eina_Bool
+panel_iochannel_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (fd_handler == _panel_iochannel_read_handler)
+     {
+        if (!_panel_client.filter_event())
+          {
+             panel_finalize();
+             panel_initialize();
+             return ECORE_CALLBACK_CANCEL;
+          }
+     }
+   else if (fd_handler == _panel_iochannel_err_handler)
+     {
+        panel_finalize();
+        panel_initialize();
+        return ECORE_CALLBACK_CANCEL;
+     }
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+turn_on_ic(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (ic && ic->impl && !ic->impl->is_on)
+     {
+        ic->impl->is_on = true;
+
+        if (ic == _focused_ic)
+          {
+             panel_req_focus_in(ic);
+             panel_req_update_spot_location(ic);
+             panel_req_update_factory_info(ic);
+             _panel_client.turn_on(ic->id);
+             _panel_client.hide_preedit_string(ic->id);
+             _panel_client.hide_aux_string(ic->id);
+             _panel_client.hide_lookup_table(ic->id);
+             ic->impl->si->focus_in();
+          }
+
+        //Record the IC on/off status
+        if (_shared_input_method)
+          _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true);
+
+        if (ic->impl->use_preedit && ic->impl->preedit_string.length())
+          {
+             ecore_imf_context_preedit_start_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+             ecore_imf_context_preedit_changed_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+             ic->impl->preedit_started = true;
+          }
+     }
+}
+
+static void
+turn_off_ic(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (ic && ic->impl && ic->impl->is_on)
+     {
+        ic->impl->is_on = false;
+
+        if (ic == _focused_ic)
+          {
+             ic->impl->si->focus_out();
+
+             panel_req_update_factory_info(ic);
+             _panel_client.turn_off(ic->id);
+          }
+
+        //Record the IC on/off status
+        if (_shared_input_method)
+          _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false);
+
+        if (ic->impl->use_preedit && ic->impl->preedit_string.length())
+          {
+             ecore_imf_context_preedit_changed_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+             ecore_imf_context_preedit_end_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+             ic->impl->preedit_started = false;
+          }
+     }
+}
+
+static void
+set_ic_capabilities(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (ic && ic->impl)
+     {
+        unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES;
+
+        if (!_on_the_spot || !ic->impl->use_preedit)
+          cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT;
+
+        ic->impl->si->update_client_capabilities(cap);
+     }
+}
+
+static bool
+check_socket_frontend(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   SocketAddress address;
+   SocketClient client;
+
+   uint32 magic;
+
+   address.set_address(scim_get_default_socket_frontend_address());
+
+   if (!client.connect(address))
+     return false;
+
+   if (!scim_socket_open_connection(magic,
+                                    String("ConnectionTester"),
+                                    String("SocketFrontEnd"),
+                                    client,
+                                    1000))
+        return false;
+
+   return true;
+}
+
+void
+initialize(void)
+{
+   std::vector<String>     config_list;
+   std::vector<String>     engine_list;
+   std::vector<String>     load_engine_list;
+
+   std::vector<String>::iterator it;
+
+   bool                    manual = false;
+
+   bool                    socket = true;
+
+   String                  config_module_name = "simple";
+
+   printf("Initializing Ecore SCIM IMModule...\n");
+
+   SCIM_DEBUG_FRONTEND(1) << "Initializing Ecore SCIM IMModule...\n";
+
+   // Get system language.
+   _language = scim_get_locale_language(scim_get_current_locale());
+
+   if (socket)
+     {
+        // If no Socket FrontEnd is running, then launch one.
+        // And set manual to false.
+        bool check_result = check_socket_frontend();
+        if (!check_result)
+          {
+             std::cerr << "Launching a SCIM daemon with Socket FrontEnd...\n";
+             //get modules list
+             scim_get_imengine_module_list(engine_list);
+
+             for (it = engine_list.begin(); it != engine_list.end(); it++)
+               {
+                  if (*it != "socket")
+                    load_engine_list.push_back(*it);
+               }
+
+             const char *new_argv [] = { "--no-stay", 0 };
+             scim_launch(true,
+                         config_module_name,
+                         (load_engine_list.size() ? scim_combine_string_list(load_engine_list, ',') : "none"),
+                         "socket",
+                         (char **)new_argv);
+             manual = false;
+          }
+
+        // If there is one Socket FrontEnd running and it's not manual mode,
+        // then just use this Socket Frontend.
+        if (!manual)
+          {
+             for (int i = 0; i < 200; ++i)
+               {
+                  if (check_result)
+                    {
+                       config_module_name = "socket";
+                       load_engine_list.clear();
+                       load_engine_list.push_back("socket");
+                       break;
+                    }
+                  scim_usleep(50000);
+                  check_result = check_socket_frontend();
+               }
+          }
+     }
+
+   if (config_module_name != "dummy")
+     {
+        //load config module
+        SCIM_DEBUG_FRONTEND(1) << "Loading Config module: " << config_module_name << "...\n";
+        _config_module = new ConfigModule(config_module_name);
+
+        //create config instance
+        if (_config_module != NULL && _config_module->valid())
+          _config = _config_module->create_config();
+     }
+
+   if (_config.null())
+     {
+        SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n";
+
+        if (_config_module) delete _config_module;
+        _config_module = NULL;
+
+        _config = new DummyConfig();
+        config_module_name = "dummy";
+     }
+
+   reload_config_callback(_config);
+   _config->signal_connect_reload(slot(reload_config_callback));
+
+   // create backend
+   _backend = new CommonBackEnd(_config, load_engine_list.size() ? load_engine_list : engine_list);
+
+   if (_backend.null())
+     std::cerr << "Cannot create BackEnd Object!\n";
+   else
+     _fallback_factory = _backend->get_factory(SCIM_COMPOSE_KEY_FACTORY_UUID);
+
+   if (_fallback_factory.null())
+     _fallback_factory = new DummyIMEngineFactory();
+
+   _fallback_instance = _fallback_factory->create_instance(String("UTF-8"), 0);
+   _fallback_instance->signal_connect_commit_string(slot(fallback_commit_string_cb));
+
+   // Attach Panel Client signal.
+   _panel_client.signal_connect_reload_config                (slot(panel_slot_reload_config));
+   _panel_client.signal_connect_exit                         (slot(panel_slot_exit));
+   _panel_client.signal_connect_update_lookup_table_page_size(slot(panel_slot_update_lookup_table_page_size));
+   _panel_client.signal_connect_lookup_table_page_up         (slot(panel_slot_lookup_table_page_up));
+   _panel_client.signal_connect_lookup_table_page_down       (slot(panel_slot_lookup_table_page_down));
+   _panel_client.signal_connect_trigger_property             (slot(panel_slot_trigger_property));
+   _panel_client.signal_connect_process_helper_event         (slot(panel_slot_process_helper_event));
+   _panel_client.signal_connect_move_preedit_caret           (slot(panel_slot_move_preedit_caret));
+   _panel_client.signal_connect_select_candidate             (slot(panel_slot_select_candidate));
+   _panel_client.signal_connect_process_key_event            (slot(panel_slot_process_key_event));
+   _panel_client.signal_connect_commit_string                (slot(panel_slot_commit_string));
+   _panel_client.signal_connect_forward_key_event            (slot(panel_slot_forward_key_event));
+   _panel_client.signal_connect_request_help                 (slot(panel_slot_request_help));
+   _panel_client.signal_connect_request_factory_menu         (slot(panel_slot_request_factory_menu));
+   _panel_client.signal_connect_change_factory               (slot(panel_slot_change_factory));
+
+   if (!panel_initialize())
+     std::cerr << "Ecore IM Module: Cannot connect to Panel!\n";
+}
+
+static void
+finalize(void)
+{
+   SCIM_DEBUG_FRONTEND(1) << "Finalizing Ecore ISF IMModule...\n";
+
+   // Reset this first so that the shared instance could be released correctly afterwards.
+   _default_instance.reset();
+
+   SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n";
+   while (_used_ic_impl_list)
+     {
+        // In case in "shared input method" mode,
+        // all contexts share only one instance,
+        // so we need point the reference pointer correctly before finalizing.
+        _used_ic_impl_list->si->set_frontend_data(static_cast <void*>(_used_ic_impl_list->parent));
+        isf_imf_context_del(_used_ic_impl_list->parent->ctx);
+     }
+
+   delete_all_ic_impl();
+
+   _fallback_instance.reset();
+   _fallback_factory.reset();
+
+   SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n";
+   _backend.reset();
+
+   SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n";
+   _config.reset();
+
+   if (_config_module)
+     {
+        SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n";
+        delete _config_module;
+        _config_module = 0;
+     }
+
+   _focused_ic = NULL;
+   _ic_list = NULL;
+
+   _scim_initialized = false;
+
+   panel_finalize();
+}
+
+static void
+open_next_factory(EcoreIMFContextISF *ic)
+{
+   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
+   IMEngineFactoryPointer sf = _backend->get_next_factory("", "UTF-8", ic->impl->si->get_factory_uuid());
+
+   if (!sf.null())
+     {
+        turn_off_ic(ic);
+        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
+        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
+        ic->impl->preedit_string = WideString();
+        ic->impl->preedit_caret = 0;
+        attach_instance(ic->impl->si);
+        _backend->set_default_factory(_language, sf->get_uuid());
+        _panel_client.register_input_context(ic->id, sf->get_uuid());
+        set_ic_capabilities(ic);
+        turn_on_ic(ic);
+
+        if (_shared_input_method)
+          {
+             _default_instance = ic->impl->si;
+             ic->impl->shared_si = true;
+          }
+     }
+}
+
+static void
+open_previous_factory(EcoreIMFContextISF *ic)
+{
+   if (ic == NULL)
+     return;
+
+   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
+   IMEngineFactoryPointer sf = _backend->get_previous_factory("", "UTF-8", ic->impl->si->get_factory_uuid());
+
+   if (!sf.null())
+     {
+        turn_off_ic(ic);
+        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
+        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
+        ic->impl->preedit_string = WideString();
+        ic->impl->preedit_caret = 0;
+        attach_instance(ic->impl->si);
+        _backend->set_default_factory(_language, sf->get_uuid());
+        _panel_client.register_input_context(ic->id, sf->get_uuid());
+        set_ic_capabilities(ic);
+        turn_on_ic(ic);
+
+        if (_shared_input_method)
+          {
+             _default_instance = ic->impl->si;
+             ic->impl->shared_si = true;
+          }
+     }
+}
+
+static void
+open_specific_factory(EcoreIMFContextISF *ic,
+                       const String     &uuid)
+{
+   if (ic == NULL)
+     return;
+
+   SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n";
+
+   // The same input method is selected, just turn on the IC.
+   if (ic->impl->si->get_factory_uuid() == uuid)
+     {
+        turn_on_ic(ic);
+        return;
+     }
+
+   IMEngineFactoryPointer sf = _backend->get_factory(uuid);
+
+   if (uuid.length() && !sf.null())
+     {
+        turn_off_ic(ic);
+        ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id());
+        ic->impl->si->set_frontend_data(static_cast <void*>(ic));
+        ic->impl->preedit_string = WideString();
+        ic->impl->preedit_caret = 0;
+        attach_instance(ic->impl->si);
+        _backend->set_default_factory(_language, sf->get_uuid());
+        _panel_client.register_input_context(ic->id, sf->get_uuid());
+        set_ic_capabilities(ic);
+        turn_on_ic(ic);
+
+        if (_shared_input_method)
+          {
+             _default_instance = ic->impl->si;
+             ic->impl->shared_si = true;
+          }
+     }
+   else
+     {
+        // turn_off_ic comment out panel_req_update_factory_info()
+        turn_off_ic(ic);
+        if (ic && ic->impl->is_on)
+          {
+             ic->impl->is_on = false;
+
+             if (ic == _focused_ic)
+               {
+                  ic->impl->si->focus_out();
+
+                  panel_req_update_factory_info(ic);
+                  _panel_client.turn_off(ic->id);
+               }
+
+             //Record the IC on/off status
+             if (_shared_input_method)
+               _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false);
+
+             if (ic->impl->use_preedit && ic->impl->preedit_string.length())
+               {
+                  ecore_imf_context_preedit_changed_event_add(ic->ctx);
+                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+                  ecore_imf_context_preedit_end_event_add(ic->ctx);
+                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+                  ic->impl->preedit_started = false;
+               }
+          }
+     }
+}
+
+static void initialize_modifier_bits(Display *display)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (__current_display == display)
+     return;
+
+   __current_display = display;
+
+   if (display == 0)
+     {
+        __current_alt_mask     = Mod1Mask;
+        __current_meta_mask    = ShiftMask | Mod1Mask;
+        __current_super_mask   = 0;
+        __current_hyper_mask   = 0;
+        __current_numlock_mask = Mod2Mask;
+        return;
+     }
+
+   XModifierKeymap *mods = NULL;
+
+   ::KeyCode ctrl_l  = XKeysymToKeycode(display, XK_Control_L);
+   ::KeyCode ctrl_r  = XKeysymToKeycode(display, XK_Control_R);
+   ::KeyCode meta_l  = XKeysymToKeycode(display, XK_Meta_L);
+   ::KeyCode meta_r  = XKeysymToKeycode(display, XK_Meta_R);
+   ::KeyCode alt_l   = XKeysymToKeycode(display, XK_Alt_L);
+   ::KeyCode alt_r   = XKeysymToKeycode(display, XK_Alt_R);
+   ::KeyCode super_l = XKeysymToKeycode(display, XK_Super_L);
+   ::KeyCode super_r = XKeysymToKeycode(display, XK_Super_R);
+   ::KeyCode hyper_l = XKeysymToKeycode(display, XK_Hyper_L);
+   ::KeyCode hyper_r = XKeysymToKeycode(display, XK_Hyper_R);
+   ::KeyCode numlock = XKeysymToKeycode(display, XK_Num_Lock);
+
+   int i, j;
+
+   mods = XGetModifierMapping(display);
+   if (mods == NULL)
+     return;
+
+   __current_alt_mask     = 0;
+   __current_meta_mask    = 0;
+   __current_super_mask   = 0;
+   __current_hyper_mask   = 0;
+   __current_numlock_mask = 0;
+
+   /* We skip the first three sets for Shift, Lock, and Control.  The
+      remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5.  */
+   for (i = 3; i < 8; i++)
+     {
+        for (j = 0; j < mods->max_keypermod; j++)
+          {
+             ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j];
+             if (! code) continue;
+             if (code == alt_l || code == alt_r)
+               __current_alt_mask |= (1 << i);
+             else if (code == meta_l || code == meta_r)
+               __current_meta_mask |= (1 << i);
+             else if (code == super_l || code == super_r)
+               __current_super_mask |= (1 << i);
+             else if (code == hyper_l || code == hyper_r)
+               __current_hyper_mask |= (1 << i);
+             else if (code == numlock)
+               __current_numlock_mask |= (1 << i);
+          }
+     }
+
+   /* Check whether there is a combine keys mapped to Meta */
+   if (__current_meta_mask == 0)
+     {
+        char buf [32];
+        XKeyEvent xkey;
+        KeySym keysym_l, keysym_r;
+
+        xkey.type = KeyPress;
+        xkey.display = display;
+        xkey.serial = 0L;
+        xkey.send_event = False;
+        xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0;
+        xkey.time = 0;
+        xkey.same_screen = False;
+        xkey.subwindow = None;
+        xkey.window = None;
+        xkey.root = DefaultRootWindow(display);
+        xkey.state = ShiftMask;
+
+        xkey.keycode = meta_l;
+        XLookupString(&xkey, buf, 32, &keysym_l, 0);
+        xkey.keycode = meta_r;
+        XLookupString(&xkey, buf, 32, &keysym_r, 0);
+
+        if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R))
+          __current_meta_mask = ShiftMask + __current_alt_mask;
+        else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R))
+          __current_meta_mask = ShiftMask + ControlMask;
+     }
+
+   XFreeModifiermap(mods);
+}
+
+static unsigned int scim_x11_keymask_scim_to_x11(Display *display, uint16 scimkeymask)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   unsigned int state = 0;
+
+   initialize_modifier_bits(display);
+
+   if (scimkeymask & SCIM_KEY_ShiftMask)    state |= ShiftMask;
+   if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask;
+   if (scimkeymask & SCIM_KEY_ControlMask)  state |= ControlMask;
+   if (scimkeymask & SCIM_KEY_AltMask)      state |= __current_alt_mask;
+   if (scimkeymask & SCIM_KEY_MetaMask)     state |= __current_meta_mask;
+   if (scimkeymask & SCIM_KEY_SuperMask)    state |= __current_super_mask;
+   if (scimkeymask & SCIM_KEY_HyperMask)    state |= __current_hyper_mask;
+   if (scimkeymask & SCIM_KEY_NumLockMask)  state |= __current_numlock_mask;
+
+   return state;
+}
+
+static XKeyEvent createKeyEvent(Display *display, Window &win,
+                                Window &winRoot, bool press,
+                                int keysym, int modifiers)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   XKeyEvent event;
+
+   event.display     = display;
+   event.window      = win;
+   event.root        = winRoot;
+   event.subwindow   = None;
+   event.time        = CurrentTime;
+   event.x           = 1;
+   event.y           = 1;
+   event.x_root      = 1;
+   event.y_root      = 1;
+   event.same_screen = EINA_TRUE;
+   event.state       = modifiers;
+   event.keycode     = XKeysymToKeycode(display, keysym);
+   if (press)
+     event.type = KeyPress;
+   else
+     event.type = KeyRelease;
+   event.send_event  = EINA_FALSE;
+   event.serial = 0;
+
+   return event;
+}
+
+static void _x_send_key_event(const KeyEvent &key)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   // Obtain the X11 display.
+   Display *display = (Display *)ecore_x_display_get();
+   if (display == NULL)
+     {
+        std::cerr << "ecore_x_display_get() failed\n";
+        return;
+     }
+
+   // Get the root window for the current display.
+   Window winRoot = 0;
+
+   // Find the window which has the current keyboard focus.
+   Window winFocus = 0;
+   int revert = RevertToParent;
+
+   XGetInputFocus(display, &winFocus, &revert);
+
+   unsigned int modifier = scim_x11_keymask_scim_to_x11(display, key.mask);
+   XKeyEvent event;
+   if (key.is_key_press())
+     {
+        event = createKeyEvent(display, winFocus, winRoot, true, key.code, modifier);
+        XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
+     }
+   else
+     {
+        event = createKeyEvent(display, winFocus, winRoot, false, key.code, modifier);
+        XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event);
+     }
+}
+
+static void
+attach_instance(const IMEngineInstancePointer &si)
+{
+   si->signal_connect_show_preedit_string(
+      slot(slot_show_preedit_string));
+   si->signal_connect_show_aux_string(
+      slot(slot_show_aux_string));
+   si->signal_connect_show_lookup_table(
+      slot(slot_show_lookup_table));
+
+   si->signal_connect_hide_preedit_string(
+      slot(slot_hide_preedit_string));
+   si->signal_connect_hide_aux_string(
+      slot(slot_hide_aux_string));
+   si->signal_connect_hide_lookup_table(
+      slot(slot_hide_lookup_table));
+
+   si->signal_connect_update_preedit_caret(
+      slot(slot_update_preedit_caret));
+   si->signal_connect_update_preedit_string(
+      slot(slot_update_preedit_string));
+   si->signal_connect_update_aux_string(
+      slot(slot_update_aux_string));
+   si->signal_connect_update_lookup_table(
+      slot(slot_update_lookup_table));
+
+   si->signal_connect_commit_string(
+      slot(slot_commit_string));
+
+   si->signal_connect_forward_key_event(
+      slot(slot_forward_key_event));
+
+   si->signal_connect_register_properties(
+      slot(slot_register_properties));
+
+   si->signal_connect_update_property(
+      slot(slot_update_property));
+
+   si->signal_connect_beep(
+      slot(slot_beep));
+
+   si->signal_connect_start_helper(
+      slot(slot_start_helper));
+
+   si->signal_connect_stop_helper(
+      slot(slot_stop_helper));
+
+   si->signal_connect_send_helper_event(
+      slot(slot_send_helper_event));
+
+   si->signal_connect_get_surrounding_text(
+      slot(slot_get_surrounding_text));
+
+   si->signal_connect_delete_surrounding_text(
+      slot(slot_delete_surrounding_text));
+}
+
+// Implementation of slot functions
+static void
+slot_show_preedit_string(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     {
+        if (ic->impl->use_preedit)
+          {
+             if (!ic->impl->preedit_started)
+               {
+                  ecore_imf_context_preedit_start_event_add(_focused_ic->ctx);
+                  ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+                  ic->impl->preedit_started = true;
+               }
+          }
+        else
+          _panel_client.show_preedit_string(ic->id);
+     }
+}
+
+static void
+slot_show_aux_string(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.show_aux_string(ic->id);
+}
+
+static void
+slot_show_lookup_table(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.show_lookup_table(ic->id);
+}
+
+static void
+slot_hide_preedit_string(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     {
+        bool emit = false;
+        if (ic->impl->preedit_string.length())
+          {
+             ic->impl->preedit_string = WideString();
+             ic->impl->preedit_caret = 0;
+             ic->impl->preedit_attrlist.clear();
+             emit = true;
+          }
+        if (ic->impl->use_preedit)
+          {
+             if (emit)
+               {
+                  ecore_imf_context_preedit_changed_event_add(ic->ctx);
+                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+               }
+             if (ic->impl->preedit_started)
+               {
+                  ecore_imf_context_preedit_end_event_add(ic->ctx);
+                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+                  ic->impl->preedit_started = false;
+               }
+          }
+        else
+          _panel_client.hide_preedit_string(ic->id);
+     }
+}
+
+static void
+slot_hide_aux_string(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.hide_aux_string(ic->id);
+}
+
+static void
+slot_hide_lookup_table(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.hide_lookup_table(ic->id);
+}
+
+static void
+slot_update_preedit_caret(IMEngineInstanceBase *si, int caret)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret)
+     {
+        ic->impl->preedit_caret = caret;
+        if (ic->impl->use_preedit)
+          {
+             if (!ic->impl->preedit_started)
+               {
+                  ecore_imf_context_preedit_start_event_add(ic->ctx);
+                  ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+                  ic->impl->preedit_started = true;
+               }
+             ecore_imf_context_preedit_changed_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+          }
+        else
+          _panel_client.update_preedit_caret(ic->id, caret);
+     }
+}
+
+static void
+slot_update_preedit_string(IMEngineInstanceBase *si,
+                            const WideString & str,
+                            const AttributeList & attrs)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length()))
+     {
+        ic->impl->preedit_string   = str;
+        ic->impl->preedit_attrlist = attrs;
+        if (ic->impl->use_preedit)
+          {
+             if (!ic->impl->preedit_started)
+               {
+                  ecore_imf_context_preedit_start_event_add(_focused_ic->ctx);
+                  ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+                  ic->impl->preedit_started = true;
+               }
+             ic->impl->preedit_caret    = str.length();
+             ic->impl->preedit_updating = true;
+             ecore_imf_context_preedit_changed_event_add(ic->ctx);
+             ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+             ic->impl->preedit_updating = false;
+          }
+        else
+          {
+             _panel_client.update_preedit_string(ic->id, str, attrs);
+          }
+     }
+}
+
+static void
+slot_update_aux_string(IMEngineInstanceBase *si,
+                        const WideString & str,
+                        const AttributeList & attrs)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.update_aux_string(ic->id, str, attrs);
+}
+
+static void
+slot_commit_string(IMEngineInstanceBase *si,
+                    const WideString & str)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->ctx)
+     {
+        ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(str).c_str());
+        ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str());
+     }
+}
+
+static void
+slot_forward_key_event(IMEngineInstanceBase *si,
+                        const KeyEvent & key)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && _focused_ic == ic)
+     {
+        if (!_fallback_instance->process_key_event(key))
+          _x_send_key_event(key);
+     }
+}
+
+static void
+slot_update_lookup_table(IMEngineInstanceBase *si,
+                          const LookupTable & table)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.update_lookup_table(ic->id, table);
+}
+
+static void
+slot_register_properties(IMEngineInstanceBase *si,
+                         const PropertyList & properties)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.register_properties(ic->id, properties);
+}
+
+static void
+slot_update_property(IMEngineInstanceBase *si,
+                     const Property & property)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     _panel_client.update_property(ic->id, property);
+}
+
+static void
+slot_beep(IMEngineInstanceBase *si)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     ecore_x_bell(0);
+}
+
+static void
+slot_start_helper(IMEngineInstanceBase *si,
+                  const String &helper_uuid)
+{
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
+      << (ic ? ic->id : -1) << " ic=" << ic
+      << " ic-uuid=" << ((ic ) ? ic->impl->si->get_factory_uuid() : "") << "...\n";
+
+   if (ic && ic->impl)
+     _panel_client.start_helper(ic->id, helper_uuid);
+}
+
+static void
+slot_stop_helper(IMEngineInstanceBase *si,
+                 const String &helper_uuid)
+{
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic ? ic->id : -1) << " ic=" << ic << "...\n";
+
+   if (ic && ic->impl)
+     _panel_client.stop_helper(ic->id, helper_uuid);
+}
+
+static void
+slot_send_helper_event(IMEngineInstanceBase *si,
+                       const String      &helper_uuid,
+                       const Transaction &trans)
+{
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
+      << (ic ? ic->id : -1) << " ic=" << ic
+      << " ic-uuid=" << ((ic) ? ic->impl->si->get_factory_uuid() : "") << "...\n";
+
+   if (ic && ic->impl)
+     _panel_client.send_helper_event(ic->id, helper_uuid, trans);
+}
+
+static bool
+slot_get_surrounding_text(IMEngineInstanceBase *si,
+                          WideString            &text,
+                          int                   &cursor,
+                          int                    maxlen_before,
+                          int                    maxlen_after)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     {
+        char *surrounding = NULL;
+        int   cursor_index;
+        if (ecore_imf_context_surrounding_get(_focused_ic->ctx, &surrounding, &cursor_index))
+          {
+             SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n";
+             SCIM_DEBUG_FRONTEND(2) << "Cursor Index    : " << cursor_index <<"\n";
+             WideString before(utf8_mbstowcs(String(surrounding, surrounding + cursor_index)));
+             WideString after(utf8_mbstowcs(String(surrounding + cursor_index)));
+             if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length())
+               before = WideString(before.begin() + (before.length() - maxlen_before), before.end());
+             else if (maxlen_before == 0) before = WideString();
+             if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length())
+               after = WideString(after.begin(), after.begin() + maxlen_after);
+             else if (maxlen_after == 0) after = WideString();
+             text = before + after;
+             cursor = before.length();
+             return true;
+          }
+     }
+   return false;
+}
+
+static bool
+slot_delete_surrounding_text(IMEngineInstanceBase *si,
+                             int                   offset,
+                             int                   len)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   EcoreIMFContextISF *ic = static_cast<EcoreIMFContextISF *>(si->get_frontend_data());
+
+   if (ic && ic->impl && _focused_ic == ic)
+     {
+        Ecore_IMF_Event_Delete_Surrounding ev;
+        ev.ctx = _focused_ic->ctx;
+        ev.n_chars = len;
+        ev.offset = offset;
+        ecore_imf_context_delete_surrounding_event_add(_focused_ic->ctx, offset, len);
+        ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
+        return true;
+     }
+   return false;
+}
+
+static void
+reload_config_callback(const ConfigPointer &config)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   _frontend_hotkey_matcher.load_hotkeys(config);
+   _imengine_hotkey_matcher.load_hotkeys(config);
+
+   KeyEvent key;
+
+   scim_string_to_key(key,
+                      config->read(String(SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK),
+                                     String("Shift+Control+Alt+Lock")));
+
+   _valid_key_mask = (key.mask > 0)?(key.mask):0xFFFF;
+   _valid_key_mask |= SCIM_KEY_ReleaseMask;
+   // Special treatment for two backslash keys on jp106 keyboard.
+   _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask;
+
+   _on_the_spot = config->read(String(SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot);
+   _shared_input_method = config->read(String(SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method);
+
+   // Get keyboard layout setting
+   // Flush the global config first, in order to load the new configs from disk.
+   scim_global_config_flush();
+
+   _keyboard_layout = scim_get_default_keyboard_layout();
+}
+
+static void
+fallback_commit_string_cb(IMEngineInstanceBase  *si EINA_UNUSED,
+                          const WideString      &str)
+{
+   SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+   if (_focused_ic && _focused_ic->impl)
+     {
+        ecore_imf_context_commit_event_add(_focused_ic->ctx, utf8_wcstombs(str).c_str());
+        ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str());
+     }
+}
+
diff --git a/src/modules/ecore_imf/scim/scim_imcontext.h b/src/modules/ecore_imf/scim/scim_imcontext.h
new file mode 100644 (file)
index 0000000..72533e2
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __ISF_IMF_CONTEXT_H
+#define __ISF_IMF_CONTEXT_H
+
+#include <Ecore_IMF.h>
+
+typedef struct _EcoreIMFContextISF      EcoreIMFContextISF;
+typedef struct _EcoreIMFContextISFImpl  EcoreIMFContextISFImpl;
+
+struct _EcoreIMFContextISF {
+    Ecore_IMF_Context *ctx;
+
+    EcoreIMFContextISFImpl *impl;
+
+    int id; /* Input Context id*/
+    struct _EcoreIMFContextISF *next;
+};
+
+void isf_imf_context_add (Ecore_IMF_Context *ctx);
+void isf_imf_context_del (Ecore_IMF_Context *ctx);
+void isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window);
+void isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *window);
+void isf_imf_context_focus_in (Ecore_IMF_Context *ctx);
+void isf_imf_context_focus_out (Ecore_IMF_Context *ctx);
+void isf_imf_context_reset (Ecore_IMF_Context *ctx);
+void isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos);
+void isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int x, int y, int w, int h);
+void isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode);
+void isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos);
+void isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos);
+void isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit);
+Eina_Bool  isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
+void isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction);
+void isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type);
+void isf_imf_context_input_panel_layout_set (Ecore_IMF_Context* ctx, Ecore_IMF_Input_Panel_Layout layout);
+void isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx);
+void isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx);
+
+EcoreIMFContextISF* isf_imf_context_new      (void);
+void                isf_imf_context_shutdown (void);
+
+#endif  /* __ISF_IMF_CONTEXT_H */
+
diff --git a/src/modules/ecore_imf/scim/scim_module.cpp b/src/modules/ecore_imf/scim/scim_module.cpp
new file mode 100644 (file)
index 0000000..d77fb11
--- /dev/null
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include "scim_imcontext.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+   static const Ecore_IMF_Context_Info isf_imf_info = {
+        "scim",                                 /* ID */
+        "SCIM immodule for Ecore",              /* Description */
+        "*",                                    /* Default locales */
+        NULL,                                   /* Canvas type */
+        0                                       /* Canvas required */
+   };
+
+   static Ecore_IMF_Context_Class isf_imf_class = {
+        isf_imf_context_add,                    /* add */
+        isf_imf_context_del,                    /* del */
+        isf_imf_context_client_window_set,      /* client_window_set */
+        isf_imf_context_client_canvas_set,      /* client_canvas_set */
+        isf_imf_context_input_panel_show,       /* input_panel_show, - show */
+        isf_imf_context_input_panel_hide,       /* input_panel_hide, - hide */
+        isf_imf_context_preedit_string_get,     /* get_preedit_string */
+        isf_imf_context_focus_in,               /* focus_in */
+        isf_imf_context_focus_out,              /* focus_out */
+        isf_imf_context_reset,                  /* reset */
+        isf_imf_context_cursor_position_set,    /* cursor_position_set */
+        isf_imf_context_use_preedit_set,        /* use_preedit_set */
+        isf_imf_context_input_mode_set,         /* input_mode_set */
+        isf_imf_context_filter_event,           /* filter_event */
+        isf_imf_context_preedit_string_with_attributes_get,  /* preedit_string_with_attribute_get */
+        isf_imf_context_prediction_allow_set,   /* prediction_allow_set */
+        isf_imf_context_autocapital_type_set,   /* autocapital_type_set */
+        NULL,                                   /* control panel show */
+        NULL,                                   /* control panel hide */
+        NULL,                                   /* input_panel_layout_set */
+        NULL,                                   /* isf_imf_context_input_panel_layout_get, */
+        NULL,                                   /* isf_imf_context_input_panel_language_set, */
+        NULL,                                   /* isf_imf_context_input_panel_language_get, */
+        isf_imf_context_cursor_location_set,    /* cursor_location_set */
+        NULL,                                   /* input_panel_imdata_set */
+        NULL,                                   /* input_panel_imdata_get */
+        NULL,                                   /* input_panel_return_key_type_set */
+        NULL,                                   /* input_panel_return_key_disabled_set */
+        NULL,                                   /* input_panel_caps_lock_mode_set */
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+   };
+
+   static Ecore_IMF_Context *imf_module_create (void);
+   static Ecore_IMF_Context *imf_module_exit (void);
+
+   static Eina_Bool imf_module_init (void)
+     {
+        ecore_imf_module_register (&isf_imf_info, imf_module_create, imf_module_exit);
+        return EINA_TRUE;
+     }
+
+   static void imf_module_shutdown (void)
+     {
+        isf_imf_context_shutdown ();
+     }
+
+   static Ecore_IMF_Context *imf_module_create (void)
+     {
+        Ecore_IMF_Context  *ctx = NULL;
+        EcoreIMFContextISF *ctxd = NULL;
+
+        ctxd = isf_imf_context_new ();
+        if (!ctxd)
+          {
+             printf ("isf_imf_context_new () failed!!!\n");
+             return NULL;
+          }
+
+        ctx = ecore_imf_context_new (&isf_imf_class);
+        if (!ctx)
+          {
+             delete ctxd;
+             return NULL;
+          }
+
+        ecore_imf_context_data_set (ctx, ctxd);
+
+        return ctx;
+     }
+
+   static Ecore_IMF_Context *imf_module_exit (void)
+     {
+        return NULL;
+     }
+
+   EINA_MODULE_INIT(imf_module_init);
+   EINA_MODULE_SHUTDOWN(imf_module_shutdown);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/src/modules/ecore_imf/xim/ecore_imf_xim.c b/src/modules/ecore_imf/xim/ecore_imf_xim.c
new file mode 100644 (file)
index 0000000..a115b90
--- /dev/null
@@ -0,0 +1,1444 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+#include <Ecore_IMF.h>
+#include <Ecore_X.h>
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <langinfo.h>
+#include <assert.h>
+
+static int _ecore_imf_xim_log_dom = -1;
+
+#ifdef CRITICAL
+#undef CRITICAL
+#endif
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_ecore_imf_xim_log_dom, __VA_ARGS__)
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_imf_xim_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_imf_xim_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_imf_xim_log_dom, __VA_ARGS__)
+
+
+static Eina_List *open_ims = NULL;
+
+#define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight)
+
+typedef struct _XIM_Im_Info XIM_Im_Info;
+
+typedef struct _Ecore_IMF_Context_Data Ecore_IMF_Context_Data;
+
+struct _XIM_Im_Info
+{
+   Ecore_X_Window win;
+   Ecore_IMF_Context_Data *user;
+   char          *locale;
+   XIM            im;
+   Eina_List     *ics;
+   Eina_Bool      reconnecting;
+   XIMStyles     *xim_styles;
+   Eina_Bool      supports_string_conversion : 1;
+   Eina_Bool      supports_cursor : 1;
+};
+
+struct _Ecore_IMF_Context_Data
+{
+   Ecore_X_Window win;
+   long           mask;
+   XIC            ic; /* Input context for composed characters */
+   char          *locale;
+   XIM_Im_Info   *im_info;
+   int            preedit_length;
+   int            preedit_cursor;
+   Eina_Unicode  *preedit_chars;
+   Eina_Bool      use_preedit;
+   Eina_Bool      finalizing;
+   Eina_Bool      has_focus;
+   Eina_Bool      in_toplevel;
+   XIMFeedback   *feedbacks;
+
+   XIMCallback    destroy_cb;
+
+   XIMCallback    preedit_start_cb;
+   XIMCallback    preedit_done_cb;
+   XIMCallback    preedit_draw_cb;
+   XIMCallback    preedit_caret_cb;
+};
+
+/* prototype */
+static Ecore_IMF_Context_Data *_ecore_imf_xim_context_data_new(void);
+static void                    _ecore_imf_xim_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data);
+
+static void          _ecore_imf_xim_feedback_attr_add(Eina_List **attrs,
+                                                     const char *str,
+                                                     XIMFeedback feedback,
+                                                     int start_pos,
+                                                     int end_pos);
+
+static void          _ecore_imf_xim_ic_reinitialize(Ecore_IMF_Context *ctx);
+static void          _ecore_imf_xim_ic_client_window_set(Ecore_IMF_Context *ctx,
+                                                        Ecore_X_Window window);
+static int           _ecore_imf_xim_preedit_start_call(XIC xic,
+                                                      XPointer client_data,
+                                                      XPointer call_data);
+static void          _ecore_imf_xim_preedit_done_call(XIC xic,
+                                                     XPointer client_data,
+                                                     XPointer call_data);
+static void          _ecore_imf_xim_preedit_draw_call(XIC xic,
+                                                     XPointer client_data,
+                                                     XIMPreeditDrawCallbackStruct *call_data);
+static void          _ecore_imf_xim_preedit_caret_call(XIC xic,
+                                                      XPointer client_data,
+                                                      XIMPreeditCaretCallbackStruct *call_data);
+
+static int           _ecore_imf_xim_text_to_utf8(Ecore_IMF_Context *ctx,
+                                                XIMText *xim_text,
+                                                char **text);
+
+static XVaNestedList _ecore_imf_xim_preedit_callback_set(Ecore_IMF_Context *ctx);
+static XIC           _ecore_imf_xim_ic_get(Ecore_IMF_Context *ctx);
+static XIM_Im_Info  *_ecore_imf_xim_im_get(Ecore_X_Window window,
+                                          char *locale);
+static void          _ecore_imf_xim_info_im_init(XIM_Im_Info *info);
+static void          _ecore_imf_xim_info_im_shutdown(Ecore_X_Display *display,
+                                             int is_error,
+                                             XIM_Im_Info *info);
+static void          _ecore_imf_xim_instantiate_cb(Display *display,
+                                                  XPointer client_data,
+                                                  XPointer call_data);
+static void          _ecore_imf_xim_destroy_cb(XIM xim,
+                                              XPointer client_data,
+                                              XPointer call_data);
+static void          _ecore_imf_xim_im_setup(XIM_Im_Info *info);
+
+static unsigned int
+_ecore_imf_xim_utf8_offset_to_index(const char *str, int offset)
+{
+   int idx = 0;
+   int i;
+   for (i = 0; i < offset; i++)
+     {
+        eina_unicode_utf8_get_next(str, &idx);
+     }
+
+   return idx;
+}
+
+static void
+_ecore_imf_context_xim_add(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = _ecore_imf_xim_context_data_new();
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   imf_context_data->use_preedit = EINA_TRUE;
+   imf_context_data->finalizing = EINA_FALSE;
+   imf_context_data->has_focus = EINA_FALSE;
+   imf_context_data->in_toplevel = EINA_FALSE;
+
+   ecore_imf_context_data_set(ctx, imf_context_data);
+}
+
+static void
+_ecore_imf_context_xim_del(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   imf_context_data->finalizing = EINA_TRUE;
+   if (imf_context_data->im_info && !imf_context_data->im_info->ics->next)
+     {
+        if (imf_context_data->im_info->reconnecting == EINA_TRUE)
+          {
+             Ecore_X_Display *dsp;
+             dsp = ecore_x_display_get();
+             XUnregisterIMInstantiateCallback(dsp,
+                                              NULL, NULL, NULL,
+                                              _ecore_imf_xim_instantiate_cb,
+                                              (XPointer)imf_context_data->im_info);
+          }
+        else if (imf_context_data->im_info->im)
+          {
+             XIMCallback im_destroy_callback;
+             im_destroy_callback.client_data = NULL;
+             im_destroy_callback.callback = NULL;
+             XSetIMValues(imf_context_data->im_info->im,
+                          XNDestroyCallback, &im_destroy_callback,
+                          NULL);
+          }
+     }
+
+   _ecore_imf_xim_ic_client_window_set(ctx, 0);
+
+   _ecore_imf_xim_context_data_destroy(imf_context_data);
+}
+
+static void
+_ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx,
+                                         void *window)
+{
+   DBG("ctx=%p, window=%p", ctx, window);
+   _ecore_imf_xim_ic_client_window_set(ctx, (Ecore_X_Window)((unsigned long)window));
+}
+
+static void
+_ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx,
+                                          char **str,
+                                          int *cursor_pos)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   char *utf8;
+   int len;
+
+   DBG("ctx=%p, imf_context_data=%p, str=%p, cursor_pos=%p",
+       ctx, imf_context_data, str, cursor_pos);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   if (imf_context_data->preedit_chars)
+     {
+        utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars,
+                                            &len);
+        if (str)
+          *str = utf8;
+        else
+          free(utf8);
+     }
+   else
+     {
+        if (str)
+          *str = NULL;
+        if (cursor_pos)
+          *cursor_pos = 0;
+     }
+
+   if (cursor_pos)
+     *cursor_pos = imf_context_data->preedit_cursor;
+}
+
+static void
+_ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
+                                                          char **str,
+                                                          Eina_List **attrs,
+                                                          int *cursor_pos)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   DBG("ctx=%p, imf_context_data=%p, str=%p, attrs=%p, cursor_pos=%p",
+       ctx, imf_context_data, str, attrs, cursor_pos);
+
+   _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos);
+
+   if (!attrs) return;
+   if (!imf_context_data || !imf_context_data->feedbacks) return;
+
+   int i = 0;
+   XIMFeedback last_feedback = 0;
+   int start = -1;
+
+   for (i = 0; i < imf_context_data->preedit_length; i++)
+     {
+        XIMFeedback new_feedback = imf_context_data->feedbacks[i] & FEEDBACK_MASK;
+
+        if (new_feedback != last_feedback)
+          {
+             if (start >= 0)
+               _ecore_imf_xim_feedback_attr_add(attrs, *str, last_feedback, start, i);
+
+             last_feedback = new_feedback;
+             start = i;
+          }
+     }
+
+   if (start >= 0)
+     _ecore_imf_xim_feedback_attr_add(attrs, *str, last_feedback, start, i);
+}
+
+static void
+_ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data  = ecore_imf_context_data_get(ctx);
+   XIC ic;
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   ic = imf_context_data->ic;
+   imf_context_data->has_focus = EINA_TRUE;
+
+   if (ecore_imf_context_input_panel_enabled_get(ctx))
+     ecore_imf_context_input_panel_show(ctx);
+
+   if (ic)
+     {
+        char *str;
+
+#ifdef X_HAVE_UTF8_STRING
+        if ((str = Xutf8ResetIC(ic)))
+#else
+        if ((str = XmbResetIC(ic)))
+#endif
+          XFree(str);
+
+        XSetICFocus(ic);
+     }
+}
+
+static void
+_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   XIC ic;
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   if (imf_context_data->has_focus == EINA_TRUE)
+     {
+        imf_context_data->has_focus = EINA_FALSE;
+        ic = imf_context_data->ic;
+        if (ic)
+          XUnsetICFocus(ic);
+
+        if (ecore_imf_context_input_panel_enabled_get(ctx))
+          ecore_imf_context_input_panel_hide(ctx);
+     }
+}
+
+static void
+_ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   XIC ic;
+   char *result;
+   /* restore conversion state after resetting ic later */
+   XIMPreeditState preedit_state = XIMPreeditUnKnown;
+   XVaNestedList preedit_attr;
+   Eina_Bool have_preedit_state = EINA_FALSE;
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   ic = imf_context_data->ic;
+   if (!ic)
+     return;
+
+   if (imf_context_data->preedit_length == 0)
+     return;
+
+   preedit_attr = XVaCreateNestedList(0,
+                                      XNPreeditState, &preedit_state,
+                                      NULL);
+   if (!XGetICValues(ic,
+                     XNPreeditAttributes, preedit_attr,
+                     NULL))
+     have_preedit_state = EINA_TRUE;
+
+   XFree(preedit_attr);
+
+   result = XmbResetIC(ic);
+
+   preedit_attr = XVaCreateNestedList(0,
+                                      XNPreeditState, preedit_state,
+                                      NULL);
+   if (have_preedit_state)
+     XSetICValues(ic,
+                  XNPreeditAttributes, preedit_attr,
+                  NULL);
+
+   XFree(preedit_attr);
+
+   if (imf_context_data->feedbacks)
+     {
+        free(imf_context_data->feedbacks);
+        imf_context_data->feedbacks = NULL;
+     }
+
+   if (imf_context_data->preedit_length)
+     {
+        imf_context_data->preedit_length = 0;
+        free(imf_context_data->preedit_chars);
+        imf_context_data->preedit_chars = NULL;
+
+        ecore_imf_context_preedit_changed_event_add(ctx);
+        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+     }
+
+   if (result)
+     {
+        char *result_utf8 = strdup(result);
+        if (result_utf8)
+          {
+             ecore_imf_context_commit_event_add(ctx, result_utf8);
+             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8);
+             free(result_utf8);
+          }
+     }
+
+   XFree(result);
+}
+
+static void
+_ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx,
+                                       Eina_Bool use_preedit)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   DBG("ctx=%p, imf_context_data=%p, use_preedit=%hhu", ctx, imf_context_data, use_preedit);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   use_preedit = use_preedit != EINA_FALSE;
+
+   if (imf_context_data->use_preedit != use_preedit)
+     {
+        imf_context_data->use_preedit = use_preedit;
+        _ecore_imf_xim_ic_reinitialize(ctx);
+     }
+}
+
+static void
+_ecore_imf_xim_feedback_attr_add(Eina_List **attrs,
+                                const char *str,
+                                XIMFeedback feedback,
+                                int start_pos,
+                                int end_pos)
+{
+   Ecore_IMF_Preedit_Attr *attr;
+   unsigned int start_index = _ecore_imf_xim_utf8_offset_to_index(str, start_pos);
+   unsigned int end_index = _ecore_imf_xim_utf8_offset_to_index(str, end_pos);
+
+   if (feedback & FEEDBACK_MASK)
+     {
+        attr = calloc(1, sizeof(Ecore_IMF_Preedit_Attr));
+        attr->start_index = start_index;
+        attr->end_index = end_index;
+        *attrs = eina_list_append(*attrs, attr);
+     }
+   else
+     return;
+
+   if (feedback & XIMUnderline)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
+
+   if (feedback & XIMReverse)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
+
+   if (feedback & XIMHighlight)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
+}
+
+static void
+_ecore_imf_context_xim_cursor_location_set(Ecore_IMF_Context *ctx,
+                                           int x, int y, int w, int h)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   XIC ic;
+   XVaNestedList preedit_attr;
+   XPoint spot;
+
+   DBG("ctx=%p, imf_context_data=%p, location=(%d, %d, %d, %d)",
+       ctx, imf_context_data, x, y, w, h);
+
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+   ic = imf_context_data->ic;
+   if (!ic)
+     return;
+
+   spot.x = x;
+   spot.y = y + h;
+
+   preedit_attr = XVaCreateNestedList(0,
+                                      XNSpotLocation, &spot,
+                                      NULL);
+   XSetICValues(ic,
+                XNPreeditAttributes, preedit_attr,
+                NULL);
+
+   XFree(preedit_attr);
+}
+
+static void
+_ecore_imf_context_xim_input_panel_show(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   ecore_x_e_virtual_keyboard_state_set
+        (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
+}
+
+static void
+_ecore_imf_context_xim_input_panel_hide(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   ecore_x_e_virtual_keyboard_state_set
+        (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
+}
+
+static unsigned int
+_ecore_x_event_reverse_modifiers(unsigned int state)
+{
+   unsigned int modifiers = 0;
+
+   /**< "Control" is pressed */
+   if (state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
+     modifiers |= ECORE_X_MODIFIER_CTRL;
+
+   /**< "Alt" is pressed */
+   if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
+     modifiers |= ECORE_X_MODIFIER_ALT;
+
+   /**< "Shift" is pressed */
+   if (state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
+     modifiers |= ECORE_X_MODIFIER_SHIFT;
+
+   /**< "Win" (between "Ctrl" and "Alt") is pressed */
+   if (state & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
+     modifiers |= ECORE_X_MODIFIER_WIN;
+
+   /**< "AltGr" is pressed */
+   if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
+     modifiers |= ECORE_X_MODIFIER_ALTGR;
+
+   return modifiers;
+}
+
+static unsigned int
+_ecore_x_event_reverse_locks(unsigned int state)
+{
+   unsigned int locks = 0;
+
+   /**< "Num" lock is active */
+   if (state & ECORE_IMF_KEYBOARD_LOCK_NUM)
+     locks |= ECORE_X_LOCK_NUM;
+
+   if (state & ECORE_IMF_KEYBOARD_LOCK_CAPS)
+     locks |= ECORE_X_LOCK_CAPS;
+
+   if (state & ECORE_IMF_KEYBOARD_LOCK_SCROLL)
+     locks |= ECORE_X_LOCK_SCROLL;
+
+   return locks;
+}
+
+static KeyCode
+_ecore_imf_xim_keycode_get(Ecore_X_Display *dsp,
+                           const char *keyname)
+{
+   KeyCode keycode;
+
+   //DBG("keyname=%s keysym=%lu", keyname, XStringToKeysym(keyname));
+   if (strcmp(keyname, "Keycode-0") == 0)
+     keycode = 0;
+   else
+     keycode = XKeysymToKeycode(dsp, XStringToKeysym(keyname));
+
+   return keycode;
+}
+
+static Eina_Bool
+_ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx,
+                                    Ecore_IMF_Event_Type type,
+                                    Ecore_IMF_Event *event)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   XIC ic;
+   Ecore_X_Display *dsp;
+   Ecore_X_Window win;
+
+   int val;
+   char compose_buffer[256];
+   KeySym sym;
+   char *compose = NULL;
+   char *tmp = NULL;
+   Eina_Bool result = EINA_FALSE;
+
+   DBG("ctx=%p, imf_context_data=%p, type=%d, event=%p",
+       ctx, imf_context_data, type, event);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, EINA_FALSE);
+   ic = imf_context_data->ic;
+   if (!ic)
+     ic = _ecore_imf_xim_ic_get(ctx);
+
+   if (type == ECORE_IMF_EVENT_KEY_DOWN)
+     {
+        XKeyPressedEvent xev;
+        Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event;
+        DBG("ECORE_IMF_EVENT_KEY_DOWN");
+
+        dsp = ecore_x_display_get();
+        win = imf_context_data->win;
+
+        xev.type = KeyPress;
+        xev.serial = 0; /* hope it doesn't matter */
+        xev.send_event = 0;
+        xev.display = dsp;
+        xev.window = win;
+        xev.root = ecore_x_window_root_get(win);
+        xev.subwindow = win;
+        xev.time = ev->timestamp;
+        xev.x = xev.x_root = 0;
+        xev.y = xev.y_root = 0;
+        xev.state = 0;
+        xev.state |= _ecore_x_event_reverse_modifiers(ev->modifiers);
+        xev.state |= _ecore_x_event_reverse_locks(ev->locks);
+        xev.keycode = _ecore_imf_xim_keycode_get(dsp, ev->keyname);
+        xev.same_screen = True;
+
+        if (ic)
+          {
+             Status mbstatus;
+#ifdef X_HAVE_UTF8_STRING
+             val = Xutf8LookupString(ic,
+                                     &xev,
+                                     compose_buffer,
+                                     sizeof(compose_buffer) - 1,
+                                     &sym,
+                                     &mbstatus);
+#else /* ifdef X_HAVE_UTF8_STRING */
+             val = XmbLookupString(ic,
+                                   &xev,
+                                   compose_buffer,
+                                   sizeof(compose_buffer) - 1,
+                                   &sym,
+                                   &mbstatus);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+             if (mbstatus == XBufferOverflow)
+               {
+                  tmp = malloc(sizeof (char) * (val + 1));
+                  if (!tmp)
+                    return EINA_FALSE;
+
+                  compose = tmp;
+
+#ifdef X_HAVE_UTF8_STRING
+                  val = Xutf8LookupString(ic,
+                                          &xev,
+                                          tmp,
+                                          val,
+                                          &sym,
+                                          &mbstatus);
+#else /* ifdef X_HAVE_UTF8_STRING */
+                  val = XmbLookupString(ic,
+                                        &xev,
+                                        tmp,
+                                        val,
+                                        &sym,
+                                        &mbstatus);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+                  if (val > 0)
+                    {
+                       tmp[val] = '\0';
+#ifndef X_HAVE_UTF8_STRING
+                       compose = eina_str_convert(nl_langinfo(CODESET),
+                                                  "UTF-8", tmp);
+                       free(tmp);
+                       tmp = compose;
+#endif /* ifndef X_HAVE_UTF8_STRING */
+                    }
+                  else
+                    compose = NULL;
+               }
+             else if (val > 0)
+               {
+                  compose_buffer[val] = '\0';
+#ifdef X_HAVE_UTF8_STRING
+                  compose = strdup(compose_buffer);
+#else /* ifdef X_HAVE_UTF8_STRING */
+                  compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8",
+                                             compose_buffer);
+#endif /* ifdef X_HAVE_UTF8_STRING */
+               }
+          }
+        else
+          {
+             compose = strdup(ev->compose);
+          }
+
+        if (compose)
+          {
+             Eina_Unicode *unicode;
+             int len;
+             unicode = eina_unicode_utf8_to_unicode(compose, &len);
+             if (!unicode) abort();
+             if (unicode[0] >= 0x20 && unicode[0] != 0x7f)
+               {
+                  ecore_imf_context_commit_event_add(ctx, compose);
+                  ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose);
+                  result = EINA_TRUE;
+               }
+             free(compose);
+             free(unicode);
+          }
+     }
+
+   return result;
+}
+
+static const Ecore_IMF_Context_Info xim_info = {
+   .id = "xim",
+   .description = "X input method",
+   .default_locales = "ko:ja:th:zh",
+   .canvas_type = "evas",
+   .canvas_required = 1,
+};
+
+static Ecore_IMF_Context_Class xim_class = {
+   .add = _ecore_imf_context_xim_add,
+   .del = _ecore_imf_context_xim_del,
+   .client_window_set = _ecore_imf_context_xim_client_window_set,
+   .client_canvas_set = NULL,
+   .show = _ecore_imf_context_xim_input_panel_show,
+   .hide = _ecore_imf_context_xim_input_panel_hide,
+   .preedit_string_get = _ecore_imf_context_xim_preedit_string_get,
+   .focus_in = _ecore_imf_context_xim_focus_in,
+   .focus_out = _ecore_imf_context_xim_focus_out,
+   .reset = _ecore_imf_context_xim_reset,
+   .cursor_position_set = NULL,
+   .use_preedit_set = _ecore_imf_context_xim_use_preedit_set,
+   .input_mode_set = NULL,
+   .filter_event = _ecore_imf_context_xim_filter_event,
+   .preedit_string_with_attributes_get = _ecore_imf_context_xim_preedit_string_with_attributes_get,
+   .prediction_allow_set = NULL,
+   .autocapital_type_set = NULL,
+   .control_panel_show = NULL,
+   .control_panel_hide = NULL,
+   .input_panel_layout_set = NULL,
+   .input_panel_layout_get = NULL,
+   .input_panel_language_set = NULL,
+   .input_panel_language_get = NULL,
+   .cursor_location_set = _ecore_imf_context_xim_cursor_location_set,
+   .input_panel_imdata_set = NULL,
+   .input_panel_imdata_get = NULL,
+   .input_panel_return_key_type_set = NULL,
+   .input_panel_return_key_disabled_set = NULL,
+   .input_panel_caps_lock_mode_set = NULL
+};
+
+static Ecore_IMF_Context *
+xim_imf_module_create(void)
+{
+   Ecore_IMF_Context *ctx = ecore_imf_context_new(&xim_class);
+   DBG("ctx=%p", ctx);
+   return ctx;
+}
+
+static Ecore_IMF_Context *
+xim_imf_module_exit(void)
+{
+   DBG(" ");
+   return NULL;
+}
+
+static Eina_Bool
+_ecore_imf_xim_init(void)
+{
+   eina_init();
+
+   _ecore_imf_xim_log_dom = eina_log_domain_register("ecore_imf_xim", NULL);
+   if (_ecore_imf_xim_log_dom < 0)
+     {
+        EINA_LOG_ERR("Could not register log domain: ecore_imf_xim");
+        return EINA_FALSE;
+     }
+
+   DBG(" ");
+
+   ecore_x_init(NULL);
+   ecore_imf_module_register(&xim_info,
+                             xim_imf_module_create,
+                             xim_imf_module_exit);
+
+   return EINA_TRUE;
+}
+
+static void
+_ecore_imf_xim_shutdown(void)
+{
+   while (open_ims)
+     {
+        XIM_Im_Info *info = open_ims->data;
+        Ecore_X_Display *display = ecore_x_display_get();
+
+        _ecore_imf_xim_info_im_shutdown(display, EINA_FALSE, info);
+     }
+
+   ecore_x_shutdown();
+
+   if (_ecore_imf_xim_log_dom > 0)
+     {
+        eina_log_domain_unregister(_ecore_imf_xim_log_dom);
+        _ecore_imf_xim_log_dom = -1;
+     }
+
+   eina_shutdown();
+}
+
+EINA_MODULE_INIT(_ecore_imf_xim_init);
+EINA_MODULE_SHUTDOWN(_ecore_imf_xim_shutdown);
+
+/*
+ * internal functions
+ */
+static Ecore_IMF_Context_Data *
+_ecore_imf_xim_context_data_new(void)
+{
+   Ecore_IMF_Context_Data *imf_context_data = NULL;
+   char *locale;
+
+   locale = setlocale(LC_CTYPE, "");
+   if (!locale) return NULL;
+
+   if (!XSupportsLocale()) return NULL;
+
+   imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL);
+
+   imf_context_data->locale = strdup(locale);
+   if (!imf_context_data->locale) goto error;
+
+   return imf_context_data;
+error:
+   _ecore_imf_xim_context_data_destroy(imf_context_data);
+   return NULL;
+}
+
+static void
+_ecore_imf_xim_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data)
+{
+   if (!imf_context_data)
+     return;
+
+   if (imf_context_data->ic)
+     XDestroyIC(imf_context_data->ic);
+
+   free(imf_context_data->preedit_chars);
+
+   if (imf_context_data->feedbacks)
+     {
+        free(imf_context_data->feedbacks);
+        imf_context_data->feedbacks = NULL;
+     }
+
+   free(imf_context_data->locale);
+   free(imf_context_data);
+}
+
+static int
+_ecore_imf_xim_preedit_start_call(XIC xic EINA_UNUSED,
+                                 XPointer client_data,
+                                 XPointer call_data EINA_UNUSED)
+{
+   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, -1);
+
+   if (imf_context_data->finalizing == EINA_FALSE)
+     {
+        ecore_imf_context_preedit_start_event_add(ctx);
+        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
+     }
+   return -1;
+}
+
+static void
+_ecore_imf_xim_preedit_done_call(XIC xic EINA_UNUSED,
+                                XPointer client_data,
+                                XPointer call_data EINA_UNUSED)
+{
+   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   if (imf_context_data->preedit_length)
+     {
+        imf_context_data->preedit_length = 0;
+        free(imf_context_data->preedit_chars);
+        imf_context_data->preedit_chars = NULL;
+        ecore_imf_context_preedit_changed_event_add(ctx);
+        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+     }
+
+   if (imf_context_data->finalizing == EINA_FALSE)
+     {
+        ecore_imf_context_preedit_end_event_add(ctx);
+        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
+     }
+}
+
+/* FIXME */
+static int
+_ecore_imf_xim_text_to_utf8(Ecore_IMF_Context *ctx EINA_UNUSED,
+                           XIMText *xim_text,
+                           char **text)
+{
+   int text_length = 0;
+   char *result = NULL;
+
+   if (xim_text && xim_text->string.multi_byte)
+     {
+        if (xim_text->encoding_is_wchar)
+          {
+             WRN("Wide character return from Xlib not currently supported");
+             *text = NULL;
+             return 0;
+          }
+
+        /* XXX Convert to UTF-8 */
+        result = strdup(xim_text->string.multi_byte);
+        if (result)
+          {
+             text_length = eina_unicode_utf8_get_len(result);
+             if (text_length != xim_text->length)
+               {
+                  WRN("Size mismatch when converting text from input method: supplied length = %d, result length = %d",
+                      xim_text->length, text_length);
+               }
+          }
+        else
+          {
+             WRN("Error converting text from IM to UCS-4");
+             *text = NULL;
+             return 0;
+          }
+
+        *text = result;
+        return text_length;
+     }
+   else
+     {
+        *text = NULL;
+        return 0;
+     }
+}
+
+static void
+_ecore_imf_xim_preedit_draw_call(XIC xic EINA_UNUSED,
+                                XPointer client_data,
+                                XIMPreeditDrawCallbackStruct *call_data)
+{
+   Eina_Bool ret = EINA_FALSE;
+   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   XIMText *t = call_data->text;
+   char *tmp;
+   Eina_Unicode *new_text = NULL;
+   Eina_UStrbuf *preedit_bufs = NULL;
+   int new_text_length;
+   int i = 0;
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   preedit_bufs = eina_ustrbuf_new();
+   if (imf_context_data->preedit_chars)
+     {
+        ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars);
+        if (ret == EINA_FALSE) goto done;
+     }
+
+   new_text_length = _ecore_imf_xim_text_to_utf8(ctx, t, &tmp);
+   if (tmp)
+     {
+        int tmp_len;
+        new_text = eina_unicode_utf8_to_unicode(tmp, &tmp_len);
+        free(tmp);
+     }
+
+   if (t == NULL)
+     {
+        /* delete string */
+        ret = eina_ustrbuf_remove(preedit_bufs,
+                                  call_data->chg_first, call_data->chg_length);
+     }
+   else if (call_data->chg_length == 0)
+     {
+        /* insert string */
+        ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first);
+     }
+   else if (call_data->chg_length > 0)
+     {
+        /* replace string */
+        ret = eina_ustrbuf_remove(preedit_bufs,
+                                  call_data->chg_first, call_data->chg_length);
+        if (ret == EINA_FALSE) goto done;
+
+        ret = eina_ustrbuf_insert_n(preedit_bufs, new_text,
+                                    new_text_length, call_data->chg_first);
+        if (ret == EINA_FALSE) goto done;
+     }
+   else
+     {
+        ret = EINA_FALSE;
+     }
+
+done:
+   if (ret == EINA_TRUE)
+     {
+        free(imf_context_data->preedit_chars);
+        imf_context_data->preedit_chars =
+          eina_ustrbuf_string_steal(preedit_bufs);
+        imf_context_data->preedit_length =
+          eina_unicode_strlen(imf_context_data->preedit_chars);
+
+        if (imf_context_data->feedbacks)
+          {
+             free(imf_context_data->feedbacks);
+             imf_context_data->feedbacks = NULL;
+          }
+
+        if (imf_context_data->preedit_length > 0)
+          {
+             imf_context_data->feedbacks = calloc(imf_context_data->preedit_length, sizeof(XIMFeedback));
+
+             for (i = 0; i < imf_context_data->preedit_length; i++)
+               imf_context_data->feedbacks[i] = t->feedback[i];
+          }
+
+        ecore_imf_context_preedit_changed_event_add(ctx);
+        ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+     }
+
+   free(new_text);
+   eina_ustrbuf_free(preedit_bufs);
+}
+
+static void
+_ecore_imf_xim_preedit_caret_call(XIC xic EINA_UNUSED,
+                                 XPointer client_data,
+                                 XIMPreeditCaretCallbackStruct *call_data)
+{
+   Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data;
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   if (call_data->direction == XIMAbsolutePosition)
+     {
+        imf_context_data->preedit_cursor = call_data->position;
+        if (imf_context_data->finalizing == EINA_FALSE)
+          {
+             ecore_imf_context_preedit_changed_event_add(ctx);
+             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+          }
+     }
+}
+
+static XVaNestedList
+_ecore_imf_xim_preedit_callback_set(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data;
+   imf_context_data = ecore_imf_context_data_get(ctx);
+
+   imf_context_data->preedit_start_cb.client_data = (XPointer)ctx;
+   imf_context_data->preedit_start_cb.callback = (XIMProc)_ecore_imf_xim_preedit_start_call;
+
+   imf_context_data->preedit_done_cb.client_data = (XPointer)ctx;
+   imf_context_data->preedit_done_cb.callback = (XIMProc)_ecore_imf_xim_preedit_done_call;
+
+   imf_context_data->preedit_draw_cb.client_data = (XPointer)ctx;
+   imf_context_data->preedit_draw_cb.callback = (XIMProc)_ecore_imf_xim_preedit_draw_call;
+
+   imf_context_data->preedit_caret_cb.client_data = (XPointer)ctx;
+   imf_context_data->preedit_caret_cb.callback = (XIMProc)_ecore_imf_xim_preedit_caret_call;
+
+   return XVaCreateNestedList(0,
+                              XNPreeditStartCallback,
+                              &imf_context_data->preedit_start_cb,
+                              XNPreeditDoneCallback,
+                              &imf_context_data->preedit_done_cb,
+                              XNPreeditDrawCallback,
+                              &imf_context_data->preedit_draw_cb,
+                              XNPreeditCaretCallback,
+                              &imf_context_data->preedit_caret_cb,
+                              NULL);
+}
+
+static XIC
+_ecore_imf_xim_ic_get(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data;
+   XIC ic;
+   imf_context_data = ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL);
+
+   ic = imf_context_data->ic;
+   if (!ic)
+     {
+        XIM_Im_Info *im_info = imf_context_data->im_info;
+        XVaNestedList preedit_attr = NULL;
+        XIMStyle im_style = 0;
+        XPoint spot = { 0, 0 };
+        char *name = NULL;
+
+        if (!im_info)
+          {
+             WRN("Could not open XIM.");
+             return NULL;
+          }
+
+        // supported styles
+        // "OverTheSpot" = XIMPreeditPosition | XIMStatusNothing
+        // "OffTheSpot" = XIMPreeditArea | XIMStatusArea
+        // "Root" = XIMPreeditNothing | XIMStatusNothing
+
+        if (imf_context_data->use_preedit == EINA_TRUE)
+          {
+             if (im_info->supports_cursor)
+               {
+                  // kinput2 DOES do this...
+                  XFontSet fs;
+                  char **missing_charset_list;
+                  int missing_charset_count;
+                  char *def_string;
+
+                  im_style |= XIMPreeditPosition;
+                  im_style |= XIMStatusNothing;
+                  fs = XCreateFontSet(ecore_x_display_get(),
+                                      "fixed",
+                                      &missing_charset_list,
+                                      &missing_charset_count,
+                                      &def_string);
+                  preedit_attr = XVaCreateNestedList(0,
+                                                     XNSpotLocation, &spot,
+                                                     XNFontSet, fs,
+                                                     NULL);
+               }
+             else
+               {
+                  im_style |= XIMPreeditCallbacks;
+                  im_style |= XIMStatusNothing;
+                  preedit_attr = _ecore_imf_xim_preedit_callback_set(ctx);
+               }
+             name = XNPreeditAttributes;
+          }
+        else
+          {
+             im_style |= XIMPreeditNothing;
+             im_style |= XIMStatusNothing;
+          }
+
+        if (!im_info->xim_styles)
+          {
+             WRN("No XIM styles supported! Wanted %#llx",
+                 (unsigned long long)im_style);
+             im_style = 0;
+          }
+        else
+          {
+             XIMStyle fallback = 0;
+             int i;
+
+             for (i = 0; i < im_info->xim_styles->count_styles; i++)
+               {
+                  XIMStyle cur = im_info->xim_styles->supported_styles[i];
+                  if (cur == im_style)
+                    break;
+                  else if (cur == (XIMPreeditNothing | XIMStatusNothing))
+                    /* TODO: fallback is just that or the anyone? */
+                    fallback = cur;
+               }
+
+             if (i == im_info->xim_styles->count_styles)
+               {
+                  if (fallback)
+                    {
+                       WRN("Wanted XIM style %#llx not found, using fallback %#llx instead.",
+                           (unsigned long long)im_style,
+                           (unsigned long long)fallback);
+                       im_style = fallback;
+                    }
+                  else
+                    {
+                       WRN("Wanted XIM style %#llx not found, no fallback supported.",
+                           (unsigned long long)im_style);
+                       im_style = 0;
+                    }
+               }
+          }
+
+        if ((im_info->im) && (im_style))
+          {
+             ic = XCreateIC(im_info->im,
+                            XNInputStyle, im_style,
+                            XNClientWindow, imf_context_data->win,
+                            name, preedit_attr, NULL);
+          }
+        XFree(preedit_attr);
+        if (ic)
+          {
+             unsigned long mask = 0xaaaaaaaa;
+             XGetICValues(ic,
+                          XNFilterEvents, &mask,
+                          NULL);
+             imf_context_data->mask = mask;
+             ecore_x_event_mask_set(imf_context_data->win, mask);
+          }
+
+        imf_context_data->ic = ic;
+        if (ic && imf_context_data->has_focus == EINA_TRUE)
+          XSetICFocus(ic);
+     }
+
+   return ic;
+}
+
+static void
+_ecore_imf_xim_ic_reinitialize(Ecore_IMF_Context *ctx)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   XIC ic = imf_context_data->ic;
+   if (ic)
+     {
+        XDestroyIC(ic);
+        imf_context_data->ic = NULL;
+        if (imf_context_data->preedit_length)
+          {
+             imf_context_data->preedit_length = 0;
+             free(imf_context_data->preedit_chars);
+             imf_context_data->preedit_chars = NULL;
+             ecore_imf_context_preedit_changed_event_add(ctx);
+             ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
+          }
+     }
+}
+
+static void
+_ecore_imf_xim_ic_client_window_set(Ecore_IMF_Context *ctx,
+                                    Ecore_X_Window window)
+{
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+   Ecore_X_Window old_win;
+
+   DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data);
+   EINA_SAFETY_ON_NULL_RETURN(imf_context_data);
+
+   /* reinitialize IC */
+   _ecore_imf_xim_ic_reinitialize(ctx);
+
+   old_win = imf_context_data->win;
+   DBG("old_win=%#x, window=%#x", old_win, window);
+   if (old_win != 0 && old_win != window)   /* XXX how do check window... */
+     {
+        XIM_Im_Info *info;
+        info = imf_context_data->im_info;
+        info->ics = eina_list_remove(info->ics, imf_context_data);
+        if (imf_context_data->im_info)
+          imf_context_data->im_info->user = NULL;
+        imf_context_data->im_info = NULL;
+     }
+
+   imf_context_data->win = window;
+
+   if (window) /* XXX */
+     {
+        XIM_Im_Info *info = NULL;
+        info = _ecore_imf_xim_im_get(window, imf_context_data->locale);
+        imf_context_data->im_info = info;
+        imf_context_data->im_info->ics =
+          eina_list_prepend(imf_context_data->im_info->ics,
+                            imf_context_data);
+        if (imf_context_data->im_info)
+          imf_context_data->im_info->user = imf_context_data;
+     }
+}
+
+static XIM_Im_Info *
+_ecore_imf_xim_im_get(Ecore_X_Window window,
+                     char *locale)
+{
+   Eina_List *l;
+   XIM_Im_Info *im_info = NULL;
+   XIM_Im_Info *info = NULL;
+
+   DBG(" ");
+   EINA_LIST_FOREACH (open_ims, l, im_info)
+     {
+        if (strcmp(im_info->locale, locale) == 0)
+          {
+             if (im_info->im)
+               {
+                  return im_info;
+               }
+             else
+               {
+                  info = im_info;
+                  break;
+               }
+          }
+     }
+
+   if (!info)
+     {
+        info = calloc(1, sizeof(XIM_Im_Info));
+        if (!info) return NULL;
+        open_ims = eina_list_prepend(open_ims, info);
+        info->win = window;
+        info->locale = strdup(locale);
+        info->reconnecting = EINA_FALSE;
+     }
+
+   _ecore_imf_xim_info_im_init(info);
+   return info;
+}
+
+/* initialize info->im */
+static void
+_ecore_imf_xim_info_im_init(XIM_Im_Info *info)
+{
+   Ecore_X_Display *dsp;
+
+   assert(info->im == NULL);
+   if (info->reconnecting == EINA_TRUE)
+     return;
+
+   if (XSupportsLocale())
+     {
+        if (!XSetLocaleModifiers(""))
+          WRN("Unable to set locale modifiers with XSetLocaleModifiers()");
+        dsp = ecore_x_display_get();
+        info->im = XOpenIM(dsp, NULL, NULL, NULL);
+        if (!info->im)
+          {
+             XRegisterIMInstantiateCallback(dsp,
+                                            NULL, NULL, NULL,
+                                            _ecore_imf_xim_instantiate_cb,
+                                            (XPointer)info);
+             info->reconnecting = EINA_TRUE;
+             return;
+          }
+        _ecore_imf_xim_im_setup(info);
+     }
+}
+
+static void
+_ecore_imf_xim_info_im_shutdown(Ecore_X_Display *display EINA_UNUSED,
+                               int is_error EINA_UNUSED,
+                               XIM_Im_Info *info)
+{
+   Eina_List *ics, *tmp_list;
+   Ecore_IMF_Context *ctx;
+
+   open_ims = eina_list_remove(open_ims, info);
+
+   ics = info->ics;
+   info->ics = NULL;
+
+   EINA_LIST_FOREACH (ics, tmp_list, ctx)
+     _ecore_imf_xim_ic_client_window_set(ctx, 0);
+
+   EINA_LIST_FREE (ics, ctx)
+     {
+        Ecore_IMF_Context_Data *imf_context_data;
+        imf_context_data = ecore_imf_context_data_get(ctx);
+        _ecore_imf_xim_context_data_destroy(imf_context_data);
+     }
+
+   free(info->locale);
+
+   if (info->im)
+     XCloseIM(info->im);
+
+   free(info);
+}
+
+static void
+_ecore_imf_xim_instantiate_cb(Display *display,
+                             XPointer client_data,
+                             XPointer call_data EINA_UNUSED)
+{
+   XIM_Im_Info *info = (XIM_Im_Info *)client_data;
+   XIM im = XOpenIM(display, NULL, NULL, NULL);
+   EINA_SAFETY_ON_NULL_RETURN(im);
+
+   info->im = im;
+   _ecore_imf_xim_im_setup(info);
+
+   XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL,
+                                    _ecore_imf_xim_instantiate_cb,
+                                    (XPointer)info);
+   info->reconnecting = EINA_FALSE;
+}
+
+static void
+_ecore_imf_xim_im_setup(XIM_Im_Info *info)
+{
+   XIMValuesList *ic_values = NULL;
+   XIMCallback im_destroy_callback;
+
+   if (!info->im)
+     return;
+
+   im_destroy_callback.client_data = (XPointer)info;
+   im_destroy_callback.callback = (XIMProc)_ecore_imf_xim_destroy_cb;
+   XSetIMValues(info->im,
+                XNDestroyCallback, &im_destroy_callback,
+                NULL);
+
+   XGetIMValues(info->im,
+                XNQueryInputStyle, &info->xim_styles,
+                XNQueryICValuesList, &ic_values,
+                NULL);
+
+   if (ic_values)
+     {
+        int i;
+
+        for (i = 0; i < ic_values->count_values; i++)
+          {
+             if (!strcmp(ic_values->supported_values[i],
+                         XNStringConversionCallback))
+               info->supports_string_conversion = EINA_TRUE;
+             if (!strcmp(ic_values->supported_values[i],
+                         XNCursor))
+               info->supports_cursor = EINA_TRUE;
+          }
+
+        XFree(ic_values);
+     }
+}
+
+static void
+_ecore_imf_xim_destroy_cb(XIM xim EINA_UNUSED,
+                         XPointer client_data,
+                         XPointer call_data EINA_UNUSED)
+{
+   XIM_Im_Info *info = (XIM_Im_Info *)client_data;
+
+   if (info->user) info->user->ic = NULL;
+   info->im = NULL;
+//   _ecore_imf_xim_ic_reinitialize(ctx);
+   _ecore_imf_xim_info_im_init(info);
+
+   return;
+}