Enable Wayland input method protocol. 54/22454/3
authorYan Wang <yan.wang@linux.intel.com>
Wed, 4 Jun 2014 08:53:33 +0000 (16:53 +0800)
committerYan Wang <yan.wang@linux.intel.com>
Tue, 15 Jul 2014 06:43:21 +0000 (14:43 +0800)
Change-Id: Ifaf99647e1ad6dd5137de562ea80e6d5e542d87c

28 files changed:
configure.ac
ism/configs/global
ism/demos/Makefile.am
ism/extras/Makefile.am
ism/extras/efl_immodule/Makefile.am
ism/extras/efl_panel/Makefile.am
ism/extras/efl_wsc/Makefile.am [new file with mode: 0644]
ism/extras/efl_wsc/input-method-client-protocol.h [new file with mode: 0644]
ism/extras/efl_wsc/input-method-protocol.c [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_context.cpp [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_context.h [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_control.cpp [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_control.h [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_control_ui.cpp [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_control_ui.h [new file with mode: 0644]
ism/extras/efl_wsc/isf_wsc_efl.cpp [new file with mode: 0644]
ism/extras/efl_wsc/text-client-protocol.h [new file with mode: 0644]
ism/extras/efl_wsc/text-protocol.c [new file with mode: 0644]
ism/extras/efl_wsm/Makefile.am [new file with mode: 0644]
ism/extras/efl_wsm/isf_wsm_efl.cpp [new file with mode: 0644]
ism/extras/efl_wsm/isf_wsm_utility.cpp [new file with mode: 0644]
ism/extras/efl_wsm/isf_wsm_utility.h [new file with mode: 0644]
ism/src/Makefile.am
ism/src/ise_context.h
ism/src/ise_preexec.cpp
ism/src/scim.cpp
ism/src/scim_config_path.h
packaging/isf.spec

index 7c411fd..0c092d4 100755 (executable)
@@ -215,10 +215,18 @@ if test "$ISF_HAS_GCONF" = "yes"; then
 fi
 
 # Check EFL library
-PKG_CHECK_MODULES(EFL, [elementary ecore-x evas ecore ecore-evas ecore-file edje ecore-input ecore-ipc ecore-imf],
+PKG_CHECK_MODULES(EFL, [elementary evas ecore ecore-evas ecore-file edje ecore-input ecore-ipc ecore-imf],
                   [ISF_HAS_EFL=yes],
                   [ISF_HAS_EFL=no])
 
+PKG_CHECK_MODULES(ECOREX, [ecore-x],
+                  [ISF_HAS_ECOREX=yes],
+                  [ISF_HAS_ECOREX=no])
+
+PKG_CHECK_MODULES(WAYLAND, [ecore-wayland wayland-client >= 1.2.0 xkbcommon],
+                  [ISF_HAS_ECOREWL=yes],
+                  [ISF_HAS_ECOREWL=no])
+
 if test "$ISF_HAS_EFL" = "yes"; then
   EFL_LIBDIR=`$PKG_CONFIG --variable=libdir ecore-imf`
   if test -z "$EFL_LIBDIR)"; then
@@ -233,7 +241,9 @@ fi
 PKG_CHECK_MODULES(EFL_ASSIST, [efl-assist])
 
 # Check x11 library
-PKG_CHECK_MODULES(X11, [x11])
+PKG_CHECK_MODULES(X11, [x11],
+                  [ISF_HAS_X11=yes],
+                  [ISF_HAS_X11=no])
 
 # Check ui-gadget library
 PKG_CHECK_MODULES(UIGADGET, [ui-gadget-1],
@@ -241,7 +251,9 @@ PKG_CHECK_MODULES(UIGADGET, [ui-gadget-1],
                   [ISF_HAS_UIGADGET=no])
 
 # Check utilX library
-PKG_CHECK_MODULES(UTILX, [utilX])
+PKG_CHECK_MODULES(UTILX, [utilX],
+                  [ISF_HAS_UTILX=yes],
+                  [ISF_HAS_UTILX=no])
 
 # Check appcore-efl library
 PKG_CHECK_MODULES(APPCORE_EFL, [appcore-efl])
@@ -441,6 +453,16 @@ AC_ARG_ENABLE(panel-efl,
               enable_panel_efl=no,
               enable_panel_efl=check)
 
+AC_ARG_ENABLE(wsm-efl,
+              [  --disable-wsm-efl       Do not build EFL Wsm],
+              enable_wsm_efl=no,
+              enable_wsm_efl=check)
+
+AC_ARG_ENABLE(wsc-efl,
+              [  --disable-wsc-efl       Do not build EFL Wsc],
+              enable_wsc_efl=no,
+              enable_wsc_efl=yes)
+
 AC_ARG_ENABLE(setting-efl,
               [  --disable-setting-efl     Do not build EFL Setting],
               enable_setting_efl=no,
@@ -560,6 +582,13 @@ else
   enable_efl_immodule=no
 fi
 
+if test "$enable_wsc_efl" = "yes" -a "$ISF_HAS_EFL" = "yes"; then
+  ISF_BUILD_WSC_EFL=1
+else
+  ISF_BUILD_WSC_EFL=0
+  enable_wsc_efl=no
+fi
+
 ISF_BUILD_PANEL_EFL=0
 if test "$enable_panel_efl" != "no"; then
   enable_panel_efl=no
@@ -569,6 +598,15 @@ if test "$enable_panel_efl" != "no"; then
   fi
 fi
 
+ISF_BUILD_WSM_EFL=0
+if test "$enable_wsm_efl" != "no"; then
+  enable_wsm_efl=no
+  if test "$ISF_HAS_EFL" = "yes"; then
+    ISF_BUILD_WSM_EFL=1
+    enable_wsm_efl=yes
+  fi
+fi
+
 ISF_BUILD_SETTING_EFL=0
 if test "$enable_setting_efl" != "no"; then
   enable_setting_efl=no
@@ -584,6 +622,9 @@ if test "$enable_panel_gtk" != "yes"; then
   SCIM_BUILD_GTK_UTILS=0
 fi
 
+AM_CONDITIONAL(HAVE_X,
+                [test "$have_x" = "yes"])
+
 AM_CONDITIONAL(SCIM_LD_VERSION_SCRIPT,
                 [test "$enable_ld_version_script" = "yes"])
 
@@ -626,9 +667,15 @@ AM_CONDITIONAL(SCIM_BUILD_TRAY_ICON,
 AM_CONDITIONAL(ISF_BUILD_EFL_IMMODULE,
                 [test "$enable_efl_immodule" = "yes"])
 
+AM_CONDITIONAL(ISF_BUILD_WSC_EFL,
+                [test "$enable_wsc_efl" = "yes"])
+
 AM_CONDITIONAL(ISF_BUILD_PANEL_EFL,
                 [test "$enable_panel_efl" = "yes"])
 
+AM_CONDITIONAL(ISF_BUILD_WSM_EFL,
+                [test "$enable_wsm_efl" = "yes"])
+
 AM_CONDITIONAL(ISF_BUILD_SETTING_EFL,
                 [test "$enable_setting_efl" = "yes"])
 
@@ -701,6 +748,8 @@ AC_CONFIG_FILES([Makefile
                  ism/extras/gtk2_immodule/Makefile
                  ism/extras/efl_immodule/Makefile
                  ism/extras/efl_panel/Makefile
+                 ism/extras/efl_wsm/Makefile
+                 ism/extras/efl_wsc/Makefile
                  ism/demos/Makefile
                  intltool-extract
                  intltool-merge
@@ -741,6 +790,8 @@ Module options:
   EFL  IMModule            $enable_efl_immodule
   EFL  IMModule dir        $EFL_IM_MODULEDIR
   EFL  Panel GUI           $enable_panel_efl
+  EFL  Wsm GUI             $enable_wsm_efl
+  EFL  Wsc GUI             $enable_wsc_efl
   EFL  Setting             $enable_setting_efl
 
   Enable TrayIcon          $enable_tray_icon
index 7913bcd..e8ff055 100755 (executable)
@@ -1,5 +1,6 @@
 /SupportedUnicodeLocales = en_US.UTF-8
 /DefaultPanelProgram = isf-panel-efl
+/DefaultPanelProgram2 = isf-wsm-efl
 /DefaultConfigModule = simple
 /DefaultSocketFrontEndAddress = local:/tmp/scim-socket-frontend
 /DefaultSocketIMEngineAddress = local:/tmp/scim-socket-frontend
index 6506159..6e19cd3 100644 (file)
@@ -42,6 +42,7 @@ isf_demo_efl_SOURCES  = isf_demo_efl.cpp \
                         isf_ondemand_efl.cpp
 
 isf_demo_efl_CXXFLAGS = @EFL_CFLAGS@ \
+                        @ECOREX_CFLAGS@ \
                         @APPCORE_EFL_CFLAGS@ \
                         @UIGADGET_CFLAGS@ \
                         @VCONF_CFLAGS@ \
@@ -49,6 +50,7 @@ isf_demo_efl_CXXFLAGS = @EFL_CFLAGS@ \
                         @EFL_ASSIST_CFLAGS@
 
 isf_demo_efl_LDFLAGS  = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \
+                        @ECOREX_LIBS@ \
                         @VCONF_LIBS@ \
                         @APPCORE_EFL_LIBS@ \
                         @UIGADGET_LIBS@ \
index 65bee7b..73c28a6 100644 (file)
@@ -18,4 +18,4 @@
 MAINTAINERCLEANFILES   = Makefile.in
 CLEANFILES             = *.bak
 
-SUBDIRS                        = gtk2_immodule efl_panel efl_immodule
+SUBDIRS                        = gtk2_immodule efl_panel efl_immodule efl_wsm efl_wsc
index 364f893..dae8f1d 100644 (file)
@@ -35,6 +35,7 @@ libisf_imf_module_la_SOURCES  = isf_imf_module.cpp \
                                 isf_imf_control.cpp
 
 libisf_imf_module_la_CXXFLAGS = @EFL_CFLAGS@ \
+                                @ECOREX_CFLAGS@ \
                                 @UTILX_CFLAGS@ \
                                 @VCONF_CFLAGS@ \
                                 @DLOG_CFLAGS@
@@ -46,6 +47,7 @@ libisf_imf_module_la_LDFLAGS  = -rpath $(moduledir) \
 libisf_imf_module_la_LIBADD  =  -lstdc++ \
                                 $(LD_VERSION_SCRIPT_OPTION) \
                                 @EFL_LIBS@ \
+                                @ECOREX_LIBS@ \
                                 @UTILX_LIBS@ \
                                 @VCONF_LIBS@ \
                                 @DLOG_LIBS@ \
index 4625af6..144c028 100644 (file)
@@ -33,10 +33,11 @@ if ISF_BUILD_MINICONTROL
 isf_panel_efl_SOURCES  += minicontrol.cpp
 endif
 
-isf_panel_efl_CXXFLAGS = @EFL_CFLAGS@ @EFL_ASSIST_CFLAGS@ @VCONF_CFLAGS@ @X11_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ @DLOG_CFLAGS@ \
+isf_panel_efl_CXXFLAGS = @EFL_CFLAGS@ @ECOREX_CFLAGS@ @EFL_ASSIST_CFLAGS@ @VCONF_CFLAGS@ @X11_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ @DLOG_CFLAGS@ \
                          @MINICONTROL_PROVIDER_CFLAGS@ @NOTIFICATION_CFLAGS@ @TTS_CFLAGS@ @EDBUS_CFLAGS@ @BLUETOOTH_CFLAGS@ @FEEDBACK_CFLAGS@
 
 isf_panel_efl_LDFLAGS  = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \
+                         @ECOREX_LIBS@ \
                          @EFL_ASSIST_LIBS@ \
                          @VCONF_LIBS@ \
                          @X11_LIBS@ \
diff --git a/ism/extras/efl_wsc/Makefile.am b/ism/extras/efl_wsc/Makefile.am
new file mode 100644 (file)
index 0000000..40bd1fa
--- /dev/null
@@ -0,0 +1,49 @@
+MAINTAINERCLEANFILES = Makefile.in
+CLEANFILES           = *.bak *.edj
+
+INCLUDES = -I$(top_builddir) \
+           -I$(top_builddir)/ism/src \
+           -I$(top_srcdir) \
+           -I$(top_srcdir)/ism/src \
+           -I$(top_srcdir)/ism/intl \
+           -I$(top_srcdir)/ism/data \
+           -I$(top_srcdir)/ism/utils \
+           -I$(includedir) \
+           -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \
+           -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \
+           -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \
+           -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \
+           -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \
+           -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \
+           -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\"
+
+noinst_HEADERS = input-method-client-protocol.h \
+                                       text-client-protocol.h \
+                                       isf_wsc_context.h \
+                                       isf_wsc_control.h \
+                                       isf_wsc_control_ui.h
+
+if ISF_BUILD_WSC_EFL
+CONFIG_WSC_EFL  = isf-wsc-efl
+endif
+
+bin_PROGRAMS           = $(CONFIG_WSC_EFL)
+
+isf_wsc_efl_SOURCES  = isf_wsc_efl.cpp \
+                                                input-method-protocol.c \
+                                                text-protocol.c \
+                                                isf_wsc_context.cpp \
+                                                isf_wsc_control.cpp \
+                                                isf_wsc_control_ui.cpp
+
+isf_wsc_efl_CXXFLAGS = @EFL_CFLAGS@ @VCONF_CFLAGS@ @DLOG_CFLAGS@ @TTS_CFLAGS@ @FEEDBACK_CFLAGS@
+
+isf_wsc_efl_LDFLAGS  = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \
+                         @VCONF_LIBS@ \
+                         @WAYLAND_LIBS@ \
+                         @DLOG_LIBS@ \
+                         @TTS_LIBS@ \
+                         @FEEDBACK_LIBS@
+
+isf_wsc_efl_LDADD    = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la
+
diff --git a/ism/extras/efl_wsc/input-method-client-protocol.h b/ism/extras/efl_wsc/input-method-client-protocol.h
new file mode 100644 (file)
index 0000000..676b5a2
--- /dev/null
@@ -0,0 +1,446 @@
+/* 
+ * Copyright Â© 2012, 2013 Intel Corporation
+ * 
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#ifndef INPUT_METHOD_CLIENT_PROTOCOL_H
+#define INPUT_METHOD_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct wl_input_method_context;
+struct wl_input_method;
+struct wl_input_panel;
+struct wl_input_panel_surface;
+
+extern const struct wl_interface wl_input_method_context_interface;
+extern const struct wl_interface wl_input_method_interface;
+extern const struct wl_interface wl_input_panel_interface;
+extern const struct wl_interface wl_input_panel_surface_interface;
+
+/**
+ * wl_input_method_context - input method context
+ * @surrounding_text: surrounding text event
+ * @reset: (none)
+ * @content_type: (none)
+ * @invoke_action: (none)
+ * @commit_state: (none)
+ * @preferred_language: (none)
+ *
+ * Corresponds to a text model on input method side. An input method
+ * context is created on text mode activation on the input method side. It
+ * allows to receive information about the text model from the application
+ * via events. Input method contexts do not keep state after deactivation
+ * and should be destroyed after deactivation is handled.
+ *
+ * Text is generally UTF-8 encoded, indices and lengths are in bytes.
+ *
+ * Serials are used to synchronize the state between the text input and an
+ * input method. New serials are sent by the text input in the commit_state
+ * request and are used by the input method to indicate the known text
+ * input state in events like preedit_string, commit_string, and keysym.
+ * The text input can then ignore events from the input method which are
+ * based on an outdated state (for example after a reset).
+ */
+struct wl_input_method_context_listener {
+       /**
+        * surrounding_text - surrounding text event
+        * @text: (none)
+        * @cursor: (none)
+        * @anchor: (none)
+        *
+        * The plain surrounding text around the input position. Cursor
+        * is the position in bytes within the surrounding text relative to
+        * the beginning of the text. Anchor is the position in bytes of
+        * the selection anchor within the surrounding text relative to the
+        * beginning of the text. If there is no selected text anchor is
+        * the same as cursor.
+        */
+       void (*surrounding_text)(void *data,
+                                struct wl_input_method_context *wl_input_method_context,
+                                const char *text,
+                                uint32_t cursor,
+                                uint32_t anchor);
+       /**
+        * reset - (none)
+        */
+       void (*reset)(void *data,
+                     struct wl_input_method_context *wl_input_method_context);
+       /**
+        * content_type - (none)
+        * @hint: (none)
+        * @purpose: (none)
+        */
+       void (*content_type)(void *data,
+                            struct wl_input_method_context *wl_input_method_context,
+                            uint32_t hint,
+                            uint32_t purpose);
+       /**
+        * invoke_action - (none)
+        * @button: (none)
+        * @index: (none)
+        */
+       void (*invoke_action)(void *data,
+                             struct wl_input_method_context *wl_input_method_context,
+                             uint32_t button,
+                             uint32_t index);
+       /**
+        * commit_state - (none)
+        * @serial: serial of text input state
+        */
+       void (*commit_state)(void *data,
+                            struct wl_input_method_context *wl_input_method_context,
+                            uint32_t serial);
+       /**
+        * preferred_language - (none)
+        * @language: (none)
+        */
+       void (*preferred_language)(void *data,
+                                  struct wl_input_method_context *wl_input_method_context,
+                                  const char *language);
+};
+
+static inline int
+wl_input_method_context_add_listener(struct wl_input_method_context *wl_input_method_context,
+                                    const struct wl_input_method_context_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_input_method_context,
+                                    (void (**)(void)) listener, data);
+}
+
+#define WL_INPUT_METHOD_CONTEXT_DESTROY        0
+#define WL_INPUT_METHOD_CONTEXT_COMMIT_STRING  1
+#define WL_INPUT_METHOD_CONTEXT_PREEDIT_STRING 2
+#define WL_INPUT_METHOD_CONTEXT_PREEDIT_STYLING        3
+#define WL_INPUT_METHOD_CONTEXT_PREEDIT_CURSOR 4
+#define WL_INPUT_METHOD_CONTEXT_DELETE_SURROUNDING_TEXT        5
+#define WL_INPUT_METHOD_CONTEXT_CURSOR_POSITION        6
+#define WL_INPUT_METHOD_CONTEXT_MODIFIERS_MAP  7
+#define WL_INPUT_METHOD_CONTEXT_KEYSYM 8
+#define WL_INPUT_METHOD_CONTEXT_GRAB_KEYBOARD  9
+#define WL_INPUT_METHOD_CONTEXT_KEY    10
+#define WL_INPUT_METHOD_CONTEXT_MODIFIERS      11
+#define WL_INPUT_METHOD_CONTEXT_LANGUAGE       12
+#define WL_INPUT_METHOD_CONTEXT_TEXT_DIRECTION 13
+
+static inline void
+wl_input_method_context_set_user_data(struct wl_input_method_context *wl_input_method_context, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_input_method_context, user_data);
+}
+
+static inline void *
+wl_input_method_context_get_user_data(struct wl_input_method_context *wl_input_method_context)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_input_method_context);
+}
+
+static inline void
+wl_input_method_context_destroy(struct wl_input_method_context *wl_input_method_context)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_DESTROY);
+
+       wl_proxy_destroy((struct wl_proxy *) wl_input_method_context);
+}
+
+static inline void
+wl_input_method_context_commit_string(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *text)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_COMMIT_STRING, serial, text);
+}
+
+static inline void
+wl_input_method_context_preedit_string(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *text, const char *commit)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_PREEDIT_STRING, serial, text, commit);
+}
+
+static inline void
+wl_input_method_context_preedit_styling(struct wl_input_method_context *wl_input_method_context, uint32_t index, uint32_t length, uint32_t style)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_PREEDIT_STYLING, index, length, style);
+}
+
+static inline void
+wl_input_method_context_preedit_cursor(struct wl_input_method_context *wl_input_method_context, int32_t index)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_PREEDIT_CURSOR, index);
+}
+
+static inline void
+wl_input_method_context_delete_surrounding_text(struct wl_input_method_context *wl_input_method_context, int32_t index, uint32_t length)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_DELETE_SURROUNDING_TEXT, index, length);
+}
+
+static inline void
+wl_input_method_context_cursor_position(struct wl_input_method_context *wl_input_method_context, int32_t index, int32_t anchor)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_CURSOR_POSITION, index, anchor);
+}
+
+static inline void
+wl_input_method_context_modifiers_map(struct wl_input_method_context *wl_input_method_context, struct wl_array *map)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_MODIFIERS_MAP, map);
+}
+
+static inline void
+wl_input_method_context_keysym(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_KEYSYM, serial, time, sym, state, modifiers);
+}
+
+static inline struct wl_keyboard *
+wl_input_method_context_grab_keyboard(struct wl_input_method_context *wl_input_method_context)
+{
+       struct wl_proxy *keyboard;
+
+       keyboard = wl_proxy_create((struct wl_proxy *) wl_input_method_context,
+                            &wl_keyboard_interface);
+       if (!keyboard)
+               return NULL;
+
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_GRAB_KEYBOARD, keyboard);
+
+       return (struct wl_keyboard *) keyboard;
+}
+
+static inline void
+wl_input_method_context_key(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_KEY, serial, time, key, state);
+}
+
+static inline void
+wl_input_method_context_modifiers(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_MODIFIERS, serial, mods_depressed, mods_latched, mods_locked, group);
+}
+
+static inline void
+wl_input_method_context_language(struct wl_input_method_context *wl_input_method_context, uint32_t serial, const char *language)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_LANGUAGE, serial, language);
+}
+
+static inline void
+wl_input_method_context_text_direction(struct wl_input_method_context *wl_input_method_context, uint32_t serial, uint32_t direction)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_method_context,
+                        WL_INPUT_METHOD_CONTEXT_TEXT_DIRECTION, serial, direction);
+}
+
+/**
+ * wl_input_method - input method
+ * @activate: activate event
+ * @deactivate: activate event
+ *
+ * An input method object is responsible to compose text in response to
+ * input from hardware or virtual keyboards. There is one input method
+ * object per seat. On activate there is a new input method context object
+ * created which allows the input method to communicate with the text
+ * model.
+ */
+struct wl_input_method_listener {
+       /**
+        * activate - activate event
+        * @id: (none)
+        *
+        * A text model was activated. Creates an input method context
+        * object which allows communication with the text model.
+        */
+       void (*activate)(void *data,
+                        struct wl_input_method *wl_input_method,
+                        struct wl_input_method_context *id);
+       /**
+        * deactivate - activate event
+        * @context: (none)
+        *
+        * The text model corresponding to the context argument was
+        * deactivated. The input method context should be destroyed after
+        * deactivation is handled.
+        */
+       void (*deactivate)(void *data,
+                          struct wl_input_method *wl_input_method,
+                          struct wl_input_method_context *context);
+};
+
+static inline int
+wl_input_method_add_listener(struct wl_input_method *wl_input_method,
+                            const struct wl_input_method_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_input_method,
+                                    (void (**)(void)) listener, data);
+}
+
+static inline void
+wl_input_method_set_user_data(struct wl_input_method *wl_input_method, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_input_method, user_data);
+}
+
+static inline void *
+wl_input_method_get_user_data(struct wl_input_method *wl_input_method)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_input_method);
+}
+
+static inline void
+wl_input_method_destroy(struct wl_input_method *wl_input_method)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_input_method);
+}
+
+#define WL_INPUT_PANEL_GET_INPUT_PANEL_SURFACE 0
+
+static inline void
+wl_input_panel_set_user_data(struct wl_input_panel *wl_input_panel, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_input_panel, user_data);
+}
+
+static inline void *
+wl_input_panel_get_user_data(struct wl_input_panel *wl_input_panel)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_input_panel);
+}
+
+static inline void
+wl_input_panel_destroy(struct wl_input_panel *wl_input_panel)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_input_panel);
+}
+
+static inline struct wl_input_panel_surface *
+wl_input_panel_get_input_panel_surface(struct wl_input_panel *wl_input_panel, struct wl_surface *surface)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_create((struct wl_proxy *) wl_input_panel,
+                            &wl_input_panel_surface_interface);
+       if (!id)
+               return NULL;
+
+       wl_proxy_marshal((struct wl_proxy *) wl_input_panel,
+                        WL_INPUT_PANEL_GET_INPUT_PANEL_SURFACE, id, surface);
+
+       return (struct wl_input_panel_surface *) id;
+}
+
+#ifndef WL_INPUT_PANEL_SURFACE_POSITION_ENUM
+#define WL_INPUT_PANEL_SURFACE_POSITION_ENUM
+enum wl_input_panel_surface_position {
+       WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM = 0,
+};
+#endif /* WL_INPUT_PANEL_SURFACE_POSITION_ENUM */
+
+struct wl_input_panel_surface_listener {
+       /**
+        * cursor_rectangle - cursor rectangle
+        * @x: (none)
+        * @y: (none)
+        * @width: (none)
+        * @height: (none)
+        *
+        * Notify when the cursor rectangle relative to the input panel
+        * surface change.
+        */
+       void (*cursor_rectangle)(void *data,
+                                struct wl_input_panel_surface *wl_input_panel_surface,
+                                int32_t x,
+                                int32_t y,
+                                int32_t width,
+                                int32_t height);
+};
+
+static inline int
+wl_input_panel_surface_add_listener(struct wl_input_panel_surface *wl_input_panel_surface,
+                                   const struct wl_input_panel_surface_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_input_panel_surface,
+                                    (void (**)(void)) listener, data);
+}
+
+#define WL_INPUT_PANEL_SURFACE_SET_TOPLEVEL    0
+#define WL_INPUT_PANEL_SURFACE_SET_OVERLAY_PANEL       1
+
+static inline void
+wl_input_panel_surface_set_user_data(struct wl_input_panel_surface *wl_input_panel_surface, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_input_panel_surface, user_data);
+}
+
+static inline void *
+wl_input_panel_surface_get_user_data(struct wl_input_panel_surface *wl_input_panel_surface)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_input_panel_surface);
+}
+
+static inline void
+wl_input_panel_surface_destroy(struct wl_input_panel_surface *wl_input_panel_surface)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_input_panel_surface);
+}
+
+static inline void
+wl_input_panel_surface_set_toplevel(struct wl_input_panel_surface *wl_input_panel_surface, struct wl_output *output, uint32_t position)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_panel_surface,
+                        WL_INPUT_PANEL_SURFACE_SET_TOPLEVEL, output, position);
+}
+
+static inline void
+wl_input_panel_surface_set_overlay_panel(struct wl_input_panel_surface *wl_input_panel_surface)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_input_panel_surface,
+                        WL_INPUT_PANEL_SURFACE_SET_OVERLAY_PANEL);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/ism/extras/efl_wsc/input-method-protocol.c b/ism/extras/efl_wsc/input-method-protocol.c
new file mode 100644 (file)
index 0000000..771af97
--- /dev/null
@@ -0,0 +1,117 @@
+/* 
+ * Copyright Â© 2012, 2013 Intel Corporation
+ * 
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+extern const struct wl_interface wl_keyboard_interface;
+extern const struct wl_interface wl_input_method_context_interface;
+extern const struct wl_interface wl_input_method_context_interface;
+extern const struct wl_interface wl_input_panel_surface_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_output_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_keyboard_interface,
+       &wl_input_method_context_interface,
+       &wl_input_method_context_interface,
+       &wl_input_panel_surface_interface,
+       &wl_surface_interface,
+       &wl_output_interface,
+       NULL,
+};
+
+static const struct wl_message wl_input_method_context_requests[] = {
+       { "destroy", "", types + 0 },
+       { "commit_string", "us", types + 0 },
+       { "preedit_string", "uss", types + 0 },
+       { "preedit_styling", "uuu", types + 0 },
+       { "preedit_cursor", "i", types + 0 },
+       { "delete_surrounding_text", "iu", types + 0 },
+       { "cursor_position", "ii", types + 0 },
+       { "modifiers_map", "a", types + 0 },
+       { "keysym", "uuuuu", types + 0 },
+       { "grab_keyboard", "n", types + 5 },
+       { "key", "uuuu", types + 0 },
+       { "modifiers", "uuuuu", types + 0 },
+       { "language", "us", types + 0 },
+       { "text_direction", "uu", types + 0 },
+};
+
+static const struct wl_message wl_input_method_context_events[] = {
+       { "surrounding_text", "suu", types + 0 },
+       { "reset", "", types + 0 },
+       { "content_type", "uu", types + 0 },
+       { "invoke_action", "uu", types + 0 },
+       { "commit_state", "u", types + 0 },
+       { "preferred_language", "s", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_method_context_interface = {
+       "wl_input_method_context", 1,
+       14, wl_input_method_context_requests,
+       6, wl_input_method_context_events,
+};
+
+static const struct wl_message wl_input_method_events[] = {
+       { "activate", "n", types + 6 },
+       { "deactivate", "o", types + 7 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_method_interface = {
+       "wl_input_method", 1,
+       0, NULL,
+       2, wl_input_method_events,
+};
+
+static const struct wl_message wl_input_panel_requests[] = {
+       { "get_input_panel_surface", "no", types + 8 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_panel_interface = {
+       "wl_input_panel", 1,
+       1, wl_input_panel_requests,
+       0, NULL,
+};
+
+static const struct wl_message wl_input_panel_surface_requests[] = {
+       { "set_toplevel", "ou", types + 10 },
+       { "set_overlay_panel", "", types + 0 },
+};
+
+static const struct wl_message wl_input_panel_surface_events[] = {
+       { "cursor_rectangle", "iiii", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = {
+       "wl_input_panel_surface", 1,
+       2, wl_input_panel_surface_requests,
+       1, wl_input_panel_surface_events,
+};
diff --git a/ism/extras/efl_wsc/isf_wsc_context.cpp b/ism/extras/efl_wsc/isf_wsc_context.cpp
new file mode 100644 (file)
index 0000000..13c223b
--- /dev/null
@@ -0,0 +1,2949 @@
+/*
+ * Copyright Â© 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define Uses_SCIM_BACKEND
+#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_HELPER_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 <pthread.h>
+#include <langinfo.h>
+#include <unistd.h>
+
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Wayland.h>
+#include <glib.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "scim_private.h"
+#include "scim.h"
+#include "isf_wsc_context.h"
+#include "isf_wsc_control_ui.h"
+
+#define ENABLE_BACKKEY 1
+
+using namespace scim;
+
+struct _WSCContextISFImpl {
+    WSCContextISF           *parent;
+    IMEngineInstancePointer  si;
+    Ecore_Wl_Window         *client_window;
+    Evas                    *client_canvas;
+    Ecore_IMF_Input_Mode     input_mode;
+    WideString               preedit_string;
+    AttributeList            preedit_attrlist;
+    Ecore_IMF_Autocapital_Type autocapital_type;
+    void                    *imdata;
+    int                      imdata_size;
+    int                      preedit_caret;
+    int                      cursor_x;
+    int                      cursor_y;
+    int                      cursor_top_y;
+    int                      cursor_pos;
+    bool                     use_preedit;
+    bool                     is_on;
+    bool                     shared_si;
+    bool                     preedit_started;
+    bool                     preedit_updating;
+    bool                     need_commit_preedit;
+    bool                     prediction_allow;
+    int                      next_shift_status;
+    int                      shift_mode_enabled;
+
+    WSCContextISFImpl        *next;
+};
+
+/* private functions */
+static void     panel_slot_reload_config                (int                     context);
+static void     panel_slot_exit                         (int                     context);
+static void     panel_slot_update_candidate_item_layout (int                     context,
+                                                         const std::vector<uint32> &row_items);
+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_update_preedit_caret         (int                     context,
+                                                         int                     caret);
+static void     panel_slot_select_aux                   (int                     context,
+                                                         int                     aux_index);
+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_slot_reset_keyboard_ise           (int                     context);
+static void     panel_slot_update_keyboard_ise          (int                     context);
+static void     panel_slot_show_preedit_string          (int                     context);
+static void     panel_slot_hide_preedit_string          (int                     context);
+static void     panel_slot_update_preedit_string        (int                     context,
+                                                         const WideString       &str,
+                                                         const AttributeList    &attrs,
+                                                         int               caret);
+static void     panel_slot_get_surrounding_text         (int                     context,
+                                                         int                     maxlen_before,
+                                                         int                     maxlen_after);
+static void     panel_slot_delete_surrounding_text      (int                     context,
+                                                         int                     offset,
+                                                         int                     len);
+
+static void     panel_req_focus_in                      (WSCContextISF     *ic);
+static void     panel_req_update_factory_info           (WSCContextISF     *ic);
+static void     panel_req_update_spot_location          (WSCContextISF     *ic);
+static void     panel_req_update_cursor_position        (WSCContextISF     *ic, int cursor_pos);
+static void     panel_req_show_help                     (WSCContextISF     *ic);
+static void     panel_req_show_factory_menu             (WSCContextISF     *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                          (WSCContextISF     *ic,
+                                                         const KeyEvent         &key);
+static void     turn_on_ic                              (WSCContextISF     *ic);
+static void     turn_off_ic                             (WSCContextISF     *ic);
+static void     set_ic_capabilities                     (WSCContextISF     *ic);
+
+static void     initialize                              (void);
+static void     finalize                                (void);
+
+static void     open_next_factory                       (WSCContextISF     *ic);
+static void     open_previous_factory                   (WSCContextISF     *ic);
+static void     open_specific_factory                   (WSCContextISF     *ic,
+                                                         const String           &uuid);
+static void     send_wl_key_event                       (WSCContextISF *ic, const KeyEvent &key, bool fake);
+static void     _hide_preedit_string                    (int context, bool update_preedit);
+
+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,
+                                                         int               caret);
+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     slot_expand_candidate                   (IMEngineInstanceBase   *si);
+static void     slot_contract_candidate                 (IMEngineInstanceBase   *si);
+
+static void     slot_set_candidate_style                (IMEngineInstanceBase   *si,
+                                                         ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line,
+                                                         ISF_CANDIDATE_MODE_T    mode);
+
+static void     reload_config_callback                  (const ConfigPointer    &config);
+
+static void     fallback_commit_string_cb               (IMEngineInstanceBase   *si,
+                                                         const WideString       &str);
+static void     _display_input_language                 (WSCContextISF *ic);
+
+/* Local variables declaration */
+static String                                           _language;
+static WSCContextISFImpl                               *_used_ic_impl_list          = 0;
+static WSCContextISFImpl                               *_free_ic_impl_list          = 0;
+static WSCContextISF                                   *_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 ConfigPointer                                    _config;
+static Connection                                       _config_connection;
+static BackEndPointer                                   _backend;
+
+static WSCContextISF                                   *_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;
+PanelClient                                             _panel_client;
+static int                                              _panel_client_id            = 0;
+
+static Ecore_Fd_Handler                                *_panel_iochannel_read_handler = 0;
+static Ecore_Fd_Handler                                *_panel_iochannel_err_handler  = 0;
+
+static Ecore_Wl_Window                                 *_client_window              = 0;
+static Ecore_Event_Handler                             *_key_down_handler           = 0;
+static Ecore_Event_Handler                             *_key_up_handler             = 0;
+
+static bool                                             _on_the_spot                = true;
+static bool                                             _shared_input_method        = false;
+static double                                           space_key_time              = 0.0;
+
+static Eina_Bool                                        autoperiod_allow            = EINA_FALSE;
+static Eina_Bool                                        autocap_allow               = EINA_FALSE;
+static Eina_Bool                                        desktop_mode                = EINA_FALSE;
+
+static bool                                             _x_key_event_is_valid       = false;
+
+typedef enum {
+    INPUT_LANG_JAPANESE,
+    INPUT_LANG_OTHER
+} Input_Language;
+
+static Input_Language                                   input_lang                  = INPUT_LANG_OTHER;
+
+#define SHIFT_MODE_OFF  0xffe1
+#define SHIFT_MODE_ON   0xffe2
+#define SHIFT_MODE_LOCK 0xffe6
+#define SHIFT_MODE_ENABLE 0x9fe7
+#define SHIFT_MODE_DISABLE 0x9fe8
+
+EAPI WSCContextISF *
+get_focused_ic ()
+{
+    return _focused_ic;
+}
+
+EAPI int
+get_panel_client_id (void)
+{
+    return _panel_client_id;
+}
+
+EAPI Eina_Bool
+get_desktop_mode ()
+{
+    return desktop_mode;
+}
+
+EAPI void
+get_language(char **language)
+{
+    *language = strdup(_language.c_str());
+}
+
+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 WSCContextISFImpl *
+new_ic_impl (WSCContextISF *parent)
+{
+    WSCContextISFImpl *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 WSCContextISFImpl;
+        if (impl == NULL)
+            return NULL;
+    }
+
+    impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
+    impl->next_shift_status = 0;
+    impl->shift_mode_enabled = 1;
+    impl->next = _used_ic_impl_list;
+    _used_ic_impl_list = impl;
+
+    impl->parent = parent;
+    impl->imdata = NULL;
+    impl->imdata_size = 0;
+
+    return impl;
+}
+
+static void
+delete_ic_impl (WSCContextISFImpl *impl)
+{
+    WSCContextISFImpl *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;
+
+            if (rec->imdata) {
+                free (rec->imdata);
+                rec->imdata = NULL;
+            }
+
+            rec->imdata_size = 0;
+            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)
+{
+    WSCContextISFImpl *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 WSCContextISF *
+find_ic (int id)
+{
+    WSCContextISFImpl *rec = _used_ic_impl_list;
+
+    while (rec != 0) {
+        if (rec->parent && rec->parent->id == id)
+            return rec->parent;
+        rec = rec->next;
+    }
+
+    return 0;
+}
+
+static bool
+check_valid_ic (WSCContextISF * ic)
+{
+    if (ic && ic->impl && ic->ctx)
+        return true;
+    else
+        return false;
+}
+
+static void
+set_prediction_allow (WSCContextISF *ctx, bool prediction)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (context_scim && context_scim->impl && context_scim == _focused_ic) {
+        _panel_client.prepare (context_scim->id);
+        context_scim->impl->si->set_prediction_allow (prediction);
+        _panel_client.send ();
+    }
+}
+
+static Eina_Bool
+check_symbol (Eina_Unicode ucode, Eina_Unicode symbols[], int symbol_num)
+{
+    for (int i = 0; i < symbol_num; i++) {
+        // Check symbol
+        if (ucode == symbols[i])
+            return EINA_TRUE;
+    }
+
+    return EINA_FALSE;
+}
+
+static void
+autoperiod_insert (WSCContextISF *ctx)
+{
+    char *plain_str = NULL;
+    char *markup_str = NULL;
+    int cursor_pos = 0;
+    Eina_Unicode *ustr = NULL;
+    Eina_Unicode space_symbols[] = {' ', 0x00A0 /* no-break space */, 0x3000 /* ideographic space */};
+    Eina_Unicode symbols[] = {' ', 0x00A0 /* no-break space */, 0x3000 /* ideographic space */,
+                              ':', ';', '.', '!', '?', 0x00BF /* Â¿ */, 0x00A1 /* Â¡ */, 0x3002 /* ã€‚ */};
+    const int symbol_num = sizeof (symbols) / sizeof (symbols[0]);
+    char *fullstop_mark = NULL;
+
+    if (autoperiod_allow == EINA_FALSE)
+        return;
+
+    if (!ctx) return;
+
+    Ecore_IMF_Input_Panel_Layout layout = wsc_context_input_panel_layout_get (ctx->ctx);
+    if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL)
+        return;
+
+    if ((ecore_time_get () - space_key_time) > DOUBLE_SPACE_INTERVAL)
+        goto done;
+
+    wsc_context_surrounding_get (ctx->ctx, &markup_str, &cursor_pos);
+    if (!markup_str) 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 < 2) goto done;
+
+    if (check_symbol (ustr[cursor_pos-1], space_symbols, (sizeof (space_symbols) / sizeof (space_symbols[0]))) &&
+        (!check_symbol (ustr[cursor_pos-2], symbols, symbol_num))) {
+        wsc_context_delete_surrounding(ctx->ctx, -1, 1);
+
+        if (input_lang == INPUT_LANG_JAPANESE) {
+            fullstop_mark = strdup ("。");
+        }
+        else {
+            fullstop_mark = strdup (".");
+        }
+
+        wsc_context_commit_string(ctx->ctx, fullstop_mark);
+
+        if (fullstop_mark) {
+            free (fullstop_mark);
+        }
+    }
+
+done:
+    if (markup_str) free (markup_str);
+    if (plain_str) free (plain_str);
+    if (ustr) free (ustr);
+    space_key_time = ecore_time_get ();
+}
+
+static Eina_Bool
+analyze_surrounding_text (WSCContextISF *ctx)
+{
+    char *plain_str = NULL;
+    char *markup_str = NULL;
+    Eina_Unicode puncs[] = {'\n','.', '!', '?', 0x00BF /* Â¿ */, 0x00A1 /* Â¡ */, 0x3002 /* ã€‚ */};
+    Eina_Unicode space_symbols[] = {' ', 0x00A0 /* no-break space */, 0x3000 /* ideographic space */};
+    Eina_Unicode *ustr = NULL;
+    Eina_Bool ret = EINA_FALSE;
+    Eina_Bool detect_space = EINA_FALSE;
+    int cursor_pos = 0;
+    int i = 0;
+    const int punc_num = sizeof (puncs) / sizeof (puncs[0]);
+    WSCContextISF *context_scim;
+
+    if (!ctx) return EINA_FALSE;
+    context_scim = 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;
+    }
+
+    if (context_scim->impl->cursor_pos == 0)
+        return EINA_TRUE;
+
+    wsc_context_surrounding_get (ctx->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 (eina_unicode_strlen (ustr) < (size_t)cursor_pos) goto done;
+
+    if (cursor_pos >= 1) {
+        if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD) {
+            // Check space or no-break space
+            if (check_symbol (ustr[cursor_pos-1], space_symbols, (sizeof (space_symbols) / sizeof (space_symbols[0])))) {
+                ret = EINA_TRUE;
+                goto done;
+            }
+        }
+
+        // Check paragraph separator <PS> or carriage return  <br>
+        if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n')) {
+            ret = EINA_TRUE;
+            goto done;
+        }
+
+        for (i = cursor_pos; i > 0; i--) {
+            // Check space or no-break space
+            if (check_symbol (ustr[i-1], space_symbols, (sizeof (space_symbols) / sizeof (space_symbols[0])))) {
+                detect_space = EINA_TRUE;
+                continue;
+            }
+
+            // Check punctuation and following the continuous space(s)
+            if (detect_space && check_symbol (ustr[i-1], puncs, punc_num)) {
+                ret = EINA_TRUE;
+                goto done;
+            }
+            else {
+                ret = EINA_FALSE;
+                goto done;
+            }
+        }
+
+        if ((i == 0) && (detect_space == EINA_TRUE)) {
+            // continuous space(s) without any character
+            ret = EINA_TRUE;
+            goto done;
+        }
+    }
+
+done:
+    if (ustr) free (ustr);
+    if (markup_str) free (markup_str);
+    if (plain_str) free (plain_str);
+
+    return ret;
+}
+
+EAPI Eina_Bool
+caps_mode_check (WSCContextISF *ctx, Eina_Bool force, Eina_Bool noti)
+{
+    Eina_Bool uppercase;
+    WSCContextISF *context_scim;
+
+    if (hw_keyboard_num_get () > 0) return EINA_FALSE;
+
+    if (!ctx) return EINA_FALSE;
+    context_scim = ctx;
+
+    if (!context_scim || !context_scim->impl)
+        return EINA_FALSE;
+
+    if (context_scim->impl->next_shift_status == SHIFT_MODE_LOCK) return EINA_TRUE;
+
+    Ecore_IMF_Input_Panel_Layout layout = wsc_context_input_panel_layout_get (ctx->ctx);
+    if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL)
+        return EINA_FALSE;
+
+    // Check autocapital type
+    if (wsc_context_input_panel_caps_lock_mode_get (ctx->ctx)) {
+        uppercase = EINA_TRUE;
+    } else {
+        if (autocap_allow == EINA_FALSE)
+            return EINA_FALSE;
+
+        if (analyze_surrounding_text (ctx)) {
+            uppercase = EINA_TRUE;
+        } else {
+            uppercase = EINA_FALSE;
+        }
+    }
+
+    if (force) {
+        context_scim->impl->next_shift_status = uppercase ? SHIFT_MODE_ON : SHIFT_MODE_OFF;
+        if (noti)
+            isf_wsc_context_input_panel_caps_mode_set (ctx, uppercase);
+    } else {
+        if (context_scim->impl->next_shift_status != (uppercase ? SHIFT_MODE_ON : SHIFT_MODE_OFF)) {
+            context_scim->impl->next_shift_status = uppercase ? SHIFT_MODE_ON : SHIFT_MODE_OFF;
+            if (noti)
+                isf_wsc_context_input_panel_caps_mode_set (ctx, uppercase);
+        }
+    }
+
+    return uppercase;
+}
+
+static void
+get_input_language ()
+{
+    char *input_lang_str = vconf_get_str (VCONFKEY_ISF_INPUT_LANGUAGE);
+    if (!input_lang_str) return;
+
+    if (strcmp (input_lang_str, "ja_JP") == 0)
+        input_lang = INPUT_LANG_JAPANESE;
+    else
+        input_lang = INPUT_LANG_OTHER;
+
+    free (input_lang_str);
+}
+
+static void autoperiod_allow_changed_cb (keynode_t *key, void* data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    autoperiod_allow = vconf_keynode_get_bool (key);
+}
+
+static void autocapital_allow_changed_cb (keynode_t *key, void* data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    autocap_allow = vconf_keynode_get_bool (key);
+}
+
+static void input_language_changed_cb (keynode_t *key, void* data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    get_input_language ();
+}
+
+EAPI void context_scim_imdata_get (WSCContextISF *ctx, void* data, int* length)
+{
+    WSCContextISF *context_scim = ctx;
+
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (context_scim && context_scim->impl) {
+        if (data && context_scim->impl->imdata)
+            memcpy (data, context_scim->impl->imdata, context_scim->impl->imdata_size);
+
+        if (length)
+            *length = context_scim->impl->imdata_size;
+    }
+}
+
+EAPI void
+imengine_layout_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Layout layout)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (context_scim && context_scim->impl && context_scim == _focused_ic) {
+        _panel_client.prepare (context_scim->id);
+        context_scim->impl->si->set_layout (layout);
+        _panel_client.send ();
+    }
+}
+
+/* Public functions */
+EAPI WSCContextISF *
+isf_wsc_context_new (void)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    int val;
+
+    WSCContextISF *context_scim = new WSCContextISF;
+    if (context_scim == NULL) {
+        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
+        return NULL;
+    }
+
+    if (_context_count == 0) {
+        _context_count = getpid () % 50000;
+    }
+    context_scim->id = _context_count++;
+
+    if (!_scim_initialized) {
+        ecore_wl_init (NULL);
+        initialize ();
+        _scim_initialized = true;
+        isf_wsc_input_panel_init ();
+        //isf_wsc_context_set_hardware_keyboard_mode(context_scim);
+
+        /* get autoperiod allow vconf value */
+        if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) {
+            if (val == EINA_TRUE)
+                autoperiod_allow = EINA_TRUE;
+        }
+
+        vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL);
+
+        /* get autocapital allow vconf value */
+        if (vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &val) == 0) {
+            if (val == EINA_TRUE)
+                autocap_allow = EINA_TRUE;
+        }
+
+        vconf_notify_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb, NULL);
+
+        /* get input language vconf value */
+        get_input_language ();
+
+        vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL);
+    }
+
+    return context_scim;
+}
+
+EAPI void
+isf_wsc_context_shutdown (void)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+    ConfigBase::set (0);
+    if (_scim_initialized) {
+        _scim_initialized = false;
+
+        vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb);
+        vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb);
+        vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb);
+
+        isf_wsc_input_panel_shutdown ();
+        finalize ();
+        ecore_wl_shutdown ();
+    }
+}
+
+EAPI void
+isf_wsc_context_add (WSCContextISF *ctx)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = 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->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->cursor_top_y        = 0;
+    context_scim->impl->is_on               = true;
+    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;
+    context_scim->impl->prediction_allow    = true;
+
+    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_wsc_context_del (WSCContextISF *ctx)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (!_ic_list) return;
+
+    WSCContextISF *context_scim = ctx;
+
+    if (context_scim) {
+        if (context_scim->id != _ic_list->id) {
+            WSCContextISF * pre = _ic_list;
+            WSCContextISF * 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.
+        // FIXME:
+        // In case the instance send out some helper event,
+        // and this context has been focused out,
+        // we need set the focused_ic to this context temporary.
+        WSCContextISF *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) {
+            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;
+    }
+}
+
+EAPI void
+isf_wsc_context_focus_in (WSCContextISF *ctx)
+{
+    WSCContextISF *context_scim = 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_wsc_context_focus_out (_focused_ic);
+    }
+
+    bool need_cap   = false;
+    bool need_reset = false;
+    bool need_reg   = false;
+
+    if (context_scim && context_scim->impl) {
+        _focused_ic = context_scim;
+
+        _panel_client.send ();
+
+        _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);
+
+        panel_req_focus_in (context_scim);
+//        panel_req_update_spot_location (context_scim);
+//        panel_req_update_factory_info (context_scim);
+
+        if (need_reset) context_scim->impl->si->reset ();
+        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 ();
+            context_scim->impl->si->set_layout (wsc_context_input_panel_layout_get (ctx->ctx));
+            context_scim->impl->si->set_prediction_allow (context_scim->impl->prediction_allow);
+            if (context_scim->impl->imdata)
+                context_scim->impl->si->set_imdata ((const char *)context_scim->impl->imdata, context_scim->impl->imdata_size);
+        } else {
+            _panel_client.turn_off (context_scim->id);
+        }
+
+        _panel_client.send ();
+        if (caps_mode_check (ctx, EINA_FALSE, EINA_TRUE) == EINA_FALSE) {
+            context_scim->impl->next_shift_status = 0;
+        }
+    }
+
+    LOGD ("ctx : %p\n", ctx);
+}
+
+EAPI void
+isf_wsc_context_focus_out (WSCContextISF *ctx)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (!context_scim) return;
+
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n";
+
+    if (context_scim && context_scim->impl && context_scim == _focused_ic) {
+
+        LOGD ("ctx : %p\n", ctx);
+
+        if (context_scim->impl->need_commit_preedit) {
+            _hide_preedit_string (context_scim->id, false);
+
+            wsc_context_commit_preedit_string(context_scim->ctx); 
+            _panel_client.prepare (context_scim->id);
+            _panel_client.reset_input_context (context_scim->id);
+            _panel_client.send ();
+        }
+
+        _panel_client.prepare (context_scim->id);
+
+        context_scim->impl->si->focus_out ();
+        context_scim->impl->si->reset ();
+        context_scim->impl->cursor_pos = -1;
+
+//          if (context_scim->impl->shared_si) context_scim->impl->si->reset ();
+
+        _panel_client.focus_out (context_scim->id);
+        _panel_client.send ();
+        _focused_ic = 0;
+    }
+    _x_key_event_is_valid = false;
+}
+
+EAPI void
+isf_wsc_context_reset (WSCContextISF *ctx)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = ctx;
+
+    if (context_scim && context_scim->impl && context_scim == _focused_ic) {
+        _panel_client.prepare (context_scim->id);
+        context_scim->impl->si->reset ();
+        _panel_client.reset_input_context (context_scim->id);
+        _panel_client.send ();
+
+        if (context_scim->impl->need_commit_preedit) {
+            _hide_preedit_string (context_scim->id, false);
+            wsc_context_commit_preedit_string(context_scim->ctx);
+        }
+    }
+}
+
+EAPI void
+isf_wsc_context_preedit_string_get (WSCContextISF *ctx, char** str, int *cursor_pos)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = 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;
+            mbs = utf8_wcstombs (
+                context_scim->impl->preedit_string.substr(0, context_scim->impl->preedit_caret));
+            *cursor_pos = mbs.length();
+        }
+    } else {
+        if (str)
+            *str = strdup ("");
+
+        if (cursor_pos)
+            *cursor_pos = 0;
+    }
+}
+
+EAPI void
+isf_wsc_context_prediction_allow_set (WSCContextISF* ctx, Eina_Bool prediction)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction == EINA_TRUE ? "true" : "false") << "...\n";
+
+    WSCContextISF *context_scim = ctx;
+
+    if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction) {
+        context_scim->impl->prediction_allow = prediction;
+        set_prediction_allow (ctx, prediction);
+    }
+}
+
+EAPI Eina_Bool
+isf_wsc_context_prediction_allow_get (WSCContextISF* ctx)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *context_scim = ctx;
+
+    Eina_Bool ret = EINA_FALSE;
+    if (context_scim && context_scim->impl) {
+        ret = context_scim->impl->prediction_allow;
+    } else {
+        std::cerr << __FUNCTION__ << " failed!!!\n";
+    }
+    return ret;
+}
+
+static void
+turn_on_ic (WSCContextISF *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 ();
+            ic->impl->si->set_layout (ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
+            ic->impl->si->set_prediction_allow (ic->impl->prediction_allow);
+        }
+
+        //Record the IC on/off status
+        if (_shared_input_method) {
+            _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true);
+            _config->flush ();
+        }
+
+        if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) {
+            if (!check_valid_ic (ic))
+                return;
+
+            if (check_valid_ic (ic))
+                ic->impl->preedit_started = true;
+        }
+    }
+}
+
+static void
+turn_off_ic (WSCContextISF *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);
+            _config->flush ();
+        }
+
+        if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) {
+            if (!check_valid_ic (ic))
+                return;
+
+            if (check_valid_ic (ic))
+                ic->impl->preedit_started = false;
+        }
+    }
+}
+
+static void
+set_ic_capabilities (WSCContextISF *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;
+}
+
+/* Panel Requestion functions. */
+static void
+panel_req_show_help (WSCContextISF *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 (WSCContextISF *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 (WSCContextISF *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"), String (SCIM_KEYBOARD_ICON_FILE));
+        }
+        _panel_client.update_factory_info (ic->id, info);
+    }
+}
+
+static void
+panel_req_focus_in (WSCContextISF *ic)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (ic && ic->impl && ic->impl->si)
+        _panel_client.focus_in (ic->id, ic->impl->si->get_factory_uuid ());
+}
+
+static void
+panel_req_update_spot_location (WSCContextISF *ic)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (ic && ic->impl)
+        _panel_client.update_spot_location (ic->id, ic->impl->cursor_x, ic->impl->cursor_y, ic->impl->cursor_top_y);
+}
+
+static void
+panel_req_update_cursor_position (WSCContextISF *ic, int cursor_pos)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (ic)
+        _panel_client.update_cursor_position (ic->id, cursor_pos);
+}
+
+static bool
+filter_hotkeys (WSCContextISF *ic, const KeyEvent &key)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    bool ret = false;
+
+    if (!check_valid_ic (ic))
+        return ret;
+
+    _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) {
+        IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ());
+        if (sf && (sf->get_option () & SCIM_IME_SUPPORT_LANGUAGE_TOGGLE_KEY)) {
+            ret = false;
+        } else {
+            if (!ic->impl->is_on) {
+                turn_on_ic (ic);
+            } else {
+                turn_off_ic (ic);
+                _panel_client.hide_aux_string (ic->id);
+                _panel_client.hide_lookup_table (ic->id);
+            }
+
+            _display_input_language (ic);
+            ret = true;
+        }
+    } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) {
+        if (!ic->impl->is_on) {
+            turn_on_ic (ic);
+            _display_input_language (ic);
+        }
+        ret = true;
+    } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) {
+        if (ic->impl->is_on) {
+            turn_off_ic (ic);
+            _display_input_language (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 ()) {
+        ISEInfo info = _imengine_hotkey_matcher.get_match_result ();
+        ISE_TYPE type = info.type;
+        if (type == IMENGINE_T)
+            open_specific_factory (ic, info.uuid);
+        else if (type == HELPER_T)
+            _panel_client.start_helper (ic->id, info.uuid);
+        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) {
+        if (_panel_client.get_client_id (_panel_client_id)) {
+            _panel_client.prepare (0);
+            _panel_client.register_client (_panel_client_id);
+            _panel_client.send ();
+        }
+
+        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);
+//        _panel_iochannel_err_handler  = ecore_main_fd_handler_add (fd, ECORE_FD_ERROR, panel_iochannel_handler, NULL, NULL, NULL);
+
+        SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n";
+
+        WSCContextISF *context_scim = _ic_list;
+        while (context_scim != NULL) {
+            if (context_scim->impl && context_scim->impl->si) {
+                _panel_client.prepare (context_scim->id);
+                _panel_client.register_input_context (context_scim->id, context_scim->impl->si->get_factory_uuid ());
+                _panel_client.send ();
+            }
+            context_scim = context_scim->next;
+        }
+
+        if (_focused_ic) {
+            _focused_ic = 0;
+        }
+
+        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, Ecore_Fd_Handler *fd_handler)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (fd_handler == _panel_iochannel_read_handler) {
+        if (_panel_client.has_pending_event () && !_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;
+}
+
+/* Panel Slot functions */
+static void
+panel_slot_reload_config (int context)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+}
+
+static void
+panel_slot_exit (int /* context */)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    finalize ();
+}
+
+static void
+panel_slot_update_candidate_item_layout (int context, const std::vector<uint32> &row_items)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " row size=" << row_items.size () << " ic=" << ic << "\n";
+    if (ic && ic->impl) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->update_candidate_item_layout (row_items);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_update_lookup_table_page_size (int context, int page_size)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid
+                           << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic != NULL ? 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)
+{
+    WSCContextISF *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_update_preedit_caret (int context, int caret)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n";
+
+    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) {
+                if (check_valid_ic (ic))
+                    ic->impl->preedit_started = true;
+            }
+        } else {
+            _panel_client.prepare (ic->id);
+            _panel_client.update_preedit_caret (ic->id, caret);
+            _panel_client.send ();
+        }
+    }
+}
+
+static void
+panel_slot_select_aux (int context, int aux_index)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " aux=" << aux_index << " ic=" << ic << "\n";
+    if (ic && ic->impl) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->select_aux (aux_index);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_select_candidate (int context, int cand_index)
+{
+    WSCContextISF *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 Eina_Bool
+feed_key_event (WSCContextISF *ic, const KeyEvent &key, bool fake)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    if (key.code <= 0x7F ||
+        (key.code >= SCIM_KEY_BackSpace && key.code <= SCIM_KEY_Delete) ||
+        (key.code >= SCIM_KEY_Home && key.code <= SCIM_KEY_Hyper_R)) {
+        // ascii code and function keys
+        send_wl_key_event(ic, key, fake);
+        return EINA_TRUE;
+    } else {
+        return EINA_FALSE;
+    }
+}
+
+static void
+panel_slot_process_key_event (int context, const KeyEvent &key)
+{
+    WSCContextISF *ic = find_ic (context);
+    Eina_Bool process_key = EINA_TRUE;
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
+
+    if (!(ic && ic->impl))
+        return;
+
+    if ((_focused_ic != NULL) && (_focused_ic != ic))
+        return;
+
+    KeyEvent _key = key;
+    if (key.is_key_press () &&
+        wsc_context_input_panel_layout_get (ic->ctx) == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL) {
+        if (key.code == SHIFT_MODE_OFF ||
+            key.code == SHIFT_MODE_ON ||
+            key.code == SHIFT_MODE_LOCK) {
+            ic->impl->next_shift_status = _key.code;
+        } else if (key.code == SHIFT_MODE_ENABLE ) {
+            ic->impl->shift_mode_enabled = true;
+            caps_mode_check (ic, EINA_TRUE, EINA_TRUE);
+        } else if (key.code == SHIFT_MODE_DISABLE ) {
+            ic->impl->shift_mode_enabled = false;
+        }
+    }
+
+    if (key.code != SHIFT_MODE_OFF &&
+        key.code != SHIFT_MODE_ON &&
+        key.code != SHIFT_MODE_LOCK &&
+        key.code != SHIFT_MODE_ENABLE &&
+        key.code != SHIFT_MODE_DISABLE) {
+        if (ic->impl->preedit_string.length() < 1) {
+            if (!((key.code >= 'a' && key.code <= 'z') ||
+                (key.code >= 'A' && key.code <= 'Z'))) {
+                if (feed_key_event (ic, _key, false)) return;
+            }
+        }
+    }
+
+    if (key.code == SHIFT_MODE_ENABLE ||
+        key.code == SHIFT_MODE_DISABLE) {
+        process_key = EINA_FALSE;
+    }
+
+    _panel_client.prepare (ic->id);
+
+    if (!filter_hotkeys (ic, _key)) {
+        if (process_key) {
+            if (!_focused_ic || !_focused_ic->impl->is_on ||
+                    !_focused_ic->impl->si->process_key_event (_key)) {
+                _fallback_instance->process_key_event (_key);
+            }
+        }
+    }
+
+    _panel_client.send ();
+}
+
+static void
+panel_slot_commit_string (int context, const WideString &wstr)
+{
+    WSCContextISF *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;
+
+        if (utf8_wcstombs (wstr) == String (" ") || utf8_wcstombs (wstr) == String (" "))
+            autoperiod_insert (ic);
+
+        if (ic->impl->need_commit_preedit)
+            _hide_preedit_string (ic->id, false);
+        wsc_context_commit_string (ic->ctx, utf8_wcstombs (wstr).c_str ());
+    }
+}
+
+static void
+panel_slot_forward_key_event (int context, const KeyEvent &key)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
+
+    if (!(ic && ic->impl))
+        return;
+
+    if ((_focused_ic != NULL) && (_focused_ic != ic))
+        return;
+
+    if (strlen (key.get_key_string ().c_str ()) >= 116)
+        return;
+
+    feed_key_event (ic, key, true);
+}
+
+static void
+panel_slot_request_help (int context)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *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)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n";
+    if (ic && ic->impl) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->reset ();
+        open_specific_factory (ic, uuid);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_reset_keyboard_ise (int context)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+    if (ic && ic->impl) {
+        WideString wstr = ic->impl->preedit_string;
+        if (ic->impl->need_commit_preedit) {
+            _hide_preedit_string (ic->id, false);
+
+            if (wstr.length ()) {
+                wsc_context_commit_string (ic->ctx, utf8_wcstombs (wstr).c_str ());
+                if (!check_valid_ic (ic))
+                    return;
+            }
+        }
+        _panel_client.prepare (ic->id);
+        ic->impl->si->reset ();
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_update_keyboard_ise (int context)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+
+    _backend->add_module (_config, "socket", false);
+}
+
+static void
+panel_slot_show_preedit_string (int context)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << "\n";
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        if (!ic->impl->is_on)
+            ic->impl->is_on = true;
+
+        if (ic->impl->use_preedit) {
+            if (!ic->impl->preedit_started) {
+                if (check_valid_ic (ic)) {
+                    ic->impl->preedit_started     = true;
+                    ic->impl->need_commit_preedit = true;
+                }
+            }
+        } else {
+            _panel_client.prepare (ic->id);
+            _panel_client.show_preedit_string (ic->id);
+            _panel_client.send ();
+        }
+    }
+}
+
+static void
+_hide_preedit_string (int context, bool update_preedit)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = find_ic (context);
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        if (!ic->impl->is_on)
+            ic->impl->is_on = true;
+
+        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 (update_preedit && emit) {
+                if (!check_valid_ic (ic))
+                    return;
+            }
+            if (ic->impl->preedit_started) {
+                if (check_valid_ic (ic)) {
+                    ic->impl->preedit_started     = false;
+                    ic->impl->need_commit_preedit = false;
+                }
+            }
+            wsc_context_send_preedit_string(ic->ctx);
+        } else {
+            _panel_client.prepare (ic->id);
+            _panel_client.hide_preedit_string (ic->id);
+            _panel_client.send ();
+        }
+    }
+}
+
+static void
+panel_slot_hide_preedit_string (int context)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    _hide_preedit_string (context, true);
+}
+
+static void
+panel_slot_update_preedit_string (int context,
+                                  const WideString    &str,
+                                  const AttributeList &attrs,
+                                  int caret)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = find_ic (context);
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        if (!ic->impl->is_on)
+            ic->impl->is_on = true;
+
+        if (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) {
+                    if (!check_valid_ic (ic))
+                        return;
+
+                    ic->impl->preedit_started = true;
+                    ic->impl->need_commit_preedit = true;
+                }
+                if (caret >= 0 && caret <= (int)str.length ())
+                    ic->impl->preedit_caret    = caret;
+                else
+                    ic->impl->preedit_caret    = str.length ();
+                ic->impl->preedit_updating = true;
+                if (check_valid_ic (ic))
+                    ic->impl->preedit_updating = false;
+                wsc_context_send_preedit_string(ic->ctx);
+            } else {
+                _panel_client.prepare (ic->id);
+                _panel_client.update_preedit_string (ic->id, str, attrs, caret);
+                _panel_client.send ();
+            }
+        }
+    }
+}
+
+static void
+panel_slot_get_surrounding_text (int context, int maxlen_before, int maxlen_after)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = find_ic (context);
+
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si) {
+        int cursor = 0;
+        WideString text = WideString ();
+        slot_get_surrounding_text (ic->impl->si, text, cursor, maxlen_before, maxlen_after);
+        _panel_client.prepare (ic->id);
+        _panel_client.update_surrounding_text (ic->id, text, cursor);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_delete_surrounding_text (int context, int offset, int len)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = find_ic (context);
+
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si)
+        slot_delete_surrounding_text (ic->impl->si, offset, len);
+}
+
+static void
+panel_slot_update_displayed_candidate_number (int context, int number)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " number=" << number << " ic=" << ic << "\n";
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->update_displayed_candidate_number (number);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_candidate_more_window_show (int context)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->candidate_more_window_show ();
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_candidate_more_window_hide (int context)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n";
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->candidate_more_window_hide ();
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_longpress_candidate (int context, int index)
+{
+    WSCContextISF *ic = find_ic (context);
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " index=" << index << " ic=" << ic << "\n";
+    if (ic && ic->impl && _focused_ic == ic && ic->impl->si) {
+        _panel_client.prepare (ic->id);
+        ic->impl->si->longpress_candidate (index);
+        _panel_client.send ();
+    }
+}
+
+static void
+panel_slot_update_ise_input_context (int context, int type, int value)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+}
+
+static void
+panel_slot_update_isf_candidate_panel (int context, int type, int value)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+}
+
+void
+initialize (void)
+{
+    std::vector<String>     config_list;
+    std::vector<String>     engine_list;
+    std::vector<String>     helper_list;
+    std::vector<String>     load_engine_list;
+
+    std::vector<String>::iterator it;
+
+    bool                    manual = false;
+    bool                    socket = true;
+    String                  config_module_name = "simple";
+
+    LOGD ("Initializing Ecore ISF 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 ISF daemon with Socket FrontEnd...\n";
+            //get modules list
+            scim_get_imengine_module_list (engine_list);
+            scim_get_helper_module_list (helper_list);
+
+            for (it = engine_list.begin (); it != engine_list.end (); it++) {
+                if (*it != "socket")
+                    load_engine_list.push_back (*it);
+            }
+            for (it = helper_list.begin (); it != helper_list.end (); it++)
+                load_engine_list.push_back (*it);
+            const char *new_argv [] = { "--no-stay", 0 };
+            scim_launch (true,
+                         config_module_name,
+                         (load_engine_list.size () > 0 ? 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") {
+        _config = ConfigBase::get (true, config_module_name);
+    }
+
+    if (_config.null ()) {
+        LOGD ("Config module cannot be loaded, using dummy Config.\n");
+        _config = new DummyConfig ();
+        config_module_name = "dummy";
+    }
+
+    reload_config_callback (_config);
+    _config_connection = _config->signal_connect_reload (slot (reload_config_callback));
+
+    // create backend
+    _backend = new CommonBackEnd (_config, load_engine_list.size () > 0 ? load_engine_list : engine_list);
+
+    if (_backend.null ()) {
+        std::cerr << "Cannot create BackEnd Object!\n";
+    } else {
+        _backend->initialize (_config, load_engine_list.size () > 0 ? load_engine_list : engine_list, false, false);
+        _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_candidate_item_layout  (slot (panel_slot_update_candidate_item_layout));
+    _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_update_preedit_caret          (slot (panel_slot_update_preedit_caret));
+    _panel_client.signal_connect_select_aux                    (slot (panel_slot_select_aux));
+    _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));
+    _panel_client.signal_connect_reset_keyboard_ise            (slot (panel_slot_reset_keyboard_ise));
+    _panel_client.signal_connect_update_keyboard_ise           (slot (panel_slot_update_keyboard_ise));
+    _panel_client.signal_connect_show_preedit_string           (slot (panel_slot_show_preedit_string));
+    _panel_client.signal_connect_hide_preedit_string           (slot (panel_slot_hide_preedit_string));
+    _panel_client.signal_connect_update_preedit_string         (slot (panel_slot_update_preedit_string));
+    _panel_client.signal_connect_get_surrounding_text          (slot (panel_slot_get_surrounding_text));
+    _panel_client.signal_connect_delete_surrounding_text       (slot (panel_slot_delete_surrounding_text));
+    _panel_client.signal_connect_update_displayed_candidate_number (slot (panel_slot_update_displayed_candidate_number));
+    _panel_client.signal_connect_candidate_more_window_show    (slot (panel_slot_candidate_more_window_show));
+    _panel_client.signal_connect_candidate_more_window_hide    (slot (panel_slot_candidate_more_window_hide));
+    _panel_client.signal_connect_longpress_candidate           (slot (panel_slot_longpress_candidate));
+    _panel_client.signal_connect_update_ise_input_context      (slot (panel_slot_update_ise_input_context));
+    _panel_client.signal_connect_update_isf_candidate_panel    (slot (panel_slot_update_isf_candidate_panel));
+
+    if (!panel_initialize ()) {
+        std::cerr << "Ecore IM Module: Cannot connect to Panel!\n";
+    }
+}
+
+static void
+finalize (void)
+{
+    LOGD ("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_wsc_context_del (_used_ic_impl_list->parent);
+    }
+
+    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 ();
+    _config_connection.disconnect ();
+
+    _focused_ic = NULL;
+    _ic_list = NULL;
+
+    _scim_initialized = false;
+
+    _panel_client.reset_signal_handler ();
+    panel_finalize ();
+}
+
+static void
+_display_input_language (WSCContextISF *ic)
+{
+}
+
+static void
+open_next_factory (WSCContextISF *ic)
+{
+    if (!check_valid_ic (ic))
+        return;
+
+    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 ());
+        _panel_client.set_candidate_style (ic->id, ONE_LINE_CANDIDATE, FIXED_CANDIDATE_WINDOW);
+        set_ic_capabilities (ic);
+        turn_on_ic (ic);
+
+        if (_shared_input_method) {
+            _default_instance = ic->impl->si;
+            ic->impl->shared_si = true;
+        }
+        //_popup_message (utf8_wcstombs (sf->get_name ()).c_str ());
+    }
+}
+
+static void
+open_previous_factory (WSCContextISF *ic)
+{
+    if (!check_valid_ic (ic))
+        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 ());
+        _panel_client.set_candidate_style (ic->id, ONE_LINE_CANDIDATE, FIXED_CANDIDATE_WINDOW);
+        set_ic_capabilities (ic);
+        turn_on_ic (ic);
+
+        if (_shared_input_method) {
+            _default_instance = ic->impl->si;
+            ic->impl->shared_si = true;
+        }
+        //_popup_message (utf8_wcstombs (sf->get_name ()).c_str ());
+    }
+}
+
+static void
+open_specific_factory (WSCContextISF *ic,
+                       const String     &uuid)
+{
+    if (!check_valid_ic (ic))
+        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 {
+        std::cerr << "open_specific_factory () is failed!!!!!!\n";
+        LOGE ("open_specific_factory () is failed. ic : %x uuid : %s", ic->id, uuid.c_str ());
+
+        // 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);
+                _config->flush ();
+            }
+
+            if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) {
+                if (!check_valid_ic (ic))
+                    return;
+
+                if (check_valid_ic (ic))
+                    ic->impl->preedit_started = false;
+            }
+        }
+    }
+}
+
+#define MOD_SHIFT_MASK         0x01
+#define MOD_ALT_MASK           0x02
+#define MOD_CONTROL_MASK       0x04
+
+static uint32_t _keyname_to_keysym(uint32_t keyname, uint32_t *modifiers)
+{
+    if (!modifiers)
+        return keyname;
+    
+    if ((keyname >= '0' && keyname <= '9') ||
+        (keyname >= 'a' && keyname <= 'z')) {
+        return keyname;
+    }
+    else if (keyname >= 'A' && keyname <= 'Z') {
+        *modifiers |= MOD_SHIFT_MASK;
+        return keyname + 32;
+    }
+
+    switch (keyname) {
+        case '!':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '1';
+        case '@':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '2';
+        case '#':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '3';
+        case '$':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '4';
+        case '%':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '5';
+        case '^':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '6';
+        case '&':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '7';
+        case '*':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '8';
+        case '(':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '9';
+        case ')':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '0';
+        case '_':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '-';
+        case '+':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '=';
+        case '{':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '[';
+        case '}':
+            *modifiers |= MOD_SHIFT_MASK;
+            return ']';
+        case '|':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '\\';
+        case '\:':
+            *modifiers |= MOD_SHIFT_MASK;
+            return ';';
+        case '\"':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '\'';
+        case '<':
+            *modifiers |= MOD_SHIFT_MASK;
+            return ',';
+        case '>':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '.';
+        case '?':
+            *modifiers |= MOD_SHIFT_MASK;
+            return '/';
+        default:
+            return keyname;
+    }
+}
+
+static void send_wl_key_event (WSCContextISF *ic, const KeyEvent &key, bool fake)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+    
+    uint32_t time = 0;
+    uint32_t sym = 0;
+
+    if (!fake)
+        time = get_time ();
+
+    uint32_t modifiers = 0;
+    if (key.is_shift_down ())
+        modifiers |= MOD_SHIFT_MASK;
+    if (key.is_alt_down ())
+        modifiers |= MOD_ALT_MASK;
+    if (key.is_control_down ())
+        modifiers |= MOD_CONTROL_MASK;
+
+    sym = _keyname_to_keysym(key.code, &modifiers);
+    wsc_context_send_key(ic->ctx, sym, modifiers, time, key.is_key_press());
+}
+
+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));
+
+    si->signal_connect_expand_candidate (
+        slot (slot_expand_candidate));
+    si->signal_connect_contract_candidate (
+        slot (slot_contract_candidate));
+
+    si->signal_connect_set_candidate_style (
+        slot (slot_set_candidate_style));
+}
+
+// Implementation of slot functions
+static void
+slot_show_preedit_string (IMEngineInstanceBase *si)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        if (ic->impl->use_preedit) {
+            if (!ic->impl->preedit_started) {
+                if (check_valid_ic (ic))
+                    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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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 (check_valid_ic (ic) && ic->impl->preedit_started) {
+                if (check_valid_ic (ic))
+                    ic->impl->preedit_started = false;
+            }
+            wsc_context_send_preedit_string(ic->ctx);
+        } else {
+            _panel_client.hide_preedit_string (ic->id);
+        }
+    }
+}
+
+static void
+slot_hide_aux_string (IMEngineInstanceBase *si)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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) {
+                if (!check_valid_ic (ic))
+                    return;
+
+                ic->impl->preedit_started = true;
+            }
+        } else {
+            _panel_client.update_preedit_caret (ic->id, caret);
+        }
+    }
+}
+
+static void
+slot_update_preedit_string (IMEngineInstanceBase *si,
+                            const WideString & str,
+                            const AttributeList & attrs,
+                            int caret)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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) {
+                if (!check_valid_ic (ic))
+                    return;
+
+                ic->impl->preedit_started = true;
+            }
+            if (caret >= 0 && caret <= (int)str.length ())
+                ic->impl->preedit_caret = caret;
+            else
+                ic->impl->preedit_caret = str.length ();
+            ic->impl->preedit_updating = true;
+            if (check_valid_ic (ic))
+                ic->impl->preedit_updating = false;
+            wsc_context_send_preedit_string(ic->ctx);
+        } else {
+            _panel_client.update_preedit_string (ic->id, str, attrs, caret);
+        }
+    }
+}
+
+static void
+slot_update_aux_string (IMEngineInstanceBase *si,
+                        const WideString & str,
+                        const AttributeList & attrs)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+    
+    if (ic && ic->ctx) {
+        if (utf8_wcstombs (str) == String (" ") || utf8_wcstombs (str) == String (" "))
+            autoperiod_insert (ic);
+
+        Eina_Bool auto_capitalized = EINA_FALSE;
+
+        if (ic->impl) {
+            if (wsc_context_input_panel_layout_get (ic->ctx) == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL &&
+                ic->impl->shift_mode_enabled &&
+                ic->impl->autocapital_type != ECORE_IMF_AUTOCAPITAL_TYPE_NONE &&
+                hw_keyboard_num_get () == 0) {
+                char converted[2] = {'\0'};
+                if (utf8_wcstombs (str).length () == 1) {
+                    Eina_Bool uppercase;
+                    switch (ic->impl->next_shift_status) {
+                        case 0:
+                            uppercase = caps_mode_check (ic, EINA_FALSE, EINA_FALSE);
+                            break;
+                        case SHIFT_MODE_OFF:
+                            uppercase = EINA_FALSE;
+                            ic->impl->next_shift_status = 0;
+                            break;
+                        case SHIFT_MODE_ON:
+                            uppercase = EINA_TRUE;
+                            ic->impl->next_shift_status = 0;
+                            break;
+                        case SHIFT_MODE_LOCK:
+                            uppercase = EINA_TRUE;
+                            break;
+                        default:
+                            uppercase = EINA_FALSE;
+                    }
+                    converted[0] = utf8_wcstombs (str).at (0);
+                    if (uppercase) {
+                        if (converted[0] >= 'a' && converted[0] <= 'z')
+                            converted[0] -= 32;
+                    } else {
+                        if (converted[0] >= 'A' && converted[0] <= 'Z')
+                            converted[0] += 32;
+                    }
+
+                    wsc_context_commit_string (ic->ctx, converted);
+                    auto_capitalized = EINA_TRUE;
+                }
+            }
+        }
+
+        if (!auto_capitalized) {
+            wsc_context_commit_string (ic->ctx, utf8_wcstombs (str).c_str ());
+        }
+    }
+}
+
+static void
+slot_forward_key_event (IMEngineInstanceBase *si,
+                        const KeyEvent & key)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && _focused_ic == ic) {
+        if (!_fallback_instance->process_key_event (key)) {
+            feed_key_event (ic, key, true);
+        }
+    }
+}
+
+static void
+slot_update_lookup_table (IMEngineInstanceBase *si,
+                          const LookupTable & table)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+}
+
+static void
+slot_start_helper (IMEngineInstanceBase *si,
+                   const String &helper_uuid)
+{
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
+                           << (ic != NULL ? ic->id : -1) << " ic=" << ic
+                           << " ic-uuid=" << ((ic != NULL && ic->impl != NULL) ? 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)
+{
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic != NULL ? 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)
+{
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context="
+                           << (ic != NULL ? ic->id : -1) << " ic=" << ic
+                           << " ic-uuid=" << ((ic != NULL && ic->impl != NULL) ? 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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        char *surrounding = NULL;
+        int   cursor_index;
+        if (wsc_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";
+
+            if (!surrounding)
+                return false;
+
+            if (cursor_index < 0) {
+                free (surrounding);
+                surrounding = NULL;
+                return false;
+            }
+
+            WideString before = utf8_mbstowcs (String (surrounding));
+            free (surrounding);
+            surrounding = NULL;
+
+            if (cursor_index > (int)before.length ())
+                return false;
+            WideString after = before;
+            before = before.substr (0, cursor_index);
+            after =  after.substr (cursor_index, after.length () - 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";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic) {
+        wsc_context_delete_surrounding(_focused_ic->ctx, offset, len);
+        return true;
+    }
+    return false;
+}
+
+static void
+slot_expand_candidate (IMEngineInstanceBase *si)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic)
+        _panel_client.expand_candidate (ic->id);
+}
+
+static void
+slot_contract_candidate (IMEngineInstanceBase *si)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic)
+        _panel_client.contract_candidate (ic->id);
+}
+
+static void
+slot_set_candidate_style (IMEngineInstanceBase *si, ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, ISF_CANDIDATE_MODE_T mode)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    WSCContextISF *ic = static_cast<WSCContextISF *> (si->get_frontend_data ());
+
+    if (ic && ic->impl && _focused_ic == ic)
+        _panel_client.set_candidate_style (ic->id, portrait_line, mode);
+}
+
+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,
+                           const WideString      &str)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+    
+    if (_focused_ic && _focused_ic->impl) {
+        wsc_context_commit_string (_focused_ic->ctx, utf8_wcstombs (str).c_str ());
+    }
+}
+
diff --git a/ism/extras/efl_wsc/isf_wsc_context.h b/ism/extras/efl_wsc/isf_wsc_context.h
new file mode 100644 (file)
index 0000000..c794501
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright Â© 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ISF_WSC_CONTEXT_H_
+#define __ISF_WSC_CONTEXT_H_
+
+#include <Ecore.h>
+#include <Ecore_IMF.h>
+#include <dlog.h>
+
+struct weescim;
+
+const double DOUBLE_SPACE_INTERVAL = 1.0;
+const double HIDE_TIMER_INTERVAL = 0.05;
+const double WILL_SHOW_TIMER_INTERVAL = 5.0;
+
+typedef struct _WSCContextISF      WSCContextISF;
+typedef struct _WSCContextISFImpl  WSCContextISFImpl;
+
+struct _WSCContextISF {
+    weescim *ctx;
+
+    WSCContextISFImpl *impl;
+
+    int id; /* Input Context id*/
+    _WSCContextISF *next;
+};
+
+EAPI void get_language(char **language);
+EAPI int get_panel_client_id ();
+EAPI Eina_Bool caps_mode_check (WSCContextISF *ctx, Eina_Bool force, Eina_Bool noti);
+
+EAPI WSCContextISF *get_focused_ic ();
+
+EAPI void context_scim_imdata_get (WSCContextISF *ctx, void* data, int* length);
+EAPI void imengine_layout_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Layout layout);
+
+EAPI void isf_wsc_context_add (WSCContextISF *ctx);
+EAPI void isf_wsc_context_del (WSCContextISF *ctx);
+EAPI void isf_wsc_context_focus_in (WSCContextISF *ctx);
+EAPI void isf_wsc_context_focus_out (WSCContextISF *ctx);
+EAPI void isf_wsc_context_reset (WSCContextISF *ctx);
+EAPI void isf_wsc_context_preedit_string_get (WSCContextISF *ctx, char** str, int *cursor_pos);
+EAPI void isf_wsc_context_prediction_allow_set (WSCContextISF* ctx, Eina_Bool prediction);
+
+EAPI WSCContextISF* isf_wsc_context_new      (void);
+EAPI void           isf_wsc_context_shutdown (void);
+
+bool wsc_context_surrounding_get (weescim *ctx, char **text, int *cursor_pos);
+Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get(weescim *ctx);
+bool wsc_context_input_panel_caps_lock_mode_get(weescim *ctx);
+void wsc_context_delete_surrounding (weescim *ctx, int offset, int len);
+void wsc_context_commit_preedit_string(weescim *ctx);
+void wsc_context_commit_string(weescim *ctx, const char *str);
+void wsc_context_send_preedit_string(weescim *ctx);
+void wsc_context_send_key(weescim *ctx, uint32_t keysym, uint32_t modifiers, uint32_t time, bool press);
+
+#endif /* __ISF_WSC_CONTEXT_H_ */
diff --git a/ism/extras/efl_wsc/isf_wsc_control.cpp b/ism/extras/efl_wsc/isf_wsc_control.cpp
new file mode 100644 (file)
index 0000000..8500848
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Haifeng Deng <haifeng.deng@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_TRANSACTION
+#define Uses_ISF_IMCONTROL_CLIENT
+#define Uses_SCIM_PANEL_CLIENT
+
+#include <stdio.h>
+#include <Ecore.h>
+#include <errno.h>
+#include "isf_wsc_control.h"
+#include "scim.h"
+
+
+using namespace scim;
+
+
+//#define IMFCONTROLDBG(str...) printf(str)
+#define IMFCONTROLDBG(str...)
+#define IMFCONTROLERR(str...) printf(str)
+
+
+extern PanelClient       _panel_client;
+
+
+int _isf_wsc_context_input_panel_show (int client_id, int context, void *data, int length, bool &input_panel_show)
+{
+    int temp = 0;
+    _panel_client.prepare (context);
+    _panel_client.show_ise (client_id, context, data, length, &temp);
+    input_panel_show = (bool)temp;
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_hide (int client_id, int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.hide_ise (client_id, context);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_control_panel_show (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.show_control_panel ();
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_control_panel_hide (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.hide_control_panel ();
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_language_set (int context, Ecore_IMF_Input_Panel_Lang lang)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_ise_language (lang);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_language_locale_get (int context, char **locale)
+{
+    _panel_client.prepare (context);
+    _panel_client.get_ise_language_locale (locale);
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_imdata_set (int context, const void *data, int len)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_imdata ((const char *)data, len);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_imdata_get (int context, void *data, int *len)
+{
+    _panel_client.prepare (context);
+    _panel_client.get_imdata ((char *)data, len);
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_geometry_get (int context, int *x, int *y, int *w, int *h)
+{
+    _panel_client.prepare (context);
+    _panel_client.get_ise_window_geometry (x, y, w, h);
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_return_key_type_set (int context, Ecore_IMF_Input_Panel_Return_Key_Type type)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_return_key_type ((int)type);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_return_key_type_get (int context, Ecore_IMF_Input_Panel_Return_Key_Type &type)
+{
+    int temp = 0;
+    _panel_client.prepare (context);
+    _panel_client.get_return_key_type (temp);
+    type = (Ecore_IMF_Input_Panel_Return_Key_Type)temp;
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_return_key_disabled_set (int context, Eina_Bool disabled)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_return_key_disable ((int)disabled);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_return_key_disabled_get (int context, Eina_Bool &disabled)
+{
+    int temp = 0;
+    _panel_client.prepare (context);
+    _panel_client.get_return_key_disable (temp);
+    disabled = (Eina_Bool)temp;
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_layout_set (int context, Ecore_IMF_Input_Panel_Layout layout)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_layout (layout);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_layout_get (int context, Ecore_IMF_Input_Panel_Layout *layout)
+{
+    int layout_temp;
+    _panel_client.prepare (context);
+    _panel_client.get_layout (&layout_temp);
+
+    *layout = (Ecore_IMF_Input_Panel_Layout)layout_temp;
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_state_get (int context, Ecore_IMF_Input_Panel_State &state)
+{
+    int temp = 0;
+    _panel_client.prepare (context);
+    _panel_client.get_ise_state (temp);
+
+    state = (Ecore_IMF_Input_Panel_State)temp;
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_caps_mode_set (int context, unsigned int mode)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_caps_mode (mode);
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_candidate_window_geometry_get (int context, int *x, int *y, int *w, int *h)
+{
+    _panel_client.prepare (context);
+    _panel_client.get_candidate_window_geometry (x, y, w, h);
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_send_will_show_ack (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.send_will_show_ack ();
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_send_will_hide_ack (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.send_will_hide_ack ();
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_set_hardware_keyboard_mode (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.set_hardware_keyboard_mode ();
+    _panel_client.send ();
+    return 0;
+}
+
+int _isf_wsc_context_input_panel_send_candidate_will_hide_ack (int context)
+{
+    _panel_client.prepare (context);
+    _panel_client.send_candidate_will_hide_ack ();
+    _panel_client.send ();
+    return 0;
+}
+
+/*
+vi:ts=4:expandtab:nowrap
+*/
diff --git a/ism/extras/efl_wsc/isf_wsc_control.h b/ism/extras/efl_wsc/isf_wsc_control.h
new file mode 100644 (file)
index 0000000..70e7958
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Haifeng Deng <haifeng.deng@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __ISF_WSC_CONTROL_H
+#define __ISF_WSC_CONTROL_H
+
+#include <Ecore_IMF.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+    int _isf_wsc_context_input_panel_show (int client_id, int context, void *data, int length, bool &input_panel_show);
+    int _isf_wsc_context_input_panel_hide (int client_id, int context);
+    int _isf_wsc_context_control_panel_show (int context);
+    int _isf_wsc_context_control_panel_hide (int context);
+
+    int _isf_wsc_context_input_panel_language_set (int context, Ecore_IMF_Input_Panel_Lang lang);
+    int _isf_wsc_context_input_panel_language_locale_get (int context, char **locale);
+
+    int _isf_wsc_context_input_panel_imdata_set (int context, const void *data, int len);
+    int _isf_wsc_context_input_panel_imdata_get (int context, void *data, int *len);
+    int _isf_wsc_context_input_panel_geometry_get (int context, int *x, int *y, int *w, int *h);
+    int _isf_wsc_context_input_panel_layout_set (int context, Ecore_IMF_Input_Panel_Layout layout);
+    int _isf_wsc_context_input_panel_layout_get (int context, Ecore_IMF_Input_Panel_Layout *layout);
+    int _isf_wsc_context_input_panel_state_get (int context, Ecore_IMF_Input_Panel_State &state);
+    int _isf_wsc_context_input_panel_return_key_type_set (int context, Ecore_IMF_Input_Panel_Return_Key_Type type);
+    int _isf_wsc_context_input_panel_return_key_type_get (int context, Ecore_IMF_Input_Panel_Return_Key_Type &type);
+    int _isf_wsc_context_input_panel_return_key_disabled_set (int context, Eina_Bool disabled);
+    int _isf_wsc_context_input_panel_return_key_disabled_get (int context, Eina_Bool &disabled);
+    int _isf_wsc_context_input_panel_caps_mode_set (int context, unsigned int mode);
+
+    int _isf_wsc_context_candidate_window_geometry_get (int context, int *x, int *y, int *w, int *h);
+
+    int _isf_wsc_context_input_panel_send_will_show_ack (int context);
+    int _isf_wsc_context_input_panel_send_will_hide_ack (int context);
+
+    int _isf_wsc_context_set_hardware_keyboard_mode (int context);
+
+    int _isf_wsc_context_input_panel_send_candidate_will_hide_ack (int context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ISF_WSC_CONTROL_H */
+
diff --git a/ism/extras/efl_wsc/isf_wsc_control_ui.cpp b/ism/extras/efl_wsc/isf_wsc_control_ui.cpp
new file mode 100644 (file)
index 0000000..106a922
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Haifeng Deng <haifeng.deng@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_TRANSACTION
+
+
+/* IM control UI part */
+#include <Ecore.h>
+#include <Ecore_Wayland.h>
+#include <Ecore_Evas.h>
+#include <Ecore_IMF.h>
+#include <glib.h>
+#include "scim.h"
+#include "isf_wsc_control_ui.h"
+#include "isf_wsc_context.h"
+#include "isf_wsc_control.h"
+#include "ise_context.h"
+
+using namespace scim;
+
+/* IM control related variables */
+static Ise_Context        iseContext;
+static bool               IfInitContext     = false;
+static unsigned int       hw_kbd_num = 0;
+WSCContextISF            *input_panel_ctx = NULL;
+
+static void _isf_wsc_context_init (void)
+{
+    iseContext.language            = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
+    iseContext.return_key_type     = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
+    iseContext.return_key_disabled = FALSE;
+    iseContext.prediction_allow    = TRUE;
+
+    if (!IfInitContext) {
+        IfInitContext = true;
+    }
+}
+
+static int _get_context_id (WSCContextISF *ctx)
+{
+    WSCContextISF *context_scim = ctx;
+    
+    if (!context_scim) return -1;
+
+    return context_scim->id;
+}
+
+int hw_keyboard_num_get ()
+{
+    return hw_kbd_num;
+}
+
+void isf_wsc_input_panel_init (void)
+{
+    //FIXME: Use wl_input protocol to check hw keyboard.
+    hw_kbd_num = 0;
+    LOGD ("The number of connected H/W keyboard : %d\n", hw_kbd_num);
+}
+
+void isf_wsc_input_panel_shutdown (void)
+{
+}
+
+void isf_wsc_context_input_panel_show (WSCContextISF* ctx)
+{
+    int length = -1;
+    void *packet = NULL;
+    char imdata[1024] = {0};
+    bool input_panel_show = false;
+    input_panel_ctx = ctx;
+
+    if (IfInitContext == false) {
+        _isf_wsc_context_init ();
+    }
+
+    /* set password mode */
+    iseContext.password_mode = EINA_FALSE;
+
+    /* set language */
+    iseContext.language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
+
+    /* set layout in ise context info */
+    iseContext.layout = wsc_context_input_panel_layout_get (ctx->ctx);
+
+    /* set layout variation in ise context info */
+    iseContext.layout_variation = 0;
+
+    /* set prediction allow */
+    iseContext.prediction_allow = EINA_TRUE;
+
+    if (iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
+        iseContext.password_mode = EINA_TRUE;
+
+    if (iseContext.password_mode)
+        iseContext.prediction_allow = EINA_FALSE;
+
+    if (iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL)
+        iseContext.prediction_allow = EINA_FALSE;
+
+    isf_wsc_context_prediction_allow_set (ctx, iseContext.prediction_allow);
+    
+    if (hw_kbd_num != 0) {
+        LOGD ("H/W keyboard is existed.\n");
+        return;
+    }
+
+    /* set return key type */
+    iseContext.return_key_type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
+
+    /* set return key disabled */
+    iseContext.return_key_disabled = EINA_FALSE;
+
+    /* set caps mode */
+    iseContext.caps_mode = caps_mode_check (ctx, EINA_TRUE, EINA_FALSE);
+
+    /* set the size of imdata */
+    context_scim_imdata_get (ctx, (void *)imdata, &iseContext.imdata_size);
+
+    /* set the cursor position of the editable widget */
+    //ecore_imf_context_surrounding_get (ctx, NULL, &iseContext.cursor_pos);
+    iseContext.cursor_pos = 0;
+
+    iseContext.autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
+
+    LOGD ("ctx : %p, layout : %d, layout variation : %d\n", ctx, iseContext.layout, iseContext.layout_variation);
+    LOGD ("language : %d, cursor position : %d, caps mode : %d\n", iseContext.language, iseContext.cursor_pos, iseContext.caps_mode);
+    LOGD ("return_key_type : %d, return_key_disabled : %d, autocapital type : %d\n", iseContext.return_key_type, iseContext.return_key_disabled, iseContext.autocapital_type);
+    
+    /* calculate packet size */
+    length = sizeof (iseContext);
+    length += iseContext.imdata_size;
+
+    /* create packet */
+    packet = calloc (1, length);
+    if (!packet)
+        return;
+
+    memcpy (packet, (void *)&iseContext, sizeof (iseContext));
+    memcpy ((void *)((unsigned int)packet + sizeof (iseContext)), (void *)imdata, iseContext.imdata_size);
+
+    int context_id = _get_context_id (ctx);
+
+    _isf_wsc_context_input_panel_show (get_panel_client_id (), context_id, packet, length, input_panel_show);
+    
+    free (packet);
+    
+    caps_mode_check (ctx, EINA_TRUE, EINA_TRUE);
+}
+
+void isf_wsc_context_input_panel_hide (WSCContextISF *ctx)
+{
+    int context_id = _get_context_id (ctx);
+    _isf_wsc_context_input_panel_hide (get_panel_client_id (), context_id);
+}
+
+void isf_wsc_context_set_hardware_keyboard_mode (WSCContextISF *ctx)
+{
+    if (IfInitContext == false) {
+        _isf_wsc_context_init ();
+    }
+
+    hw_kbd_num = 1;
+    SECURE_LOGD ("The number of connected H/W keyboard : %d\n", hw_kbd_num);
+    _isf_wsc_context_set_hardware_keyboard_mode (_get_context_id (ctx));
+}
+
+void
+isf_wsc_context_input_panel_layout_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Layout layout)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+
+    if (context_scim == get_focused_ic ()) {
+        LOGD ("layout type : %d\n", layout);
+        _isf_wsc_context_input_panel_layout_set (_get_context_id (ctx), layout);
+        imengine_layout_set (ctx, layout);
+    }
+}
+
+Ecore_IMF_Input_Panel_Layout isf_wsc_context_input_panel_layout_get (WSCContextISF *ctx)
+{
+    Ecore_IMF_Input_Panel_Layout layout;
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+    _isf_wsc_context_input_panel_layout_get (_get_context_id (ctx), &layout);
+
+    return layout;
+}
+
+void isf_wsc_context_input_panel_caps_mode_set (WSCContextISF *ctx, unsigned int mode)
+{
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+    LOGD ("ctx : %p, mode : %d\n", ctx, mode);
+    _isf_wsc_context_input_panel_caps_mode_set (_get_context_id (ctx), mode);
+}
+
+void isf_wsc_context_input_panel_caps_lock_mode_set (WSCContextISF *ctx, Eina_Bool mode)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+
+    if (context_scim == get_focused_ic ())
+        caps_mode_check (ctx, EINA_TRUE, EINA_TRUE);
+}
+
+void isf_wsc_context_input_panel_language_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Lang language)
+{
+    WSCContextISF *context_scim = ctx;
+
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+    iseContext.language = language;
+
+    if (context_scim == get_focused_ic ()) {
+        LOGD ("language mode : %d\n", language);
+        _isf_wsc_context_input_panel_language_set (_get_context_id (ctx), language);
+    }
+}
+
+Ecore_IMF_Input_Panel_Lang isf_imf_context_input_panel_language_get (WSCContextISF *ctx)
+{
+    if (!IfInitContext)
+        _isf_wsc_context_init ();
+    return iseContext.language;
+}
+
diff --git a/ism/extras/efl_wsc/isf_wsc_control_ui.h b/ism/extras/efl_wsc/isf_wsc_control_ui.h
new file mode 100644 (file)
index 0000000..d2dfb37
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Haifeng Deng <haifeng.deng@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __ISF_IMF_CONTROL_UI_H
+#define __ISF_IMF_CONTROL_UI_H
+
+#include "isf_wsc_context.h"
+#include <Ecore_IMF.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+    int  hw_keyboard_num_get ();
+    bool process_update_input_context (int type, int value);
+    void clear_hide_request ();
+
+    void isf_wsc_input_panel_init ();
+    void isf_wsc_input_panel_shutdown ();
+    void isf_wsc_context_input_panel_show (WSCContextISF *ctx);
+    void isf_wsc_context_input_panel_hide (WSCContextISF *ctx);
+    void isf_wsc_context_input_panel_language_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Lang lang);
+    Ecore_IMF_Input_Panel_Lang isf_wsc_context_input_panel_language_get (WSCContextISF *ctx);
+    void isf_wsc_context_input_panel_layout_set (WSCContextISF *ctx, Ecore_IMF_Input_Panel_Layout layout);
+    Ecore_IMF_Input_Panel_Layout isf_wsc_context_input_panel_layout_get (WSCContextISF *ctx);
+    void isf_wsc_context_input_panel_caps_mode_set (WSCContextISF *ctx, unsigned int mode);
+    void isf_wsc_context_input_panel_caps_lock_mode_set (WSCContextISF *ctx, Eina_Bool mode);
+    void isf_wsc_context_set_hardware_keyboard_mode (WSCContextISF *ctx);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ISF_IMF_CONTROL_UI_H */
+
diff --git a/ism/extras/efl_wsc/isf_wsc_efl.cpp b/ism/extras/efl_wsc/isf_wsc_efl.cpp
new file mode 100644 (file)
index 0000000..0a082fb
--- /dev/null
@@ -0,0 +1,760 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more fitable.
+ * Copyright (c) 2012-2014 Intel Co., Ltd.
+ *
+ * Contact: Yan Wang <yan.wang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_CONFIG_PATH
+#define Uses_SCIM_HELPER_MODULE
+#define Uses_SCIM_PANEL_AGENT
+#define Uses_SCIM_COMPOSE_KEY
+#define Uses_SCIM_IMENGINE_MODULE
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <list>
+#include <glib.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Wayland.h>
+#include <Ecore_File.h>
+#include <malloc.h>
+#include "scim_private.h"
+#include "scim.h"
+#include "scim_stl_map.h"
+#if HAVE_VCONF
+#include <vconf.h>
+#include <vconf-keys.h>
+#endif
+#include <privilege-control.h>
+#include <dlog.h>
+
+#include <linux/input.h>
+#include <xkbcommon/xkbcommon.h>
+#include <sys/mman.h>
+#include "input-method-client-protocol.h"
+#include "text-client-protocol.h"
+#include "isf_wsc_context.h"
+#include "isf_wsc_control_ui.h"
+#include "scim_stl_map.h"
+
+using namespace scim;
+
+#if SCIM_USE_STL_EXT_HASH_MAP
+    typedef __gnu_cxx::hash_map <uint32_t, uint32_t, __gnu_cxx::hash <uint32_t> >   KeycodeRepository;
+#elif SCIM_USE_STL_HASH_MAP
+    typedef std::hash_map <uint32_t, ClientInfo, std::hash <uint32_t> >             KeycodeRepository;
+#else
+    typedef std::map <uint32_t, uint32_t>                                           KeycodeRepository;
+#endif
+
+static KeycodeRepository _keysym2keycode;
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of macro.
+/////////////////////////////////////////////////////////////////////////////
+#define LOG_TAG                                         "ISF_WSC_EFL"
+
+/* This structure stores the wayland input method information */
+struct weescim;
+
+#define MOD_SHIFT_MASK         0x01
+#define MOD_ALT_MASK           0x02
+#define MOD_CONTROL_MASK       0x04
+
+typedef void (*keyboard_input_key_handler_t)(struct weescim *wsc,
+                                            uint32_t serial,
+                                            uint32_t time, uint32_t key, uint32_t unicode,
+                                            enum wl_keyboard_key_state state);
+
+struct weescim
+{
+    struct wl_input_method *im;
+    struct wl_input_method_context *im_ctx;
+    struct wl_seat *seat;
+    struct wl_keyboard *keyboard;
+
+    struct xkb_context *xkb_context;
+
+    uint32_t modifiers;
+
+    struct xkb_keymap *keymap;
+    struct xkb_state *state;
+    xkb_mod_mask_t control_mask;
+    xkb_mod_mask_t alt_mask;
+    xkb_mod_mask_t shift_mask;
+
+    keyboard_input_key_handler_t key_handler;
+
+    char *surrounding_text;
+    char *preedit_str;
+    char *language;
+
+    uint32_t serial;
+    uint32_t text_direction;
+    uint32_t preedit_style;
+    uint32_t content_hint;
+    uint32_t content_purpose;
+    uint32_t surrounding_cursor;
+
+    Eina_Bool context_changed;
+    Eina_Bool hw_kbd;
+
+    WSCContextISF *wsc_ctx;
+};
+static struct weescim _wsc                                  = {0};
+
+static char *
+append(char *s1, const char *s2)
+{
+       int len1, len2;
+       char *s;
+
+       len1 = strlen(s1);
+       len2 = strlen(s2);
+       s = (char*)realloc(s1, len1 + len2 + 1);
+       memcpy(s + len1, s2, len2);
+       s[len1 + len2] = '\0';
+
+       return s;
+}
+
+static char *
+insert_text(const char *text, uint32_t offset, const char *insert)
+{
+       int tlen = strlen(text), ilen = strlen(insert);
+       char *new_text = (char*)malloc(tlen + ilen + 1);
+
+       memcpy(new_text, text, offset);
+       memcpy(new_text + offset, insert, ilen);
+       memcpy(new_text + offset + ilen, text + offset, tlen - offset);
+       new_text[tlen + ilen] = '\0';
+
+       return new_text;
+}
+
+static void
+wsc_commit_preedit(weescim *ctx)
+{
+       char *surrounding_text;
+
+       if (!ctx->preedit_str ||
+           strlen(ctx->preedit_str) == 0)
+               return;
+
+       wl_input_method_context_cursor_position(ctx->im_ctx,
+                                               0, 0);
+       wl_input_method_context_commit_string(ctx->im_ctx,
+                                             ctx->serial,
+                                             ctx->preedit_str);
+
+       if (ctx->surrounding_text) {
+               surrounding_text = insert_text(ctx->surrounding_text,
+                                              ctx->surrounding_cursor,
+                                              ctx->preedit_str);
+               free(ctx->surrounding_text);
+               ctx->surrounding_text = surrounding_text;
+               ctx->surrounding_cursor += strlen(ctx->preedit_str);
+       } else {
+               ctx->surrounding_text = strdup(ctx->preedit_str);
+               ctx->surrounding_cursor = strlen(ctx->preedit_str);
+       }
+
+       free(ctx->preedit_str);
+       ctx->preedit_str = strdup("");
+}
+
+static void
+wsc_send_preedit(weescim *ctx, int32_t cursor)
+{
+       uint32_t index = strlen(ctx->preedit_str);
+
+       if (ctx->preedit_style)
+               wl_input_method_context_preedit_styling(ctx->im_ctx,
+                                                       0,
+                                                       strlen(ctx->preedit_str),
+                                                       ctx->preedit_style);
+       if (cursor > 0)
+               index = cursor;
+       wl_input_method_context_preedit_cursor(ctx->im_ctx, index);
+       wl_input_method_context_preedit_string(ctx->im_ctx,
+                                              ctx->serial,
+                                              ctx->preedit_str,
+                                              ctx->preedit_str);
+}
+
+bool wsc_context_surrounding_get(weescim *ctx, char **text, int *cursor_pos)
+{
+    if (!ctx)
+        return false;
+
+    *text = strdup (ctx->surrounding_text);
+    *cursor_pos = ctx->surrounding_cursor;
+    return true;
+}
+
+Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get(weescim *ctx)
+{
+    Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
+    
+    switch (ctx->content_purpose) {
+        case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER:
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_DATE:
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_TIME:
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER;
+            break;
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
+            break;
+        case WL_TEXT_INPUT_CONTENT_PURPOSE_URL:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
+            break;
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
+            break;
+           case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
+            break;
+        default:
+            layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
+            break;
+    }
+    
+    return layout;
+}
+
+bool wsc_context_input_panel_caps_lock_mode_get(weescim *ctx)
+{
+    if (ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE)
+        return true;
+    
+    return false;
+}
+
+void wsc_context_delete_surrounding (weescim *ctx, int offset, int len)
+{
+    if (!ctx)
+        return;
+
+    wl_input_method_context_delete_surrounding_text(ctx->im_ctx, offset, len);
+}
+
+void wsc_context_commit_string(weescim *ctx, const char *str)
+{
+    if (ctx->preedit_str) {
+        free(ctx->preedit_str);
+        ctx->preedit_str = NULL;
+    }
+    
+    ctx->preedit_str = strdup (str);
+    wsc_commit_preedit(ctx);
+}
+
+void wsc_context_commit_preedit_string(weescim *ctx)
+{
+    char *preedit_str = NULL;
+    int cursor_pos = 0;
+
+    isf_wsc_context_preedit_string_get(ctx->wsc_ctx, &preedit_str, &cursor_pos);
+    if (ctx->preedit_str) {
+        free(ctx->preedit_str);
+        ctx->preedit_str = NULL;
+    }
+    
+    ctx->preedit_str = preedit_str;
+    wsc_commit_preedit(ctx);
+}
+
+void wsc_context_send_preedit_string(weescim *ctx)
+{
+    char *preedit_str = NULL;
+    int cursor_pos = 0;
+
+    isf_wsc_context_preedit_string_get(ctx->wsc_ctx, &preedit_str, &cursor_pos);
+    if (ctx->preedit_str) {
+        free(ctx->preedit_str);
+        ctx->preedit_str = NULL;
+    }
+    
+    ctx->preedit_str = preedit_str;
+    wsc_send_preedit(ctx, cursor_pos);
+}
+
+void wsc_context_send_key(weescim *ctx, uint32_t keysym, uint32_t modifiers, uint32_t time, bool press)
+{
+    uint32_t keycode;
+    KeycodeRepository::iterator it = _keysym2keycode.find(keysym);
+    
+    if(it == _keysym2keycode.end())
+        return;
+
+    keycode = it->second;
+    ctx->modifiers = modifiers;
+
+    if (press) {
+        if (ctx->modifiers) {
+            wl_input_method_context_modifiers(ctx->im_ctx, ctx->serial,
+                ctx->modifiers, 0, 0, 0);
+        }
+
+        wl_input_method_context_key(ctx->im_ctx, ctx->serial, time,
+            keycode, WL_KEYBOARD_KEY_STATE_PRESSED);
+    }
+    else {
+        wl_input_method_context_key(ctx->im_ctx, ctx->serial, time,
+            keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
+        
+        if (ctx->modifiers) {
+            wl_input_method_context_modifiers(ctx->im_ctx, ctx->serial,
+                0, 0, 0, 0);
+        }
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementation of Wayland Input Method functions.
+/////////////////////////////////////////////////////////////////////////////
+static void
+_wsc_im_ctx_surrounding_text(void *data, struct wl_input_method_context *im_ctx, const char *text, uint32_t cursor, uint32_t anchor)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    free (wsc->surrounding_text);
+    wsc->surrounding_text = strdup (text);
+    wsc->surrounding_cursor = cursor;
+}
+
+static void
+_wsc_im_ctx_reset(void *data, struct wl_input_method_context *im_ctx)
+{
+    struct weescim *wsc = (weescim*)data;
+    
+    isf_wsc_context_reset(wsc->wsc_ctx);
+}
+
+static void
+_wsc_im_ctx_content_type(void *data, struct wl_input_method_context *im_ctx, uint32_t hint, uint32_t purpose)
+{
+    struct weescim *wsc = (weescim*)data;
+    Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
+
+    ISF_LOG ("im_context = %p hint = %d purpose = %d", im_ctx, hint, purpose);
+
+    if (!wsc->context_changed)
+        return;
+
+    wsc->content_hint = hint;
+    wsc->content_purpose = purpose;
+
+    isf_wsc_context_input_panel_layout_set (wsc->wsc_ctx,
+        wsc_context_input_panel_layout_get (wsc));
+    
+    caps_mode_check(wsc->wsc_ctx, EINA_TRUE, EINA_TRUE);
+
+    //FIXME: process hint like layout.
+
+    wsc->context_changed = EINA_FALSE;
+}
+
+static void
+_wsc_im_ctx_invoke_action(void *data, struct wl_input_method_context *im_ctx, uint32_t button, uint32_t index)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    if (button != BTN_LEFT)
+        return;
+
+    wsc_context_send_preedit_string (wsc);
+}
+
+static void
+_wsc_im_ctx_commit_state(void *data, struct wl_input_method_context *im_ctx, uint32_t serial)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    wsc->serial = serial;
+
+    if (wsc->surrounding_text)
+        ISF_LOG ("Surrounding text updated: %s", wsc->surrounding_text);
+
+    if(wsc->language)
+           wl_input_method_context_language (im_ctx, wsc->serial, wsc->language);
+
+       wl_input_method_context_text_direction (im_ctx, wsc->serial, wsc->text_direction);
+}
+
+static void
+_wsc_im_ctx_preferred_language(void *data, struct wl_input_method_context *im_ctx, const char *language)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    if (language && wsc->language && !strcmp (language, wsc->language))
+        return;
+
+    if (wsc->language) {
+        free (wsc->language);
+        wsc->language = NULL;
+    }
+
+    if (language) {
+        wsc->language = strdup (language);
+        ISF_LOG ("Language changed, new: '%s'", language);
+    }
+}
+
+static const struct wl_input_method_context_listener wsc_im_context_listener = {
+     _wsc_im_ctx_surrounding_text,
+     _wsc_im_ctx_reset,
+     _wsc_im_ctx_content_type,
+     _wsc_im_ctx_invoke_action,
+     _wsc_im_ctx_commit_state,
+     _wsc_im_ctx_preferred_language,
+};
+
+static void
+_init_keysym2keycode(struct weescim *wsc)
+{
+    uint32_t i = 0;
+    uint32_t code;
+    uint32_t num_syms;
+    const xkb_keysym_t *syms;
+
+    if (!wsc->state)
+        return;
+
+    for (i = 0; i < 256; i++) {
+        code = i + 8;
+        num_syms = xkb_key_get_syms(wsc->state, code, &syms);
+
+        if (num_syms == 1)
+            _keysym2keycode[syms[0]] = i;
+    }
+}
+
+static void
+_fini_keysym2keycode(struct weescim *wsc)
+{
+    _keysym2keycode.clear();
+}
+
+static void
+_wsc_im_keyboard_keymap(void *data,
+        struct wl_keyboard *wl_keyboard,
+        uint32_t format,
+        int32_t fd,
+        uint32_t size)
+{
+    struct weescim *wsc = (weescim*)data;
+    char *map_str;
+
+    _fini_keysym2keycode(wsc);
+
+    if (wsc->state) {
+        xkb_state_unref(wsc->state);
+        wsc->state = NULL;
+    }
+
+    if (wsc->keymap) {
+        xkb_map_unref(wsc->keymap);
+        wsc->keymap = NULL;
+    }
+
+    if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
+        close(fd);
+        return;
+    }
+
+    map_str = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+    if (map_str == MAP_FAILED) {
+        close(fd);
+        return;
+    }
+
+    wsc->keymap =
+        xkb_map_new_from_string(wsc->xkb_context,
+                map_str,
+                XKB_KEYMAP_FORMAT_TEXT_V1,
+                (xkb_keymap_compile_flags)0);
+
+    munmap(map_str, size);
+    close(fd);
+
+    if (!wsc->keymap) {
+        fprintf(stderr, "failed to compile keymap\n");
+        return;
+    }
+
+    wsc->state = xkb_state_new(wsc->keymap);
+    if (!wsc->state) {
+        fprintf(stderr, "failed to create XKB state\n");
+        xkb_map_unref(wsc->keymap);
+        return;
+    }
+
+    wsc->control_mask =
+        1 << xkb_map_mod_get_index(wsc->keymap, "Control");
+    wsc->alt_mask =
+        1 << xkb_map_mod_get_index(wsc->keymap, "Mod1");
+    wsc->shift_mask =
+        1 << xkb_map_mod_get_index(wsc->keymap, "Shift");
+    
+    fprintf(stderr, "create _keysym2keycode\n");
+    _init_keysym2keycode(wsc);
+}
+
+static void
+_wsc_im_keyboard_key(void *data,
+        struct wl_keyboard *wl_keyboard,
+        uint32_t serial,
+        uint32_t time,
+        uint32_t key,
+        uint32_t state_w)
+{
+    struct weescim *wsc = (weescim*)data;
+    uint32_t code;
+    uint32_t num_syms;
+    const xkb_keysym_t *syms;
+    xkb_keysym_t sym;
+    enum wl_keyboard_key_state state = (wl_keyboard_key_state)state_w;
+
+    if (!wsc->state)
+        return;
+
+    code = key + 8;
+    num_syms = xkb_key_get_syms(wsc->state, code, &syms);
+
+    sym = XKB_KEY_NoSymbol;
+    if (num_syms == 1)
+        sym = syms[0];
+
+    if (wsc->key_handler)
+        (*wsc->key_handler)(wsc, serial, time, key, sym,
+                state);
+}
+
+static void
+_wsc_im_keyboard_modifiers(void *data,
+        struct wl_keyboard *wl_keyboard,
+        uint32_t serial,
+        uint32_t mods_depressed,
+        uint32_t mods_latched,
+        uint32_t mods_locked,
+        uint32_t group)
+{
+    struct weescim *wsc = (weescim*)data;
+    struct wl_input_method_context *context = wsc->im_ctx;
+    xkb_mod_mask_t mask;
+
+    if (!wsc->state)
+        return;
+
+    xkb_state_update_mask(wsc->state, mods_depressed,
+            mods_latched, mods_locked, 0, 0, group);
+    mask = xkb_state_serialize_mods(wsc->state,
+            (xkb_state_component)(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED));
+
+    wsc->modifiers = 0;
+    if (mask & wsc->control_mask)
+        wsc->modifiers |= MOD_CONTROL_MASK;
+    if (mask & wsc->alt_mask)
+        wsc->modifiers |= MOD_ALT_MASK;
+    if (mask & wsc->shift_mask)
+        wsc->modifiers |= MOD_SHIFT_MASK;
+
+    wl_input_method_context_modifiers(context, serial,
+            mods_depressed, mods_depressed,
+            mods_latched, group);
+}
+
+static const struct wl_keyboard_listener wsc_im_keyboard_listener = {
+    _wsc_im_keyboard_keymap,
+    NULL, /* enter */
+    NULL, /* leave */
+    _wsc_im_keyboard_key,
+    _wsc_im_keyboard_modifiers
+};
+
+static void
+_wsc_im_activate(void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    if (wsc->im_ctx)
+        wl_input_method_context_destroy (wsc->im_ctx);
+
+    if (wsc->preedit_str)
+        free (wsc->preedit_str);
+
+    wsc->preedit_str = strdup ("");
+    wsc->content_hint = WL_TEXT_INPUT_CONTENT_HINT_NONE;
+    wsc->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
+
+    free (wsc->language);
+    wsc->language = NULL;
+
+    free (wsc->surrounding_text);
+    wsc->surrounding_text = NULL;
+
+    wsc->im_ctx = im_ctx;
+    wl_input_method_context_add_listener (im_ctx, &wsc_im_context_listener, wsc);
+
+    wsc->keyboard = wl_input_method_context_grab_keyboard(im_ctx);
+    wl_keyboard_add_listener(wsc->keyboard, &wsc_im_keyboard_listener, wsc);
+
+    wsc->context_changed = EINA_TRUE;
+    isf_wsc_context_focus_in (wsc->wsc_ctx);
+    isf_wsc_context_input_panel_show (wsc->wsc_ctx);
+}
+
+static void
+_wsc_im_deactivate(void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    isf_wsc_context_input_panel_hide (wsc->wsc_ctx);
+    isf_wsc_context_focus_out (wsc->wsc_ctx);
+
+    if (wsc->im_ctx) {
+        wl_input_method_context_destroy(wsc->im_ctx);
+        wsc->im_ctx = NULL;
+    } 
+}
+
+static const struct wl_input_method_listener wsc_im_listener = {
+    _wsc_im_activate,
+    _wsc_im_deactivate
+};
+
+static void
+_wsc_seat_handle_capabilities(void *data, struct wl_seat *seat,
+        uint32_t caps)
+{
+    struct weescim *wsc = (weescim*)data;
+
+    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
+        wsc->hw_kbd = true;
+    } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
+        wsc->hw_kbd = false;
+    }
+}
+
+static const struct wl_seat_listener wsc_seat_listener = {
+       _wsc_seat_handle_capabilities,
+};
+
+static void
+_wsc_im_key_handler(struct weescim *wsc,
+                     uint32_t serial, uint32_t time, uint32_t key, uint32_t sym,
+                     enum wl_keyboard_key_state state)
+{
+}
+
+static void
+_wsc_setup(struct weescim *wsc)
+{
+    struct wl_list *globals;
+    struct wl_registry *registry;
+    Ecore_Wl_Global *global;
+       
+    wsc->xkb_context = xkb_context_new((xkb_context_flags)0);
+    if (wsc->xkb_context == NULL) {
+        fprintf(stderr, "Failed to create XKB context\n");
+        return;
+    }
+
+    wsc->key_handler = _wsc_im_key_handler;
+
+    wsc->wsc_ctx = isf_wsc_context_new ();
+    wsc->wsc_ctx->ctx = wsc;
+
+    get_language(&wsc->language);
+
+    if (!(registry = ecore_wl_registry_get()))
+        return;
+
+    if (!(globals = (wl_list*)ecore_wl_globals_get()))
+        return;
+
+    EINA_INLIST_FOREACH(globals, global) {
+        if (strcmp (global->interface, "wl_input_method") == 0)
+            wsc->im = (wl_input_method*)wl_registry_bind (registry, global->id, &wl_input_method_interface, 1);
+        else if (strcmp (global->interface, "wl_seat") == 0)
+            wsc->seat = (wl_seat*)wl_registry_bind (registry, global->id, &wl_seat_interface, 1);
+    }
+
+    /* Input method listener */
+    ISF_LOG ("Adding wl_input_method listener");
+    wl_input_method_add_listener (wsc->im, &wsc_im_listener, wsc);
+       
+    wl_seat_add_listener(wsc->seat, &wsc_seat_listener, wsc);
+    
+    isf_wsc_context_add (wsc->wsc_ctx);
+}
+
+static void
+_wsc_free(struct weescim *wsc)
+{
+    _fini_keysym2keycode(wsc);
+
+    if (wsc->state) {
+        xkb_state_unref(wsc->state);
+        wsc->state = NULL;
+    }
+
+    if (wsc->keymap) {
+        xkb_map_unref(wsc->keymap);
+        wsc->keymap = NULL;
+    }
+
+    if (wsc->im_ctx)
+        wl_input_method_context_destroy (wsc->im_ctx);
+    
+    isf_wsc_context_del(wsc->wsc_ctx);
+    isf_wsc_context_shutdown ();
+
+    free (wsc->preedit_str);
+    free (wsc->surrounding_text);
+}
+
+int main (int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{
+    sleep(1);
+
+    _wsc_setup(&_wsc);
+   
+    ecore_main_loop_begin();
+    
+    _wsc_free(&_wsc);
+
+    return 0;
+}
+
+/*
+vi:ts=4:nowrap:expandtab
+*/
diff --git a/ism/extras/efl_wsc/text-client-protocol.h b/ism/extras/efl_wsc/text-client-protocol.h
new file mode 100644 (file)
index 0000000..b8da964
--- /dev/null
@@ -0,0 +1,543 @@
+/* 
+ * Copyright Â© 2012, 2013 Intel Corporation
+ * 
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#ifndef TEXT_CLIENT_PROTOCOL_H
+#define TEXT_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct wl_text_input;
+struct wl_text_input_manager;
+
+extern const struct wl_interface wl_text_input_interface;
+extern const struct wl_interface wl_text_input_manager_interface;
+
+#ifndef WL_TEXT_INPUT_CONTENT_HINT_ENUM
+#define WL_TEXT_INPUT_CONTENT_HINT_ENUM
+/**
+ * wl_text_input_content_hint - content hint
+ * @WL_TEXT_INPUT_CONTENT_HINT_NONE: no special behaviour
+ * @WL_TEXT_INPUT_CONTENT_HINT_DEFAULT: auto completion, correction and
+ *     capitalization
+ * @WL_TEXT_INPUT_CONTENT_HINT_PASSWORD: hidden and sensitive text
+ * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION: suggest word completions
+ * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION: suggest word corrections
+ * @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION: switch to uppercase
+ *     letters at the start of a sentence
+ * @WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE: prefer lowercase letters
+ * @WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE: prefer uppercase letters
+ * @WL_TEXT_INPUT_CONTENT_HINT_TITLECASE: prefer casing for titles and
+ *     headings (can be language dependent)
+ * @WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT: characters should be hidden
+ * @WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA: typed text should not be
+ *     stored
+ * @WL_TEXT_INPUT_CONTENT_HINT_LATIN: just latin characters should be
+ *     entered
+ * @WL_TEXT_INPUT_CONTENT_HINT_MULTILINE: the text input is multiline
+ *
+ * Content hint is a bitmask to allow to modify the behavior of the text
+ * input.
+ */
+enum wl_text_input_content_hint {
+       WL_TEXT_INPUT_CONTENT_HINT_NONE = 0x0,
+       WL_TEXT_INPUT_CONTENT_HINT_DEFAULT = 0x7,
+       WL_TEXT_INPUT_CONTENT_HINT_PASSWORD = 0xc0,
+       WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION = 0x1,
+       WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION = 0x2,
+       WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 0x4,
+       WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE = 0x8,
+       WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE = 0x10,
+       WL_TEXT_INPUT_CONTENT_HINT_TITLECASE = 0x20,
+       WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT = 0x40,
+       WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA = 0x80,
+       WL_TEXT_INPUT_CONTENT_HINT_LATIN = 0x100,
+       WL_TEXT_INPUT_CONTENT_HINT_MULTILINE = 0x200,
+};
+#endif /* WL_TEXT_INPUT_CONTENT_HINT_ENUM */
+
+#ifndef WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM
+#define WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM
+/**
+ * wl_text_input_content_purpose - content purpose
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL: default input, allowing all
+ *     characters
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA: allow only alphabetic characters
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS: allow only digits
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER: input a number (including
+ *     decimal separator and sign)
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE: input a phone number
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_URL: input an URL
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL: input an email address
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_NAME: input a name of a person
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD: input a password (combine
+ *     with password or sensitive_data hint)
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_DATE: input a date
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_TIME: input a time
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME: input a date and time
+ * @WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL: input for a terminal
+ *
+ * The content purpose allows to specify the primary purpose of a text
+ * input.
+ *
+ * This allows an input method to show special purpose input panels with
+ * extra characters or to disallow some characters.
+ */
+enum wl_text_input_content_purpose {
+       WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL = 0,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA = 1,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS = 2,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER = 3,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE = 4,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_URL = 5,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL = 6,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_NAME = 7,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD = 8,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_DATE = 9,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_TIME = 10,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME = 11,
+       WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL = 12,
+};
+#endif /* WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM */
+
+#ifndef WL_TEXT_INPUT_PREEDIT_STYLE_ENUM
+#define WL_TEXT_INPUT_PREEDIT_STYLE_ENUM
+enum wl_text_input_preedit_style {
+       WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT = 0,
+       WL_TEXT_INPUT_PREEDIT_STYLE_NONE = 1,
+       WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE = 2,
+       WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE = 3,
+       WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT = 4,
+       WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE = 5,
+       WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION = 6,
+       WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT = 7,
+};
+#endif /* WL_TEXT_INPUT_PREEDIT_STYLE_ENUM */
+
+#ifndef WL_TEXT_INPUT_TEXT_DIRECTION_ENUM
+#define WL_TEXT_INPUT_TEXT_DIRECTION_ENUM
+enum wl_text_input_text_direction {
+       WL_TEXT_INPUT_TEXT_DIRECTION_AUTO = 0,
+       WL_TEXT_INPUT_TEXT_DIRECTION_LTR = 1,
+       WL_TEXT_INPUT_TEXT_DIRECTION_RTL = 2,
+};
+#endif /* WL_TEXT_INPUT_TEXT_DIRECTION_ENUM */
+
+/**
+ * wl_text_input - text input
+ * @enter: enter event
+ * @leave: leave event
+ * @modifiers_map: modifiers map
+ * @input_panel_state: state of the input panel
+ * @preedit_string: pre-edit
+ * @preedit_styling: pre-edit styling
+ * @preedit_cursor: pre-edit cursor
+ * @commit_string: commit
+ * @cursor_position: set cursor to new position
+ * @delete_surrounding_text: delete surrounding text
+ * @keysym: keysym
+ * @language: language
+ * @text_direction: text direction
+ *
+ * An object used for text input. Adds support for text input and input
+ * methods to applications. A text-input object is created from a
+ * wl_text_input_manager and corresponds typically to a text entry in an
+ * application. Requests are used to activate/deactivate the text-input
+ * object and set state information like surrounding and selected text or
+ * the content type. The information about entered text is sent to the
+ * text-input object via the pre-edit and commit events. Using this
+ * interface removes the need for applications to directly process hardware
+ * key events and compose text out of them.
+ *
+ * Text is generally UTF-8 encoded, indices and lengths are in bytes.
+ *
+ * Serials are used to synchronize the state between the text input and an
+ * input method. New serials are sent by the text input in the commit_state
+ * request and are used by the input method to indicate the known text
+ * input state in events like preedit_string, commit_string, and keysym.
+ * The text input can then ignore events from the input method which are
+ * based on an outdated state (for example after a reset).
+ */
+struct wl_text_input_listener {
+       /**
+        * enter - enter event
+        * @surface: (none)
+        *
+        * Notify the text-input object when it received focus. Typically
+        * in response to an activate request.
+        */
+       void (*enter)(void *data,
+                     struct wl_text_input *wl_text_input,
+                     struct wl_surface *surface);
+       /**
+        * leave - leave event
+        *
+        * Notify the text-input object when it lost focus. Either in
+        * response to a deactivate request or when the assigned surface
+        * lost focus or was destroyed.
+        */
+       void (*leave)(void *data,
+                     struct wl_text_input *wl_text_input);
+       /**
+        * modifiers_map - modifiers map
+        * @map: (none)
+        *
+        * Transfer an array of 0-terminated modifiers names. The
+        * position in the array is the index of the modifier as used in
+        * the modifiers bitmask in the keysym event.
+        */
+       void (*modifiers_map)(void *data,
+                             struct wl_text_input *wl_text_input,
+                             struct wl_array *map);
+       /**
+        * input_panel_state - state of the input panel
+        * @state: (none)
+        *
+        * Notify when the visibility state of the input panel changed.
+        */
+       void (*input_panel_state)(void *data,
+                                 struct wl_text_input *wl_text_input,
+                                 uint32_t state);
+       /**
+        * preedit_string - pre-edit
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        * @commit: (none)
+        *
+        * Notify when a new composing text (pre-edit) should be set
+        * around the current cursor position. Any previously set composing
+        * text should be removed.
+        *
+        * The commit text can be used to replace the preedit text on reset
+        * (for example on unfocus).
+        *
+        * The text input should also handle all preedit_style and
+        * preedit_cursor events occuring directly before preedit_string.
+        */
+       void (*preedit_string)(void *data,
+                              struct wl_text_input *wl_text_input,
+                              uint32_t serial,
+                              const char *text,
+                              const char *commit);
+       /**
+        * preedit_styling - pre-edit styling
+        * @index: (none)
+        * @length: (none)
+        * @style: (none)
+        *
+        * Sets styling information on composing text. The style is
+        * applied for length bytes from index relative to the beginning of
+        * the composing text (as byte offset). Multiple styles can be
+        * applied to a composing text by sending multiple preedit_styling
+        * events.
+        *
+        * This event is handled as part of a following preedit_string
+        * event.
+        */
+       void (*preedit_styling)(void *data,
+                               struct wl_text_input *wl_text_input,
+                               uint32_t index,
+                               uint32_t length,
+                               uint32_t style);
+       /**
+        * preedit_cursor - pre-edit cursor
+        * @index: (none)
+        *
+        * Sets the cursor position inside the composing text (as byte
+        * offset) relative to the start of the composing text. When index
+        * is a negative number no cursor is shown.
+        *
+        * This event is handled as part of a following preedit_string
+        * event.
+        */
+       void (*preedit_cursor)(void *data,
+                              struct wl_text_input *wl_text_input,
+                              int32_t index);
+       /**
+        * commit_string - commit
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        *
+        * Notify when text should be inserted into the editor widget.
+        * The text to commit could be either just a single character after
+        * a key press or the result of some composing (pre-edit). It could
+        * be also an empty text when some text should be removed (see
+        * delete_surrounding_text) or when the input cursor should be
+        * moved (see cursor_position).
+        *
+        * Any previously set composing text should be removed.
+        */
+       void (*commit_string)(void *data,
+                             struct wl_text_input *wl_text_input,
+                             uint32_t serial,
+                             const char *text);
+       /**
+        * cursor_position - set cursor to new position
+        * @index: (none)
+        * @anchor: (none)
+        *
+        * Notify when the cursor or anchor position should be modified.
+        *
+        * This event should be handled as part of a following
+        * commit_string event.
+        */
+       void (*cursor_position)(void *data,
+                               struct wl_text_input *wl_text_input,
+                               int32_t index,
+                               int32_t anchor);
+       /**
+        * delete_surrounding_text - delete surrounding text
+        * @index: (none)
+        * @length: (none)
+        *
+        * Notify when the text around the current cursor position should
+        * be deleted.
+        *
+        * Index is relative to the current cursor (in bytes). Length is
+        * the length of deleted text (in bytes).
+        *
+        * This event should be handled as part of a following
+        * commit_string event.
+        */
+       void (*delete_surrounding_text)(void *data,
+                                       struct wl_text_input *wl_text_input,
+                                       int32_t index,
+                                       uint32_t length);
+       /**
+        * keysym - keysym
+        * @serial: serial of the latest known text input state
+        * @time: (none)
+        * @sym: (none)
+        * @state: (none)
+        * @modifiers: (none)
+        *
+        * Notify when a key event was sent. Key events should not be
+        * used for normal text input operations, which should be done with
+        * commit_string, delete_surrounding_text, etc. The key event
+        * follows the wl_keyboard key event convention. Sym is a XKB
+        * keysym, state a wl_keyboard key_state. Modifiers are a mask for
+        * effective modifiers (where the modifier indices are set by the
+        * modifiers_map event)
+        */
+       void (*keysym)(void *data,
+                      struct wl_text_input *wl_text_input,
+                      uint32_t serial,
+                      uint32_t time,
+                      uint32_t sym,
+                      uint32_t state,
+                      uint32_t modifiers);
+       /**
+        * language - language
+        * @serial: serial of the latest known text input state
+        * @language: (none)
+        *
+        * Sets the language of the input text. The "language" argument
+        * is a RFC-3066 format language tag.
+        */
+       void (*language)(void *data,
+                        struct wl_text_input *wl_text_input,
+                        uint32_t serial,
+                        const char *language);
+       /**
+        * text_direction - text direction
+        * @serial: serial of the latest known text input state
+        * @direction: (none)
+        *
+        * Sets the text direction of input text.
+        *
+        * It is mainly needed for showing input cursor on correct side of
+        * the editor when there is no input yet done and making sure
+        * neutral direction text is laid out properly.
+        */
+       void (*text_direction)(void *data,
+                              struct wl_text_input *wl_text_input,
+                              uint32_t serial,
+                              uint32_t direction);
+};
+
+static inline int
+wl_text_input_add_listener(struct wl_text_input *wl_text_input,
+                          const struct wl_text_input_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_text_input,
+                                    (void (**)(void)) listener, data);
+}
+
+#define WL_TEXT_INPUT_ACTIVATE 0
+#define WL_TEXT_INPUT_DEACTIVATE       1
+#define WL_TEXT_INPUT_SHOW_INPUT_PANEL 2
+#define WL_TEXT_INPUT_HIDE_INPUT_PANEL 3
+#define WL_TEXT_INPUT_RESET    4
+#define WL_TEXT_INPUT_SET_SURROUNDING_TEXT     5
+#define WL_TEXT_INPUT_SET_CONTENT_TYPE 6
+#define WL_TEXT_INPUT_SET_CURSOR_RECTANGLE     7
+#define WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE   8
+#define WL_TEXT_INPUT_COMMIT_STATE     9
+#define WL_TEXT_INPUT_INVOKE_ACTION    10
+
+static inline void
+wl_text_input_set_user_data(struct wl_text_input *wl_text_input, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_text_input, user_data);
+}
+
+static inline void *
+wl_text_input_get_user_data(struct wl_text_input *wl_text_input)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input);
+}
+
+static inline void
+wl_text_input_destroy(struct wl_text_input *wl_text_input)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_text_input);
+}
+
+static inline void
+wl_text_input_activate(struct wl_text_input *wl_text_input, struct wl_seat *seat, struct wl_surface *surface)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_ACTIVATE, seat, surface);
+}
+
+static inline void
+wl_text_input_deactivate(struct wl_text_input *wl_text_input, struct wl_seat *seat)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_DEACTIVATE, seat);
+}
+
+static inline void
+wl_text_input_show_input_panel(struct wl_text_input *wl_text_input)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_SHOW_INPUT_PANEL);
+}
+
+static inline void
+wl_text_input_hide_input_panel(struct wl_text_input *wl_text_input)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_HIDE_INPUT_PANEL);
+}
+
+static inline void
+wl_text_input_reset(struct wl_text_input *wl_text_input)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_RESET);
+}
+
+static inline void
+wl_text_input_set_surrounding_text(struct wl_text_input *wl_text_input, const char *text, uint32_t cursor, uint32_t anchor)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_SET_SURROUNDING_TEXT, text, cursor, anchor);
+}
+
+static inline void
+wl_text_input_set_content_type(struct wl_text_input *wl_text_input, uint32_t hint, uint32_t purpose)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_SET_CONTENT_TYPE, hint, purpose);
+}
+
+static inline void
+wl_text_input_set_cursor_rectangle(struct wl_text_input *wl_text_input, int32_t x, int32_t y, int32_t width, int32_t height)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_SET_CURSOR_RECTANGLE, x, y, width, height);
+}
+
+static inline void
+wl_text_input_set_preferred_language(struct wl_text_input *wl_text_input, const char *language)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE, language);
+}
+
+static inline void
+wl_text_input_commit_state(struct wl_text_input *wl_text_input, uint32_t serial)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_COMMIT_STATE, serial);
+}
+
+static inline void
+wl_text_input_invoke_action(struct wl_text_input *wl_text_input, uint32_t button, uint32_t index)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input,
+                        WL_TEXT_INPUT_INVOKE_ACTION, button, index);
+}
+
+#define WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT        0
+
+static inline void
+wl_text_input_manager_set_user_data(struct wl_text_input_manager *wl_text_input_manager, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_text_input_manager, user_data);
+}
+
+static inline void *
+wl_text_input_manager_get_user_data(struct wl_text_input_manager *wl_text_input_manager)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input_manager);
+}
+
+static inline void
+wl_text_input_manager_destroy(struct wl_text_input_manager *wl_text_input_manager)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_text_input_manager);
+}
+
+static inline struct wl_text_input *
+wl_text_input_manager_create_text_input(struct wl_text_input_manager *wl_text_input_manager)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_create((struct wl_proxy *) wl_text_input_manager,
+                            &wl_text_input_interface);
+       if (!id)
+               return NULL;
+
+       wl_proxy_marshal((struct wl_proxy *) wl_text_input_manager,
+                        WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT, id);
+
+       return (struct wl_text_input *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/ism/extras/efl_wsc/text-protocol.c b/ism/extras/efl_wsc/text-protocol.c
new file mode 100644 (file)
index 0000000..3906811
--- /dev/null
@@ -0,0 +1,94 @@
+/* 
+ * Copyright Â© 2012, 2013 Intel Corporation
+ * 
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+extern const struct wl_interface wl_seat_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_seat_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_text_input_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_seat_interface,
+       &wl_surface_interface,
+       &wl_seat_interface,
+       &wl_surface_interface,
+       &wl_text_input_interface,
+};
+
+static const struct wl_message wl_text_input_requests[] = {
+       { "activate", "oo", types + 5 },
+       { "deactivate", "o", types + 7 },
+       { "show_input_panel", "", types + 0 },
+       { "hide_input_panel", "", types + 0 },
+       { "reset", "", types + 0 },
+       { "set_surrounding_text", "suu", types + 0 },
+       { "set_content_type", "uu", types + 0 },
+       { "set_cursor_rectangle", "iiii", types + 0 },
+       { "set_preferred_language", "s", types + 0 },
+       { "commit_state", "u", types + 0 },
+       { "invoke_action", "uu", types + 0 },
+};
+
+static const struct wl_message wl_text_input_events[] = {
+       { "enter", "o", types + 8 },
+       { "leave", "", types + 0 },
+       { "modifiers_map", "a", types + 0 },
+       { "input_panel_state", "u", types + 0 },
+       { "preedit_string", "uss", types + 0 },
+       { "preedit_styling", "uuu", types + 0 },
+       { "preedit_cursor", "i", types + 0 },
+       { "commit_string", "us", types + 0 },
+       { "cursor_position", "ii", types + 0 },
+       { "delete_surrounding_text", "iu", types + 0 },
+       { "keysym", "uuuuu", types + 0 },
+       { "language", "us", types + 0 },
+       { "text_direction", "uu", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface wl_text_input_interface = {
+       "wl_text_input", 1,
+       11, wl_text_input_requests,
+       13, wl_text_input_events,
+};
+
+static const struct wl_message wl_text_input_manager_requests[] = {
+       { "create_text_input", "n", types + 9 },
+};
+
+WL_EXPORT const struct wl_interface wl_text_input_manager_interface = {
+       "wl_text_input_manager", 1,
+       1, wl_text_input_manager_requests,
+       0, NULL,
+};
+
diff --git a/ism/extras/efl_wsm/Makefile.am b/ism/extras/efl_wsm/Makefile.am
new file mode 100644 (file)
index 0000000..65a7033
--- /dev/null
@@ -0,0 +1,41 @@
+MAINTAINERCLEANFILES = Makefile.in
+CLEANFILES           = *.bak *.edj
+
+INCLUDES = -I$(top_builddir) \
+           -I$(top_builddir)/ism/src \
+           -I$(top_srcdir) \
+           -I$(top_srcdir)/ism/src \
+           -I$(top_srcdir)/ism/intl \
+           -I$(top_srcdir)/ism/data \
+           -I$(top_srcdir)/ism/utils \
+           -I$(includedir) \
+           -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \
+           -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \
+           -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \
+           -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \
+           -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \
+           -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \
+           -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\"
+
+noinst_HEADERS = isf_wsm_utility.h
+
+if ISF_BUILD_WSM_EFL
+CONFIG_WSM_EFL  = isf-wsm-efl
+endif
+
+bin_PROGRAMS           = $(CONFIG_WSM_EFL)
+
+isf_wsm_efl_SOURCES  = isf_wsm_efl.cpp \
+                         isf_wsm_utility.cpp
+
+isf_wsm_efl_CXXFLAGS = @EFL_CFLAGS@ @VCONF_CFLAGS@ @DLOG_CFLAGS@ @TTS_CFLAGS@ @FEEDBACK_CFLAGS@
+
+isf_wsm_efl_LDFLAGS  = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \
+                         @VCONF_LIBS@ \
+                         @WAYLAND_LIBS@ \
+                         @DLOG_LIBS@ \
+                         @TTS_LIBS@ \
+                         @FEEDBACK_LIBS@
+
+isf_wsm_efl_LDADD    = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la
+
diff --git a/ism/extras/efl_wsm/isf_wsm_efl.cpp b/ism/extras/efl_wsm/isf_wsm_efl.cpp
new file mode 100644 (file)
index 0000000..2120f54
--- /dev/null
@@ -0,0 +1,4537 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more fitable.
+ * Copyright (c) 2012-2014 Intel Co., Ltd.
+ *
+ * Contact: Yan Wang <yan.wang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_CONFIG_PATH
+#define Uses_SCIM_HELPER_MODULE
+#define Uses_SCIM_PANEL_AGENT
+#define Uses_SCIM_COMPOSE_KEY
+#define Uses_SCIM_IMENGINE_MODULE
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <list>
+#include <glib.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Wayland.h>
+#include <Ecore_File.h>
+#include <Elementary.h>
+#include <malloc.h>
+#include "scim_private.h"
+#include "scim.h"
+#include "scim_stl_map.h"
+#if HAVE_VCONF
+#include <vconf.h>
+#include <vconf-keys.h>
+#endif
+#include <privilege-control.h>
+#include "isf_wsm_utility.h"
+#include <dlog.h>
+#if HAVE_TTS
+#include <tts.h>
+#endif
+#if HAVE_FEEDBACK
+#include <feedback.h>
+#endif
+
+using namespace scim;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of macro.
+/////////////////////////////////////////////////////////////////////////////
+#define EFL_CANDIDATE_THEME1                            (SCIM_DATADIR "/isf_candidate_theme1.edj")
+
+#define ISF_CANDIDATE_TABLE                             0
+
+#define ISF_EFL_AUX                                     1
+#define ISF_EFL_CANDIDATE_0                             2
+#define ISF_EFL_CANDIDATE_ITEMS                         3
+
+#define ISE_DEFAULT_HEIGHT_PORTRAIT                     444
+#define ISE_DEFAULT_HEIGHT_LANDSCAPE                    316
+
+#define ISF_SYSTEM_APPSERVICE_READY_VCONF               "memory/appservice/status"
+#define ISF_SYSTEM_APPSERVICE_READY_STATE               1
+#define ISF_SYSTEM_WM_WAIT_COUNT                        200
+#define ISF_SYSTEM_WAIT_DELAY                           100 * 1000
+#define ISF_CANDIDATE_DESTROY_DELAY                     3
+
+#define ISF_PREEDIT_BORDER                              16
+
+#define LOG_TAG                                         "ISF_WSM_EFL"
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of external variables.
+/////////////////////////////////////////////////////////////////////////////
+extern MapStringVectorSizeT         _groups;
+extern std::vector<String>          _uuids;
+extern std::vector<String>          _names;
+extern std::vector<String>          _module_names;
+extern std::vector<String>          _langs;
+extern std::vector<String>          _icons;
+extern std::vector<uint32>          _options;
+extern std::vector<TOOLBAR_MODE_T>  _modes;
+
+extern EAPI CommonLookupTable       g_isf_candidate_table;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of internal data types.
+/////////////////////////////////////////////////////////////////////////////
+typedef enum _WINDOW_STATE {
+    WINDOW_STATE_HIDE = 0,
+    WINDOW_STATE_WILL_HIDE,
+    WINDOW_STATE_WILL_SHOW,
+    WINDOW_STATE_SHOW,
+    WINDOW_STATE_ON,
+} WINDOW_STATE;
+
+typedef std::map <String, Ecore_File_Monitor *>  OSPEmRepository;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of internal functions.
+/////////////////////////////////////////////////////////////////////////////
+static Evas_Object *efl_create_window                  (const char *strWinName, const char *strEffect);
+static void       efl_set_transient_for_app_window     (Ecore_X_Window window);
+static int        efl_get_angle_for_app_window         (void);
+static int        efl_get_angle_for_ise_window         (void);
+
+static int        ui_candidate_get_valid_height        (void);
+static void       ui_candidate_hide                    (bool bForce, bool bSetVirtualKbd = true, bool will_hide = false);
+static void       ui_destroy_candidate_window          (void);
+static void       ui_settle_candidate_window           (void);
+static void       ui_candidate_show                    (bool bSetVirtualKbd = true);
+static void       ui_create_candidate_window           (void);
+static void       update_table                         (int table_type, const LookupTable &table);
+static void       ui_candidate_window_close_button_cb  (void *data, Evas *e, Evas_Object *button, void *event_info);
+
+static bool       check_wm_ready                       (void);
+static bool       check_system_ready                   (void);
+static void       launch_default_soft_keyboard         (keynode_t *key = NULL, void* data = NULL);
+
+/* PanelAgent related functions */
+static bool       initialize_panel_agent               (const String &config, const String &display, bool resident);
+
+static void       slot_reload_config                   (void);
+static void       slot_focus_in                        (void);
+static void       slot_focus_out                       (void);
+static void       slot_expand_candidate                (void);
+static void       slot_contract_candidate              (void);
+static void       slot_set_candidate_style             (int portrait_line, int mode);
+static void       slot_update_input_context            (int type, int value);
+static void       slot_update_ise_geometry             (int x, int y, int width, int height);
+static void       slot_update_spot_location            (int x, int y, int top_y);
+static void       slot_update_factory_info             (const PanelFactoryInfo &info);
+static void       slot_show_preedit_string             (void);
+static void       slot_show_aux_string                 (void);
+static void       slot_show_candidate_table            (void);
+static void       slot_hide_preedit_string             (void);
+static void       slot_hide_aux_string                 (void);
+static void       slot_hide_candidate_table            (void);
+static void       slot_update_preedit_string           (const String &str, const AttributeList &attrs, int caret);
+static void       slot_update_preedit_caret            (int caret);
+static void       slot_update_aux_string               (const String &str, const AttributeList &attrs);
+static void       slot_update_candidate_table          (const LookupTable &table);
+static void       slot_select_candidate                (int index);
+static void       slot_set_active_ise                  (const String &uuid, bool changeDefault);
+static bool       slot_get_ise_list                    (std::vector<String> &list);
+static bool       slot_get_ise_information             (String uuid, String &name, String &language, int &type, int &option, String &module_name);
+static bool       slot_get_keyboard_ise_list           (std::vector<String> &name_list);
+static void       slot_get_language_list               (std::vector<String> &name);
+static void       slot_get_all_language                (std::vector<String> &lang);
+static void       slot_get_ise_language                (char *name, std::vector<String> &list);
+static bool       slot_get_ise_info                    (const String &uuid, ISE_INFO &info);
+static void       slot_get_candidate_geometry          (struct rectinfo &info);
+static void       slot_get_input_panel_geometry        (struct rectinfo &info);
+static void       slot_set_keyboard_ise                (const String &uuid);
+static void       slot_get_keyboard_ise                (String &ise_name, String &ise_uuid);
+static void       slot_accept_connection               (int fd);
+static void       slot_close_connection                (int fd);
+static void       slot_exit                            (void);
+
+static void       slot_register_helper_properties      (int id, const PropertyList &props);
+static void       slot_show_ise                        (void);
+static void       slot_hide_ise                        (void);
+
+static void       slot_will_hide_ack                   (void);
+static void       slot_candidate_will_hide_ack         (void);
+
+static void       slot_get_ise_state                   (int &state);
+
+static Eina_Bool  panel_agent_handler                  (void *data, Ecore_Fd_Handler *fd_handler);
+
+static Eina_Bool  efl_create_control_window            (void);
+static void       _launch_default_soft_keyboard        (void);
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of internal variables.
+/////////////////////////////////////////////////////////////////////////////
+static Evas_Object       *_candidate_window                 = 0;
+static Evas_Object       *_candidate_area_1                 = 0;
+static Evas_Object       *_candidate_area_2                 = 0;
+static Evas_Object       *_candidate_bg                     = 0;
+static Evas_Object       *_candidate_0_scroll               = 0;
+static Evas_Object       *_candidate_scroll                 = 0;
+static Evas_Object       *_scroller_bg                      = 0;
+static Evas_Object       *_candidate_0_table                = 0;
+static Evas_Object       *_candidate_table                  = 0;
+static Evas_Object       *_candidate_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_candidate_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_seperate_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_seperate_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_line_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_line_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE];
+static Evas_Object       *_more_btn                         = 0;
+static Evas_Object       *_close_btn                        = 0;
+static bool               _candidate_show_requested         = false;
+
+static int                _candidate_x                      = 0;
+static int                _candidate_y                      = 0;
+static int                _candidate_width                  = 0;
+static int                _candidate_height                 = 0;
+static int                _candidate_valid_height           = 0;
+
+static bool               _candidate_area_1_visible         = false;
+static bool               _candidate_area_2_visible         = false;
+static bool               _aux_area_visible                 = false;
+
+static ISF_CANDIDATE_MODE_T          _candidate_mode        = SOFT_CANDIDATE_WINDOW;
+static ISF_CANDIDATE_PORTRAIT_LINE_T _candidate_port_line   = ONE_LINE_CANDIDATE;
+
+static int                _candidate_port_width             = 480;
+static int                _candidate_port_height_min        = 76;
+static int                _candidate_port_height_min_2      = 150;
+static int                _candidate_port_height_max        = 286;
+static int                _candidate_port_height_max_2      = 350;
+static int                _candidate_land_width             = 784;
+static int                _candidate_land_height_min        = 84;
+static int                _candidate_land_height_min_2      = 168;
+static int                _candidate_land_height_max        = 150;
+static int                _candidate_land_height_max_2      = 214;
+static int                _candidate_area_1_pos [2]         = {0, 2};
+static int                _more_btn_pos [4]                 = {369, 11, 689, 11};
+static int                _close_btn_pos [4]                = {362, 211, 682, 75};
+
+static int                _v_padding                        = 2;
+static int                _item_min_width                   = 99;
+static int                _item_min_height                  = 82;
+
+static int                _candidate_scroll_0_width_min     = 350;
+static int                _candidate_scroll_0_width_max     = 670;
+
+static int                _candidate_scroll_width           = 453;
+static int                _candidate_scroll_width_min       = 453;
+static int                _candidate_scroll_width_max       = 663;
+static int                _candidate_scroll_height_min      = 124;
+static int                _candidate_scroll_height_max      = 190;
+
+static Evas_Object       *_preedit_window                   = 0;
+static Evas_Object       *_preedit_text                     = 0;
+static int                _preedit_width                    = 100;
+static int                _preedit_height                   = 54;
+
+static Evas_Object       *_aux_area                         = 0;
+static Evas_Object       *_aux_line                         = 0;
+static Evas_Object       *_aux_table                        = 0;
+static int                _aux_height                       = 0;
+static int                _aux_port_width                   = 444;
+static int                _aux_land_width                   = 764;
+static std::vector<Evas_Object *> _aux_items;
+static std::vector<Evas_Object *> _aux_seperates;
+
+static Evas_Object       *_tmp_preedit_text                 = 0;
+static Evas_Object       *_tmp_aux_text                     = 0;
+static Evas_Object       *_tmp_candidate_text               = 0;
+
+static int                _spot_location_x                  = -1;
+static int                _spot_location_y                  = -1;
+static int                _spot_location_top_y              = -1;
+static int                _candidate_angle                  = 0;
+static int                _window_angle                     = -1;
+
+static int                _ise_width                        = 0;
+static int                _ise_height                       = 0;
+static WINDOW_STATE       _ise_state                        = WINDOW_STATE_HIDE;
+static WINDOW_STATE       _candidate_state                  = WINDOW_STATE_HIDE;
+
+static int                _indicator_height                 = 0;//24;
+static int                _screen_width                     = 720;
+static int                _screen_height                    = 1280;
+static float              _width_rate                       = 1.0;
+static float              _height_rate                      = 1.0;
+static int                _blank_width                      = 30;
+
+static String             _candidate_name                   = String ("candidate");
+static String             _candidate_edje_file              = String (EFL_CANDIDATE_THEME1);
+
+static String             _candidate_font_name              = String ("Tizen");
+static int                _candidate_font_size              = 38;
+static int                _aux_font_size                    = 38;
+static int                _click_object                     = 0;
+static int                _click_down_pos [2]               = {0, 0};
+static int                _click_up_pos [2]                 = {0, 0};
+static bool               _is_click                         = true;
+static bool               _appsvc_callback_regist           = false;
+static String             _initial_ise_uuid                 = String ("");
+static ConfigPointer      _config;
+static PanelAgent        *_panel_agent                      = 0;
+static std::vector<Ecore_Fd_Handler *> _read_handler_list;
+
+static clock_t            _clock_start;
+
+static Ecore_Timer       *_check_size_timer                 = NULL;
+static Ecore_Timer       *_longpress_timer                  = NULL;
+static Ecore_Timer       *_destroy_timer                    = NULL;
+static Ecore_Timer       *_system_ready_timer               = NULL;
+static Ecore_Timer       *_off_prepare_done_timer           = NULL;
+static Ecore_Timer       *_candidate_hide_timer             = NULL;
+
+static Ecore_X_Window     _ise_window                       = 0;
+static Ecore_X_Window     _app_window                       = 0;
+static Ecore_X_Window     _control_window                   = 0;
+
+static Ecore_File_Monitor *_inh_helper_ise_em               = NULL;
+static Ecore_File_Monitor *_inh_keyboard_ise_em             = NULL;
+static Ecore_File_Monitor *_osp_helper_ise_em               = NULL;
+static Ecore_File_Monitor *_osp_keyboard_ise_em             = NULL;
+static OSPEmRepository     _osp_bin_em;
+static OSPEmRepository     _osp_info_em;
+
+static bool               hw_kbd_mode                       = false;
+
+#if HAVE_TTS
+static tts_h              _tts                              = NULL;
+#endif
+
+#if HAVE_FEEDBACK
+static bool               feedback_initialized              = false;
+#endif
+
+static Ecore_Event_Handler *_candidate_show_handler         = NULL;
+
+/* This structure stores the geometry information reported by ISE */
+struct GeometryCache
+{
+    bool valid;                /* Whether this information is currently valid */
+    int angle;                 /* For which angle this information is useful */
+    struct rectinfo geometry;  /* Geometry information */
+};
+static struct GeometryCache _ise_reported_geometry          = {0};
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementation of internal functions.
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief Print system time point for panel performance.
+ *
+ * @param strInfo The output information.
+ */
+static void check_time (const char *strInfo)
+{
+    gettime (_clock_start, strInfo);
+    ISF_LOG ("%s ppid=%d pid=%d\n", strInfo, getppid (), getpid ());
+}
+
+/**
+ * @brief Check the specific file.
+ *
+ * @param strFile The file path.
+ *
+ * @return true if the file is existed, otherwise false.
+ */
+static bool check_file (const char* strFile)
+{
+    struct stat st;
+
+    /* Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor */
+    if (stat (strFile, &st) < 0 && strcmp (strFile, "/"))
+        return false;
+    else
+        return true;
+}
+
+/**
+ * @brief Flush memory for elm.
+ *
+ * @return void
+ */
+static void flush_memory (void)
+{
+    elm_cache_all_flush ();
+    malloc_trim (0);
+}
+
+/**
+ * @brief Get ISE geometry information.
+ *        Returns the "expected" ISE geometry when kbd_state is ON, otherwise w/h set to 0
+ *
+ * @param info The data is used to store ISE position and size.
+ * @param kbd_state The keyboard state.
+ */
+static struct rectinfo get_ise_geometry ()
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    struct rectinfo info = {0, 0, 0, 0};
+
+    int win_w = _screen_width, win_h = _screen_height;
+    int angle = (_window_angle == -1) ? efl_get_angle_for_app_window () : _window_angle;
+
+    if (angle == 90 || angle == 270) {
+        win_w = _screen_height;
+        win_h = _screen_width;
+    }
+
+    /* If we have geometry reported by ISE, use the geometry information */
+    if (_ise_reported_geometry.valid && _ise_reported_geometry.angle == angle) {
+        info = _ise_reported_geometry.geometry;
+    } else {
+        /* READ ISE's SIZE HINT HERE */
+        int pos_x, pos_y, width, height;
+        
+        // FIXME: Get the ISE's SIZE.
+        pos_x = 0;
+        pos_y = 0;
+        width = 0;
+        height = 0;
+
+        info.pos_x = pos_x;
+        info.pos_y = pos_y;
+        info.width = width;
+        info.height = height;
+    }
+    _ise_width  = info.width;
+    _ise_height = info.height;
+
+    return info;
+}
+
+/**
+ * @brief Set keyboard geometry for autoscroll.
+ *        This includes the ISE geometry together with candidate window
+ *
+ * @param kbd_state The keyboard state.
+ */
+static void set_keyboard_geometry_atom_info (Ecore_X_Window window, struct rectinfo ise_rect)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (hw_kbd_mode) {
+        ise_rect.pos_x = 0;
+        if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+            ise_rect.width  = _candidate_width;
+            ise_rect.height = _candidate_height;
+        }
+        int angle = efl_get_angle_for_app_window ();
+        if (angle == 90 || angle == 270)
+            ise_rect.pos_y = _screen_width - ise_rect.height;
+        else
+            ise_rect.pos_y = _screen_height - ise_rect.height;
+    } else {
+        if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+            if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+                _candidate_valid_height = ui_candidate_get_valid_height ();
+                if ((_candidate_height - _candidate_valid_height) > _ise_height) {
+                    _candidate_valid_height = _candidate_height;
+                    ise_rect.pos_y  = ise_rect.pos_y + ise_rect.height - _candidate_height;
+                    ise_rect.height = _candidate_height;
+                } else {
+                    ise_rect.pos_y  -= _candidate_valid_height;
+                    ise_rect.height += _candidate_valid_height;
+                }
+            }
+        }
+    }
+
+    // FIXME: Ecore_X dependency.
+}
+
+/**
+ * @brief Get ISE index according to uuid.
+ *
+ * @param uuid The ISE uuid.
+ *
+ * @return The ISE index
+ */
+static int get_ise_index (const String uuid)
+{
+    int index = 0;
+    if (uuid.length () > 0) {
+        for (unsigned int i = 0; i < _uuids.size (); i++) {
+            if (uuid == _uuids[i]) {
+                index = i;
+                break;
+            }
+        }
+    }
+
+    return index;
+}
+
+/**
+ * @brief Get ISE module file path.
+ *
+ * @param module_name The ISE's module name.
+ * @param type The ISE's type.
+ *
+ * @return ISE module file path if successfully, otherwise return empty string.
+ */
+static String get_module_file_path (const String &module_name, const String &type)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    String strFile;
+    if (module_name.substr (0, 1) == String ("/")) {
+        strFile = module_name + String (".so");
+        if (access (strFile.c_str (), R_OK) == 0)
+            return strFile;
+    }
+
+    /* Check inhouse path */
+    strFile = String (SCIM_MODULE_PATH) +
+              String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+              String (SCIM_PATH_DELIM_STRING) + type +
+              String (SCIM_PATH_DELIM_STRING) + module_name + String (".so");
+    if (access (strFile.c_str (), R_OK) == 0)
+        return strFile;
+
+    const char *module_path_env = getenv ("SCIM_MODULE_PATH");
+    if (module_path_env) {
+        strFile = String (module_path_env) +
+                  String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+                  String (SCIM_PATH_DELIM_STRING) + type +
+                  String (SCIM_PATH_DELIM_STRING) + module_name + String (".so");
+        if (access (strFile.c_str (), R_OK) == 0)
+            return strFile;
+    }
+
+    return String ("");
+}
+
+/**
+ * @brief Get module names for all 3rd party's IMEs.
+ * @param ops_module_names The list to store module names for all 3rd party's IMEs.
+ * @return module name list size
+ */
+static int osp_module_list_get (std::vector <String> &ops_module_names)
+{
+    const char *module_path_env = getenv ("SCIM_MODULE_PATH");
+    if (module_path_env) {
+        String path = String (module_path_env) +
+                      String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+                      String (SCIM_PATH_DELIM_STRING) + String ("Helper");
+        ops_module_names.clear ();
+
+        DIR *dir = opendir (path.c_str ());
+        if (dir) {
+            struct dirent *file = readdir (dir);
+            while (file) {
+                struct stat filestat;
+                String absfn = path + String (SCIM_PATH_DELIM_STRING) + file->d_name;
+                stat (absfn.c_str (), &filestat);
+                if (S_ISREG (filestat.st_mode)) {
+                    String link_name = String (file->d_name);
+                    ops_module_names.push_back (link_name.substr (0, link_name.find_last_of ('.')));
+                }
+
+                file = readdir (dir);
+            }
+            closedir (dir);
+        }
+    }
+
+    std::sort (ops_module_names.begin (), ops_module_names.end ());
+    ops_module_names.erase (std::unique (ops_module_names.begin (), ops_module_names.end ()), ops_module_names.end ());
+
+    return ops_module_names.size ();
+}
+
+static String osp_module_name_get (const String &path)
+{
+    String pkg_id   = path.substr (path.find_last_of (SCIM_PATH_DELIM) + 1);
+    String ise_name = String ("");
+    String bin_path = path + String ("/bin");
+    DIR *dir = opendir (bin_path.c_str ());
+    if (dir) {
+        struct dirent *file = readdir (dir);
+        while (file) {
+            struct stat filestat;
+            String absfn = bin_path + String (SCIM_PATH_DELIM_STRING) + file->d_name;
+            stat (absfn.c_str (), &filestat);
+            if (S_ISREG (filestat.st_mode)) {
+                String ext = absfn.substr (absfn.length () - 4);
+                if (ext == String (".exe")) {
+                    int begin = absfn.find_last_of (SCIM_PATH_DELIM) + 1;
+                    ise_name = absfn.substr (begin, absfn.find_last_of ('.') - begin);
+                    break;
+                }
+            }
+
+            file = readdir (dir);
+        }
+        closedir (dir);
+    } else {
+        LOGD ("open (%s) is failed!!!", bin_path.c_str ());
+    }
+    String module_name = String ("");
+    if (ise_name.length () > 0)
+        module_name = pkg_id + String (".") + ise_name;
+
+    LOGD ("module name = %s", module_name.c_str ());
+    return module_name;
+}
+
+static void osp_engine_dir_monitor_cb (void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
+{
+    String em_path       = String (ecore_file_monitor_path_get (em));
+    String manifest_file = em_path.substr (0, em_path.find_last_of (SCIM_PATH_DELIM)) + String ("/info/manifest.xml");
+    String ext           = String (path).substr (String (path).length () - 4);
+
+    if (event == ECORE_FILE_EVENT_CLOSED) {
+        if (String (path) == manifest_file || ext == String (".exe")) {
+            LOGD ("path = %s, event = %d", path, event);
+            String pkg_path = em_path.substr (0, em_path.find_last_of (SCIM_PATH_DELIM));
+            String module_name = osp_module_name_get (pkg_path);
+            const char *module_path_env = getenv ("SCIM_MODULE_PATH");
+            if (module_path_env && module_name.length () > 0) {
+                String module_path = String (module_path_env) +
+                      String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+                      String (SCIM_PATH_DELIM_STRING) + String ("Helper") + String (SCIM_PATH_DELIM_STRING) + module_name + String (".so");
+                isf_update_ise_module (String (module_path), _config);
+                _panel_agent->update_ise_list (_uuids);
+                _panel_agent->reload_config ();
+#if 0
+                String uuid  = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid);
+                int    index = get_ise_index (uuid);
+                if (_modes[index] == TOOLBAR_HELPER_MODE) {
+                    String active_module = get_module_file_path (_module_names[index], String ("Helper"));
+                    if (String (module_path) == active_module) {
+                        /* Restart helper ISE */
+                        _panel_agent->hide_helper (uuid);
+                        _panel_agent->stop_helper (uuid);
+                        _panel_agent->start_helper (uuid);
+                    }
+                }
+#endif
+            }
+        }
+    }
+}
+
+static void add_monitor_for_osp_module (const String &module_name)
+{
+    String rpath         = String ("/opt/apps/") + module_name.substr (0, module_name.find_first_of ('.'));
+    String exe_path      = rpath + String ("/bin");
+    String manifest_path = rpath + String ("/info");
+
+    if (_osp_bin_em.find (module_name) == _osp_bin_em.end () || _osp_bin_em[module_name] == NULL) {
+        _osp_bin_em[module_name] = ecore_file_monitor_add (exe_path.c_str (), osp_engine_dir_monitor_cb, NULL);
+        LOGD ("add %s", module_name.c_str ());
+    }
+    if (_osp_info_em.find (module_name) == _osp_info_em.end () || _osp_info_em[module_name] == NULL) {
+        _osp_info_em[module_name] = ecore_file_monitor_add (manifest_path.c_str (), osp_engine_dir_monitor_cb, NULL);
+    }
+}
+
+/**
+ * @brief : add monitor for engine file and info file update of 3rd party's IMEs
+ */
+static void add_monitor_for_all_osp_modules (void)
+{
+    std::vector<String> osp_module_list;
+    osp_module_list_get (osp_module_list);
+
+    if (osp_module_list.size () > 0) {
+        for (unsigned int i = 0; i < osp_module_list.size (); i++)
+            add_monitor_for_osp_module (osp_module_list[i]);
+    }
+}
+
+/**
+ * @brief Callback function for ISE file monitor.
+ *
+ * @param data Data to pass when it is called.
+ * @param em The handle of Ecore_File_Monitor.
+ * @param event The event type.
+ * @param path The path for current event.
+ */
+static void ise_file_monitor_cb (void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " path=" << path << "\n";
+    LOGD ("path = %s, event = %d", path, event);
+
+    String directory = String (path);
+    directory = directory.substr (0, 4);
+    if (event == ECORE_FILE_EVENT_DELETED_FILE || event == ECORE_FILE_EVENT_CLOSED ||
+        (event == ECORE_FILE_EVENT_CREATED_FILE && directory == String ("/opt"))) {
+        String file_path = String (path);
+        String file_ext  = file_path.substr (file_path.length () - 3);
+        if (file_ext != String (".so")) {
+            LOGD ("%s is not valid so file!!!", path);
+            return;
+        }
+
+        int begin = String (path).find_last_of (SCIM_PATH_DELIM) + 1;
+        String module_name = String (path).substr (begin, String (path).find_last_of ('.') - begin);
+
+        if (event == ECORE_FILE_EVENT_DELETED_FILE) {
+            /* Update ISE list */
+            std::vector<String> list;
+            slot_get_ise_list (list);
+
+            /* delete osp monitor */
+            OSPEmRepository::iterator iter = _osp_bin_em.find (module_name);
+            if (iter != _osp_bin_em.end ()) {
+                ecore_file_monitor_del (iter->second);
+                _osp_bin_em.erase (iter);
+                LOGD ("delete %s", module_name.c_str ());
+            }
+            iter = _osp_info_em.find (module_name);
+            if (iter != _osp_info_em.end ()) {
+                ecore_file_monitor_del (iter->second);
+                _osp_info_em.erase (iter);
+            }
+        } else if (event == ECORE_FILE_EVENT_CLOSED) {
+            isf_update_ise_module (String (path), _config);
+            _panel_agent->update_ise_list (_uuids);
+            _panel_agent->reload_config ();
+#if 0
+            String uuid    = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid);
+            int    index   = get_ise_index (uuid);
+            String strFile = String (ecore_file_monitor_path_get (em)) +
+                             String (SCIM_PATH_DELIM_STRING) + _module_names[index] + String (".so");
+
+            if (String (path) == strFile && _modes[index] == TOOLBAR_HELPER_MODE) {
+                /* Restart helper ISE */
+                _panel_agent->hide_helper (uuid);
+                _panel_agent->stop_helper (uuid);
+                _panel_agent->start_helper (uuid);
+            }
+
+            /* add osp monitor */
+            if (event == ECORE_FILE_EVENT_CREATED_FILE && directory == String ("/opt")) {
+                add_monitor_for_osp_module (module_name);
+                LOGD ("add %s", module_name.c_str ());
+            }
+#endif
+        }
+    }
+}
+
+/**
+ * @brief Delete keyboard ISE file monitor.
+ */
+static void delete_ise_directory_em (void) {
+    if (_inh_keyboard_ise_em) {
+        ecore_file_monitor_del (_inh_keyboard_ise_em);
+        _inh_keyboard_ise_em = NULL;
+    }
+    if (_inh_helper_ise_em) {
+        ecore_file_monitor_del (_inh_helper_ise_em);
+        _inh_helper_ise_em = NULL;
+    }
+
+    if (_osp_keyboard_ise_em) {
+        ecore_file_monitor_del (_osp_keyboard_ise_em);
+        _osp_keyboard_ise_em = NULL;
+    }
+    if (_osp_helper_ise_em) {
+        ecore_file_monitor_del (_osp_helper_ise_em);
+        _osp_helper_ise_em = NULL;
+    }
+
+    OSPEmRepository::iterator iter;
+    for (iter = _osp_bin_em.begin (); iter != _osp_bin_em.end (); iter++) {
+        if (iter->second) {
+            ecore_file_monitor_del (iter->second);
+            iter->second = NULL;
+        }
+    }
+    for (iter = _osp_info_em.begin (); iter != _osp_info_em.end (); iter++) {
+        if (iter->second) {
+            ecore_file_monitor_del (iter->second);
+            iter->second = NULL;
+        }
+    }
+    _osp_bin_em.clear ();
+    _osp_info_em.clear ();
+}
+
+/**
+ * @brief Add inhouse ISEs and OSP ISEs directory monitor.
+ */
+static void add_ise_directory_em (void) {
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    // inhouse IMEngine path
+    String path = String (SCIM_MODULE_PATH) +
+                  String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+                  String (SCIM_PATH_DELIM_STRING) + String ("IMEngine");
+    if (_inh_keyboard_ise_em == NULL)
+        _inh_keyboard_ise_em = ecore_file_monitor_add (path.c_str (), ise_file_monitor_cb, NULL);
+
+    // inhouse Helper path
+    path = String (SCIM_MODULE_PATH) +
+           String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+           String (SCIM_PATH_DELIM_STRING) + String ("Helper");
+    if (_inh_helper_ise_em == NULL)
+        _inh_helper_ise_em = ecore_file_monitor_add (path.c_str (), ise_file_monitor_cb, NULL);
+
+    const char *module_path_env = getenv ("SCIM_MODULE_PATH");
+    if (module_path_env) {
+        // OSP IMEngine path
+        path = String (module_path_env) +
+               String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+               String (SCIM_PATH_DELIM_STRING) + String ("IMEngine");
+        if (access (path.c_str (), R_OK) == 0) {
+            if (_osp_keyboard_ise_em == NULL) {
+                _osp_keyboard_ise_em = ecore_file_monitor_add (path.c_str (), ise_file_monitor_cb, NULL);
+                LOGD ("ecore_file_monitor_add path=%s", path.c_str ());
+            }
+        } else {
+            LOGD ("access path=%s is failed!!!", path.c_str ());
+        }
+
+        // OSP Helper path
+        path = String (module_path_env) +
+               String (SCIM_PATH_DELIM_STRING) + String (SCIM_BINARY_VERSION) +
+               String (SCIM_PATH_DELIM_STRING) + String ("Helper");
+        if (access (path.c_str (), R_OK) == 0) {
+            if (_osp_helper_ise_em == NULL) {
+                _osp_helper_ise_em = ecore_file_monitor_add (path.c_str (), ise_file_monitor_cb, NULL);
+                LOGD ("ecore_file_monitor_add path=%s", path.c_str ());
+            }
+        } else {
+            LOGD ("access path=%s is failed!!!", path.c_str ());
+        }
+    } else {
+        LOGD ("getenv (\"SCIM_MODULE_PATH\") is failed!!!");
+    }
+
+    add_monitor_for_all_osp_modules ();
+}
+
+/**
+ * @brief Set keyboard ISE.
+ *
+ * @param uuid The keyboard ISE's uuid.
+ * @param module_name The keyboard ISE's module name.
+ *
+ * @return false if keyboard ISE change is failed, otherwise return true.
+ */
+static bool set_keyboard_ise (const String &uuid, const String &module_name)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode ();
+
+    if (TOOLBAR_HELPER_MODE == mode) {
+        String pre_uuid = _panel_agent->get_current_helper_uuid ();
+        _panel_agent->hide_helper (pre_uuid);
+        _panel_agent->stop_helper (pre_uuid);
+    } else if (TOOLBAR_KEYBOARD_MODE == mode) {
+        uint32 kbd_option = 0;
+        String kbd_uuid, kbd_name;
+        isf_get_keyboard_ise (_config, kbd_uuid, kbd_name, kbd_option);
+        if (kbd_uuid == uuid)
+            return false;
+    }
+
+    _panel_agent->change_factory (uuid);
+
+    String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/
+    _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, uuid);
+
+    return true;
+}
+
+/**
+ * @brief Set helper ISE.
+ *
+ * @param uuid The helper ISE's uuid.
+ * @param module_name The helper ISE's module name.
+ *
+ * @return false if helper ISE change is failed, otherwise return true.
+ */
+static bool set_helper_ise (const String &uuid, const String &module_name)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode ();
+    String pre_uuid = _panel_agent->get_current_helper_uuid ();
+    if (pre_uuid == uuid)
+        return false;
+
+    if (TOOLBAR_HELPER_MODE == mode) {
+        _panel_agent->hide_helper (pre_uuid);
+        _panel_agent->stop_helper (pre_uuid);
+        char buf[256] = {0};
+        snprintf (buf, sizeof (buf), "time:%ld  pid:%d  %s  %s  stop helper(%s)\n",
+            time (0), getpid (), __FILE__, __func__, pre_uuid.c_str ());
+        isf_save_log (buf);
+    }
+
+    /* Set ComposeKey as keyboard ISE */
+    uint32 kbd_option = 0;
+    String kbd_uuid, kbd_name;
+    isf_get_keyboard_ise (_config, kbd_uuid, kbd_name, kbd_option);
+    if (kbd_uuid != String (SCIM_COMPOSE_KEY_FACTORY_UUID)) {
+        kbd_uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID);
+        _panel_agent->change_factory (kbd_uuid);
+
+        String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/
+        _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, kbd_uuid);
+    }
+    char buf[256] = {0};
+    snprintf (buf, sizeof (buf), "time:%ld  pid:%d  %s  %s  Start helper(%s)\n",
+        time (0), getpid (), __FILE__, __func__, uuid.c_str ());
+    isf_save_log (buf);
+
+    _panel_agent->start_helper (uuid);
+    _config->write (String (SCIM_CONFIG_DEFAULT_HELPER_ISE), uuid);
+
+    return true;
+}
+
+/**
+ * @brief Set active ISE.
+ *
+ * @param uuid The ISE's uuid.
+ *
+ * @return false if ISE change is failed, otherwise return true.
+ */
+static bool set_active_ise (const String &uuid)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    char buf[256] = {0};
+    snprintf (buf, sizeof (buf), "time:%ld  pid:%d  %s  %s  set ISE(%s)\n",
+        time (0), getpid (), __FILE__, __func__, uuid.c_str ());
+    isf_save_log (buf);
+
+    if (uuid.length () <= 0)
+        return false;
+
+    bool ise_changed = false;
+
+    for (unsigned int i = 0; i < _uuids.size (); i++) {
+        if (!uuid.compare (_uuids[i])) {
+            if (TOOLBAR_KEYBOARD_MODE == _modes[i])
+                ise_changed = set_keyboard_ise (_uuids[i], _module_names[i]);
+            else if (TOOLBAR_HELPER_MODE == _modes[i])
+                ise_changed = set_helper_ise (_uuids[i], _module_names[i]);
+
+            if (ise_changed) {
+                _panel_agent->set_current_toolbar_mode (_modes[i]);
+                _panel_agent->set_current_ise_name (_names[i]);
+
+                _ise_width  = 0;
+                _ise_height = 0;
+                _ise_state  = WINDOW_STATE_HIDE;
+                _candidate_mode      = SOFT_CANDIDATE_WINDOW;
+                _candidate_port_line = ONE_LINE_CANDIDATE;
+                if (_candidate_window)
+                    ui_create_candidate_window ();
+
+                scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _uuids[i]);
+                scim_global_config_flush ();
+
+                _config->flush ();
+                _config->reload ();
+                _panel_agent->reload_config ();
+            }
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief Load ISF configuration and ISEs information.
+ */
+static void load_config (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* Read configurations. */
+    if (!_config.null ()) {
+        bool shared_ise = _config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), false);
+        _panel_agent->set_should_shared_ise (shared_ise);
+    }
+
+    isf_load_ise_information (ALL_ISE, _config);
+}
+
+/**
+ * @brief Reload config callback function for ISF panel.
+ *
+ * @param config The config pointer.
+ */
+static void config_reload_cb (const ConfigPointer &config)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* load_config (); */
+}
+
+static Eina_Bool system_ready_timeout_cb (void *data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    LOGW ("Launching IME because of appservice ready timeout\n");
+
+    _launch_default_soft_keyboard ();
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Start of Candidate Functions
+//////////////////////////////////////////////////////////////////////
+/**
+ * @brief Get candidate window valid height for autoscroll.
+ *
+ * @return The valid height.
+ */
+static int ui_candidate_get_valid_height (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "\n";
+
+    int height = 0;
+    int angle = 0;
+
+    if (_candidate_window) {
+        if (_candidate_state == WINDOW_STATE_SHOW)
+            angle = _candidate_angle;
+        else
+            angle = efl_get_angle_for_app_window ();
+
+        if (_aux_area_visible && _candidate_area_1_visible) {
+            if (angle == 90 || angle == 270)
+                height = _candidate_land_height_min_2;
+            else
+                height = _candidate_port_height_min_2;
+        } else {
+            if (angle == 90 || angle == 270)
+                height = _candidate_land_height_min;
+            else
+                height = _candidate_port_height_min;
+        }
+    }
+    return height;
+}
+
+/**
+ * @brief Resize candidate window size.
+ *
+ * @param new_width  New width for candidate window.
+ * @param new_height New height for candidate window.
+ */
+static void ui_candidate_window_resize (int new_width, int new_height)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " width:" << new_width << " height:" << new_height << "\n";
+
+    if (!_candidate_window)
+        return;
+
+    int height;
+
+    LOGD ("%s (w: %d, h: %d)\n", __func__, new_width, new_height);
+    evas_object_resize (_aux_line, new_width, 2);
+    _candidate_width  = new_width;
+    _candidate_height = new_height;
+    if (_candidate_state == WINDOW_STATE_SHOW)
+        _panel_agent->update_candidate_panel_event ((uint32)ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT, 0);
+
+    if (_candidate_state == WINDOW_STATE_SHOW && _candidate_mode == FIXED_CANDIDATE_WINDOW) {
+        height = ui_candidate_get_valid_height ();
+        if ((_ise_width == 0 && _ise_height == 0) ||
+            (_ise_height > 0 && _candidate_valid_height != height) ||
+            (_ise_height > 0 && (_candidate_height - height) > _ise_height)) {
+            set_keyboard_geometry_atom_info (_app_window, get_ise_geometry ());
+            _panel_agent->update_input_panel_event (ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
+        }
+    }
+
+    /* Get height for portrait and landscape */
+    int port_width  = _candidate_port_width;
+    int port_height = _candidate_port_height_min;
+    int land_width  = _candidate_land_width;
+    int land_height = _candidate_land_height_min;
+    if (_candidate_angle == 90 || _candidate_angle == 270) {
+        land_height = new_height;
+        if (land_height == _candidate_land_height_min_2) {
+            port_height = _candidate_port_height_min_2;
+        } else if (land_height == _candidate_land_height_max) {
+            port_height = _candidate_port_height_max;
+        } else if (land_height == _candidate_land_height_max_2) {
+            port_height = _candidate_port_height_max_2;
+        }
+    } else {
+        port_height = new_height;
+        if (port_height == _candidate_port_height_min_2) {
+            land_height = _candidate_land_height_min_2;
+        } else if (port_height == _candidate_port_height_max) {
+            land_height = _candidate_land_height_max;
+        } else if (port_height == _candidate_port_height_max_2) {
+            land_height = _candidate_land_height_max_2;
+        }
+    }
+
+    // FIXME: ECORE_X dependency.
+}
+
+/**
+ * @brief This function will show/hide widgets of candidate window,
+ *        and resize candidate window size according to aux_area/candidate_area.
+ */
+static void ui_candidate_window_adjust (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (!_candidate_window)
+        return;
+
+    int x, y, width, height;
+
+    /* Get candidate window size */
+    // FIXME:
+    x = y = 0;
+    width = _candidate_width;
+    height = _candidate_height;
+
+    if (_aux_area_visible && _candidate_area_2_visible) {
+        evas_object_show (_aux_line);
+        evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min);
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            ui_candidate_window_resize (width, _candidate_land_height_max_2);
+            evas_object_move (_close_btn, _close_btn_pos[2], _close_btn_pos[3] + _candidate_port_height_min_2 - _candidate_port_height_min);
+            evas_object_move (_candidate_area_2, 0, _candidate_land_height_min_2);
+            evas_object_move (_scroller_bg, 0, _candidate_land_height_min_2);
+        } else {
+            ui_candidate_window_resize (width, _candidate_port_height_max_2);
+            evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min);
+            evas_object_move (_candidate_area_2, 0, _candidate_port_height_min_2);
+            evas_object_move (_scroller_bg, 0, _candidate_port_height_min_2);
+        }
+    } else if (_aux_area_visible && _candidate_area_1_visible) {
+        evas_object_show (_aux_line);
+        evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min);
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            ui_candidate_window_resize (width, _candidate_land_height_min_2);
+            evas_object_move (_more_btn, _more_btn_pos[2], _more_btn_pos[3] + _candidate_port_height_min_2 - _candidate_port_height_min);
+        } else {
+            ui_candidate_window_resize (width, _candidate_port_height_min_2);
+            evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min);
+        }
+    } else if (_aux_area_visible) {
+        evas_object_hide (_aux_line);
+        ui_candidate_window_resize (width, _aux_height + 2);
+    } else if (_candidate_area_2_visible) {
+        evas_object_hide (_aux_line);
+        evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1]);
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            ui_candidate_window_resize (width, _candidate_land_height_max);
+            evas_object_move (_close_btn, _close_btn_pos[2], _close_btn_pos[3]);
+            evas_object_move (_candidate_area_2, 0, _candidate_land_height_min);
+            evas_object_move (_scroller_bg, 0, _candidate_land_height_min);
+        } else {
+            ui_candidate_window_resize (width, _candidate_port_height_max);
+            evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1]);
+            evas_object_move (_candidate_area_2, 0, _candidate_port_height_min);
+            evas_object_move (_scroller_bg, 0, _candidate_port_height_min);
+        }
+    } else {
+        evas_object_hide (_aux_line);
+        evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1]);
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            ui_candidate_window_resize (width, _candidate_land_height_min);
+            evas_object_move (_more_btn, _more_btn_pos[2], _more_btn_pos[3]);
+        } else {
+            ui_candidate_window_resize (width, _candidate_port_height_min);
+            evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1]);
+        }
+    }
+}
+
+/**
+ * @brief Rotate candidate window.
+ *
+ * @param angle The angle of candidate window.
+ */
+static void ui_candidate_window_rotate (int angle)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (!_candidate_window)
+        return;
+
+    ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL);
+
+    if (angle == 90 || angle == 270) {
+        _candidate_scroll_width = _candidate_scroll_width_max;
+        ui_candidate_window_resize (_candidate_land_width, _candidate_land_height_min);
+        evas_object_resize (_aux_area, _aux_land_width, _aux_height);
+        evas_object_resize (_candidate_area_1, _candidate_scroll_0_width_max, _item_min_height);
+        evas_object_resize (_candidate_area_2, _candidate_scroll_width, _candidate_scroll_height_min);
+        evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_min + 6);
+    } else {
+        _candidate_scroll_width = _candidate_scroll_width_min;
+        ui_candidate_window_resize (_candidate_port_width, _candidate_port_height_min);
+        evas_object_resize (_aux_area, _aux_port_width, _aux_height);
+        evas_object_resize (_candidate_area_1, _candidate_scroll_0_width_min, (_item_min_height+2)*_candidate_port_line-2);
+        evas_object_resize (_candidate_area_2, _candidate_scroll_width, _candidate_scroll_height_max);
+        evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6);
+    }
+
+    evas_object_hide (_candidate_area_2);
+    _candidate_area_2_visible = false;
+    ui_candidate_window_adjust ();
+    if (_candidate_area_1_visible) {
+        update_table (ISF_CANDIDATE_TABLE, g_isf_candidate_table);
+    }
+    flush_memory ();
+
+    LOGD ("elm_win_rotation_with_resize_set (window : %p, angle : %d)\n", _candidate_window, angle);
+    elm_win_rotation_with_resize_set (_candidate_window, angle);
+    if (_preedit_window)
+        elm_win_rotation_with_resize_set (_preedit_window, angle);
+}
+
+/**
+ * @brief This function is used to judge whether candidate window should be hidden.
+ *
+ * @return true if candidate window should be hidden, otherwise return false.
+ */
+static bool ui_candidate_can_be_hide (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_aux_area_visible || _candidate_area_1_visible || _candidate_area_2_visible)
+        return false;
+    else
+        return true;
+}
+
+/**
+ * @brief Delete check candidate window size timer.
+ *
+ * @return void
+ */
+static void ui_candidate_delete_check_size_timer (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_check_size_timer != NULL) {
+        ecore_timer_del (_check_size_timer);
+        _check_size_timer = NULL;
+    }
+}
+
+/**
+ * @brief Callback function for check candidate window size timer.
+ *
+ * @param data Data to pass when it is called.
+ *
+ * @return ECORE_CALLBACK_CANCEL
+ */
+static Eina_Bool ui_candidate_check_size_timeout (void *data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    ui_candidate_delete_check_size_timer ();
+    ui_candidate_window_resize (_candidate_width, _candidate_height);
+    ui_settle_candidate_window ();
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * @brief Delete longpress timer.
+ *
+ * @return void
+ */
+static void ui_candidate_delete_longpress_timer (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_longpress_timer != NULL) {
+        ecore_timer_del (_longpress_timer);
+        _longpress_timer = NULL;
+    }
+}
+
+/**
+ * @brief Callback function for candidate longpress timer.
+ *
+ * @param data Data to pass when it is called.
+ *
+ * @return ECORE_CALLBACK_CANCEL
+ */
+static Eina_Bool ui_candidate_longpress_timeout (void *data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int index = (int)GPOINTER_TO_INT(data);
+    ui_candidate_delete_longpress_timer ();
+    _is_click = false;
+    _panel_agent->send_longpress_event (_click_object, index);
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * @brief Delete destroy timer.
+ *
+ * @return void
+ */
+static void ui_candidate_delete_destroy_timer (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_destroy_timer != NULL) {
+        ecore_timer_del (_destroy_timer);
+        _destroy_timer = NULL;
+    }
+}
+
+/**
+ * @brief Callback function for destroy timer.
+ *
+ * @param data Data to pass when it is called.
+ *
+ * @return ECORE_CALLBACK_CANCEL
+ */
+static Eina_Bool ui_candidate_destroy_timeout (void *data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    ui_candidate_delete_destroy_timer ();
+    ui_destroy_candidate_window ();
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * @brief Callback function for off_prepare_done.
+ *
+ * @param data Data to pass when it is called.
+ *
+ * @return ECORE_CALLBACK_CANCEL
+ */
+static Eina_Bool off_prepare_done_timeout (void *data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* WMSYNC, #8 Let the Window Manager to actually hide keyboard window */
+    // WILL_HIDE_REQUEST_DONE Ack to WM
+    // FIXME:
+
+    _off_prepare_done_timer = NULL;
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * @brief Delete candidate hide timer.
+ *
+ * @return void
+ */
+static void delete_candidate_hide_timer (void)
+{
+    LOGD ("deleting candidate_hide_timer");
+    if (_candidate_hide_timer) {
+        ecore_timer_del (_candidate_hide_timer);
+        _candidate_hide_timer = NULL;
+    }
+}
+
+static void candidate_window_hide (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "\n";
+
+    delete_candidate_hide_timer ();
+    _candidate_state = WINDOW_STATE_HIDE;
+
+    LOGD ("evas_object_hide (_candidate_window, %p)\n", elm_win_xwindow_get (_candidate_window));
+
+    if (_candidate_window) {
+        /* There are cases that when there are rapid ISE_HIDE and ISE_SHOW requests,
+           candidate window should be displayed but STATE_OFF for the first ISE_HIDE
+           calls this function, so when the candidate window is shown by the following
+           STATE_ON message, a blank area is displayed in candidate window -
+           so we let the _cnadidate_area_1 as the default area that would be displayed */
+        //evas_object_hide (_candidate_area_1);
+        //evas_object_hide (_more_btn);
+        _candidate_area_1_visible = false;
+
+        evas_object_hide (_candidate_window);
+        SCIM_DEBUG_MAIN (3) << "    Hide candidate window\n";
+    }
+}
+
+/**
+ * @brief Callback function for candidate hide timer
+ *
+ * @param data Data to pass when it is called.
+ *
+ * @return ECORE_CALLBACK_CANCEL
+ */
+static Eina_Bool candidate_hide_timer (void *data)
+{
+    LOGD ("calling candidate_window_hide()");
+    candidate_window_hide ();
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * @brief Delete candidate show handler.
+ *
+ * @return void
+ */
+static void delete_candidate_show_handler (void)
+{
+    if (_candidate_show_handler) {
+        ecore_event_handler_del (_candidate_show_handler);
+        _candidate_show_handler = NULL;
+    }
+}
+
+
+/**
+ * @brief Show candidate window.
+ *
+ * @param bSetVirtualKbd The flag for set_keyboard_geometry_atom_info () calling.
+ */
+static void ui_candidate_show (bool bSetVirtualKbd)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+
+    delete_candidate_hide_timer ();
+
+    if (!_candidate_window) return;
+
+   /* FIXME : SHOULD UNIFY THE METHOD FOR CHECKING THE HW KEYBOARD EXISTENCE */
+   /* If the ISE is not visible currently, wait for the ISE to be opened and then show our candidate window */
+   _candidate_show_requested = true;
+   if( (hw_kbd_detect == 0 && _ise_state != WINDOW_STATE_SHOW)) {
+        LOGD ("setting _show_can didate_requested to TRUE");
+        return;
+    }
+
+    ui_candidate_window_rotate (_candidate_angle);
+
+    /* If the candidate window was about to hide, turn it back to SHOW state now */
+    if (_candidate_state == WINDOW_STATE_WILL_HIDE) {
+        _candidate_state = WINDOW_STATE_SHOW;
+    }
+
+    /* Change to WILL_SHOW state only when we are not currently in SHOW state */
+    if (_candidate_state != WINDOW_STATE_SHOW) {
+        _candidate_state = WINDOW_STATE_WILL_SHOW;
+    }
+
+    if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+        if (bSetVirtualKbd) {
+            set_keyboard_geometry_atom_info (_app_window, get_ise_geometry ());
+        }
+    }
+
+    ui_candidate_delete_check_size_timer ();
+    _check_size_timer = ecore_timer_add (0.02, ui_candidate_check_size_timeout, NULL);
+
+    SCIM_DEBUG_MAIN (3) << "    Show candidate window\n";
+    if (_ise_state == WINDOW_STATE_SHOW) {
+        edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "more_button");
+        edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "close_button");
+    } else {
+        edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "close_button");
+        edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "more_button");
+    }
+
+    /* If we are in hardward keyboard mode, this candidate window is now considered to be a input panel */
+    if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+        if (hw_kbd_mode) {
+            LOGD ("sending ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW");
+            _panel_agent->update_input_panel_event ((uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT, (uint32)ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW);
+        }
+    }
+
+    evas_object_show (_candidate_window);
+}
+
+/**
+ * @brief Hide candidate window.
+ *
+ * @param bForce The flag to hide candidate window by force.
+ * @param bSetVirtualKbd The flag for set_keyboard_geometry_atom_info () calling.
+ */
+static void ui_candidate_hide (bool bForce, bool bSetVirtualKbd, bool will_hide)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " bForce:" << bForce << " bSetVirtualKbd:" << bSetVirtualKbd << " will_hide:" << will_hide << "...\n";
+    
+    if (!_candidate_window)
+        return;
+
+    if (bForce) {
+        if (_candidate_area_2 && _candidate_area_2_visible) {
+            evas_object_hide (_candidate_area_2);
+            _candidate_area_2_visible = false;
+            evas_object_hide (_scroller_bg);
+            evas_object_hide (_close_btn);
+            _panel_agent->candidate_more_window_hide ();
+            ui_candidate_window_adjust ();
+        }
+    }
+
+    if (bForce || ui_candidate_can_be_hide ()) {
+        if (will_hide) {
+            LOGD ("candidate_state = WILL_HIDE");
+            _candidate_state = WINDOW_STATE_WILL_HIDE;
+
+            delete_candidate_hide_timer ();
+            _candidate_hide_timer = ecore_timer_add (2.0, candidate_hide_timer, NULL);
+        }
+
+        if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+            /* FIXME : should check if bSetVirtualKbd flag is really needed in this case */
+            if (_ise_state == WINDOW_STATE_SHOW) {
+                set_keyboard_geometry_atom_info (_app_window, get_ise_geometry ());
+            } else {
+                if (bSetVirtualKbd) {
+                    set_keyboard_geometry_atom_info (_app_window, get_ise_geometry ());
+                }
+            }
+        }
+
+        if (!will_hide) {
+            /* If we are not in will_hide state, hide the candidate window immediately */
+            candidate_window_hide ();
+            evas_object_hide (_preedit_window);
+        }
+    }
+}
+
+/**
+ * @brief Callback function for more button.
+ *
+ * @param data Data to pass when it is called.
+ * @param e The evas for current event.
+ * @param button The evas object for current event.
+ * @param event_info The information for current event.
+ */
+static void ui_candidate_window_more_button_cb (void *data, Evas *e, Evas_Object *button, void *event_info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    _panel_agent->candidate_more_window_show ();
+
+    if (_candidate_angle == 180 || _candidate_angle == 270) {
+        Ecore_Evas *ee = ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window));
+        ecore_evas_move_resize (ee, 0, 0, 0, 0);
+    }
+
+    evas_object_show (_candidate_area_2);
+    _candidate_area_2_visible = true;
+    evas_object_show (_scroller_bg);
+    evas_object_hide (_more_btn);
+    evas_object_show (_close_btn);
+
+    ui_candidate_window_adjust ();
+    ui_settle_candidate_window ();
+    flush_memory ();
+}
+
+/**
+ * @brief Callback function for close button.
+ *
+ * @param data Data to pass when it is called.
+ * @param e The evas for current event.
+ * @param button The evas object for current event.
+ * @param event_info The information for current event.
+ */
+static void ui_candidate_window_close_button_cb (void *data, Evas *e, Evas_Object *button, void *event_info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_candidate_area_2 == NULL || !_candidate_area_2_visible)
+        return;
+
+    evas_object_hide (_candidate_area_2);
+    _candidate_area_2_visible = false;
+    evas_object_hide (_scroller_bg);
+    evas_object_hide (_close_btn);
+    _panel_agent->candidate_more_window_hide ();
+
+    evas_object_show (_candidate_area_1);
+    _candidate_area_1_visible = true;
+    evas_object_show (_more_btn);
+
+    elm_scroller_region_show (_candidate_area_2, 0, 0, _candidate_scroll_width, 100);
+    if (_candidate_angle == 180 || _candidate_angle == 270) {
+        Ecore_Evas *ee= ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window));
+        ecore_evas_move_resize (ee, 0, 0, 0, 0);
+    }
+
+    ui_candidate_window_adjust ();
+    ui_settle_candidate_window ();
+    flush_memory ();
+}
+
+/**
+ * @brief Callback function for mouse button press.
+ *
+ * @param data Data to pass when it is called.
+ * @param e The evas for current event.
+ * @param button The evas object for current event.
+ * @param event_info The information for current event.
+ */
+static void ui_mouse_button_pressed_cb (void *data, Evas *e, Evas_Object *button, void *event_info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    _click_object = GPOINTER_TO_INT (data) & 0xFF;
+    _is_click     = true;
+
+    Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
+    _click_down_pos [0] = ev->canvas.x;
+    _click_down_pos [1] = ev->canvas.y;
+
+    if (_click_object == ISF_EFL_CANDIDATE_0 || _click_object == ISF_EFL_CANDIDATE_ITEMS) {
+        int index = GPOINTER_TO_INT (data) >> 8;
+
+#if HAVE_FEEDBACK
+        if (feedback_initialized) {
+            int feedback_result = 0;
+
+            feedback_result = feedback_play_type (FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_SIP);
+
+            if (FEEDBACK_ERROR_NONE == feedback_result)
+                LOGD ("Sound play successful");
+            else
+                LOGW ("Cannot play feedback sound : %d", feedback_result);
+
+            feedback_result = feedback_play_type (FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP);
+
+            if (FEEDBACK_ERROR_NONE == feedback_result)
+                LOGD ("Vibration play successful");
+            else
+                LOGW ("Cannot play feedback vibration : %d", feedback_result);
+        }
+#endif
+
+        ui_candidate_delete_longpress_timer ();
+        _longpress_timer = ecore_timer_add (1.0, ui_candidate_longpress_timeout, (void *)index);
+    }
+}
+
+/**
+ * @brief Callback function for mouse button release.
+ *
+ * @param data Data to pass when it is called.
+ * @param e The evas for current event.
+ * @param button The evas object for current event.
+ * @param event_info The information for current event.
+ */
+static void ui_mouse_button_released_cb (void *data, Evas *e, Evas_Object *button, void *event_info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " index:" << GPOINTER_TO_INT (data) << "...\n";
+
+    ui_candidate_delete_longpress_timer ();
+
+    int index = GPOINTER_TO_INT (data);
+    if (_click_object == ISF_EFL_AUX && _is_click) {
+/*      double ret = 0;
+        const char *buf = edje_object_part_state_get (button, "aux", &ret);
+        if (strcmp ("selected", buf)) {
+            for (unsigned int i = 0; i < _aux_items.size (); i++) {
+                buf = edje_object_part_state_get (_aux_items [i], "aux", &ret);
+                if (!strcmp ("selected", buf))
+                    edje_object_signal_emit (_aux_items [i], "aux,state,unselected", "aux");
+            }
+            edje_object_signal_emit (button, "aux,state,selected", "aux");
+            _panel_agent->select_aux (index);
+        }*/
+        int r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3;
+        edje_object_color_class_get (_aux_items [index], "text_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3);
+        // Normal item is clicked
+        if (!(r == 62 && g == 207 && b == 255)) {
+            for (unsigned int i = 0; i < _aux_items.size (); i++) {
+                edje_object_color_class_set (_aux_items [i], "text_color", 249, 249, 249, 255, r2, g2, b2, a2, r3, g3, b3, a3);
+            }
+            edje_object_color_class_set (_aux_items [index], "text_color", 62, 207, 255, 255, r2, g2, b2, a2, r3, g3, b3, a3);
+            _panel_agent->select_aux (index);
+        }
+    } else if (_click_object == ISF_EFL_CANDIDATE_0 && _is_click) {
+        ui_candidate_window_close_button_cb (NULL, NULL, _close_btn, NULL);
+        _panel_agent->select_candidate (index);
+    } else if (_click_object == ISF_EFL_CANDIDATE_ITEMS && _is_click) {
+        ui_candidate_window_close_button_cb (NULL, NULL, _close_btn, NULL);
+        _panel_agent->select_candidate (index);
+    }
+}
+
+/**
+ * @brief Callback function for mouse move.
+ *
+ * @param data Data to pass when it is called.
+ * @param e The evas for current event.
+ * @param button The evas object for current event.
+ * @param event_info The information for current event.
+ */
+static void ui_mouse_moved_cb (void *data, Evas *e, Evas_Object *button, void *event_info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
+    _click_up_pos [0] = ev->canvas.x;
+    _click_up_pos [1] = ev->canvas.y;
+
+    if (abs (_click_up_pos [0] - _click_down_pos [0]) >= (int)(15 * _height_rate) ||
+        abs (_click_up_pos [1] - _click_down_pos [1]) >= (int)(15 * _height_rate)) {
+        _is_click = false;
+        ui_candidate_delete_longpress_timer ();
+    }
+}
+
+/**
+ * @brief Open TTS device.
+ *
+ * @return false if open is failed, otherwise return true.
+ */
+static bool ui_open_tts (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+#if HAVE_TTS
+    int r = tts_create (&_tts);
+    if (TTS_ERROR_NONE != r) {
+        LOGW ("tts_create FAILED : result(%d)\n", r);
+        _tts = NULL;
+        return false;
+    }
+
+    r = tts_set_mode (_tts, TTS_MODE_SCREEN_READER);
+    if (TTS_ERROR_NONE != r) {
+        LOGW ("tts_set_mode FAILED : result(%d)\n", r);
+    }
+
+    tts_state_e current_state;
+    r = tts_get_state (_tts, &current_state);
+    if (TTS_ERROR_NONE != r) {
+        LOGW ("tts_get_state FAILED : result(%d)\n", r);
+    }
+
+    if (TTS_STATE_CREATED == current_state)  {
+        r = tts_prepare (_tts);
+        if (TTS_ERROR_NONE != r) {
+            LOGW ("tts_prepare FAILED : ret(%d)\n", r);
+        }
+    }
+    return true;
+#else
+    return false;
+#endif
+}
+
+/**
+ * @brief Close TTS device.
+ */
+static void ui_close_tts (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+#if HAVE_TTS
+    if (_tts) {
+        int r = tts_unprepare (_tts);
+        if (TTS_ERROR_NONE != r) {
+            LOGW ("tts_unprepare FAILED : result(%d)\n", r);
+        }
+
+        r = tts_destroy (_tts);
+        if (TTS_ERROR_NONE != r) {
+            LOGW ("tts_destroy FAILED : result(%d)\n", r);
+        }
+    }
+#endif
+}
+
+/**
+ * @brief Play string by TTS.
+ *
+ * @param str The string for playing.
+ */
+static void ui_play_tts (const char* str)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " str=" << str << "\n";
+
+#if HAVE_TTS
+    if (_tts == NULL) {
+        if (!ui_open_tts ())
+            return;
+    }
+
+    if (str) {
+        int r;
+        int utt_id = 0;
+        tts_state_e current_state;
+
+        r = tts_get_state (_tts, &current_state);
+        if (TTS_ERROR_NONE != r) {
+            LOGW ("Fail to get state from TTS : ret(%d)\n", r);
+        }
+
+        if (TTS_STATE_PLAYING == current_state)  {
+            r = tts_stop (_tts);
+            if (TTS_ERROR_NONE != r) {
+                LOGW ("Fail to stop TTS : ret(%d)\n", r);
+            }
+        }
+        /* FIXME: Should support for all languages */
+        r = tts_add_text (_tts, str, "en_US", TTS_VOICE_TYPE_FEMALE, TTS_SPEED_NORMAL, &utt_id);
+        if (TTS_ERROR_NONE == r) {
+            r = tts_play (_tts);
+            if (TTS_ERROR_NONE != r) {
+                LOGW ("Fail to play TTS : ret(%d)\n", r);
+            }
+        }
+    }
+#endif
+}
+
+/**
+ * @brief Mouse over (find focus object and play text by TTS) when screen reader is enabled.
+ *
+ * @param mouse_x Mouse X position.
+ * @param mouse_y Mouse Y position.
+ */
+static void ui_mouse_over (int mouse_x, int mouse_y)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_window == NULL || _candidate_state != WINDOW_STATE_SHOW)
+        return;
+
+    int x, y, width, height;
+    for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) {
+        if (_candidate_0 [i]) {
+            evas_object_geometry_get (_candidate_0 [i], &x, &y, &width, &height);
+            if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height) {
+                /* FIXME: Should consider emoji case */
+                String mbs = utf8_wcstombs (g_isf_candidate_table.get_candidate_in_current_page (i));
+                SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " play candidate string: " << mbs << "\n";
+                ui_play_tts (mbs.c_str ());
+                return;
+            }
+        }
+    }
+
+    String strTts = String ("");
+    if (_candidate_area_2_visible) {
+        evas_object_geometry_get (_close_btn, &x, &y, &width, &height);
+        if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height)
+            strTts = String ("close button");
+    } else {
+        evas_object_geometry_get (_more_btn, &x, &y, &width, &height);
+        if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height)
+            strTts = String ("more button");
+    }
+    if (strTts.length () > 0)
+        ui_play_tts (strTts.c_str ());
+}
+
+/**
+ * @brief Mouse click (find focus object and do click event) when screen reader is enabled.
+ *
+ * @param mouse_x Mouse X position.
+ * @param mouse_y Mouse Y position.
+ */
+static void ui_mouse_click (int mouse_x, int mouse_y)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_window == NULL || _candidate_state != WINDOW_STATE_SHOW)
+        return;
+
+    int x, y, width, height;
+    for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) {
+        if (_candidate_0 [i]) {
+            evas_object_geometry_get (_candidate_0 [i], &x, &y, &width, &height);
+            if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height) {
+                Evas_Event_Mouse_Down event_info;
+                event_info.canvas.x = mouse_x;
+                event_info.canvas.y = mouse_y;
+                ui_mouse_button_pressed_cb (GINT_TO_POINTER ((i << 8) + ISF_EFL_CANDIDATE_0), NULL, NULL, &event_info);
+                ui_mouse_button_released_cb (GINT_TO_POINTER (i), NULL, NULL, &event_info);
+                return;
+            }
+        }
+    }
+
+    if (_candidate_area_2_visible) {
+        evas_object_geometry_get (_close_btn, &x, &y, &width, &height);
+        if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height) {
+            ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL);
+        }
+    } else {
+        evas_object_geometry_get (_more_btn, &x, &y, &width, &height);
+        if (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height) {
+            ui_candidate_window_more_button_cb (NULL, NULL, NULL, NULL);
+        }
+    }
+}
+
+/**
+ * @brief Create preedit window.
+ */
+static void ui_create_preedit_window (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    _preedit_width  = 100;
+    _preedit_height = _preedit_height * _height_rate;
+    if (_preedit_window == NULL) {
+        _preedit_window = efl_create_window ("preedit", "Preedit Window");
+        evas_object_resize (_preedit_window, _preedit_width, _preedit_height);
+
+        int preedit_font_size = (int)(32 * _width_rate);
+
+        _preedit_text = edje_object_add (evas_object_evas_get (_preedit_window));
+        edje_object_file_set (_preedit_text, _candidate_edje_file.c_str (), "preedit_text");
+        edje_object_text_class_set (_preedit_text, "preedit_text_class", _candidate_font_name.c_str (), preedit_font_size);
+        evas_object_size_hint_fill_set (_preedit_text, EVAS_HINT_FILL, EVAS_HINT_FILL);
+        evas_object_size_hint_weight_set (_preedit_text, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        elm_win_resize_object_add (_preedit_window, _preedit_text);
+        evas_object_show (_preedit_text);
+
+        _tmp_preedit_text = evas_object_text_add (evas_object_evas_get (_preedit_window));
+        evas_object_text_font_set (_tmp_preedit_text, _candidate_font_name.c_str (), preedit_font_size);
+    }
+}
+
+/**
+ * @brief Create native style candidate window.
+ */
+static void ui_create_native_candidate_window (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    _candidate_port_width        = _screen_width;
+    _candidate_port_height_min   = 84 * _height_rate * _candidate_port_line;
+    _candidate_port_height_min_2 = 84 * _height_rate + _candidate_port_height_min;
+    _candidate_port_height_max   = 444 * _height_rate + _candidate_port_height_min;
+    _candidate_port_height_max_2 = 84 * _height_rate + _candidate_port_height_max;
+    _candidate_land_width        = _screen_height;
+    _candidate_land_height_min   = 84 * _width_rate;
+    _candidate_land_height_min_2 = 168 * _width_rate;
+    _candidate_land_height_max   = 316 * _width_rate + _candidate_land_height_min;
+    _candidate_land_height_max_2 = 426 * _width_rate;
+
+    _candidate_scroll_0_width_min= _screen_width;
+    _candidate_scroll_0_width_max= _screen_height;
+    _candidate_scroll_width_min  = _screen_width;
+    _candidate_scroll_width_max  = _screen_height;
+    _candidate_scroll_height_min = 252 * _width_rate;
+    _candidate_scroll_height_max = 420 * _height_rate;
+
+    _candidate_area_1_pos [0]    = 0 * _width_rate;
+    _candidate_area_1_pos [1]    = 2 * _height_rate;
+    _more_btn_pos [0]            = 628 * _width_rate;
+    _more_btn_pos [1]            = 12 * _height_rate;
+    _more_btn_pos [2]            = 1188 * _height_rate;
+    _more_btn_pos [3]            = 12 * _width_rate;
+    _close_btn_pos [0]           = 628 * _width_rate;
+    _close_btn_pos [1]           = 12 * _height_rate;
+    _close_btn_pos [2]           = 1188 * _height_rate;
+    _close_btn_pos [3]           = 12 * _width_rate;
+
+    _aux_height                  = 84 * _height_rate - 2;
+    _aux_port_width              = _screen_width;
+    _aux_land_width              = _screen_height;
+
+    _item_min_height             = 84 * _height_rate - 2;
+
+    /* Create candidate window */
+    if (_candidate_window == NULL) {
+        _candidate_window = efl_create_window ("candidate", "Prediction Window");
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            _candidate_width  = _candidate_land_width;
+            _candidate_height = _candidate_land_height_min;
+        } else {
+            _candidate_width  = _candidate_port_width;
+            _candidate_height = _candidate_port_height_min;
+        }
+
+        // FIXME: Ecore_X dependency.
+
+        /* Add background */
+        _candidate_bg = edje_object_add (evas_object_evas_get (_candidate_window));
+        edje_object_file_set (_candidate_bg, _candidate_edje_file.c_str (), "candidate_bg");
+        evas_object_size_hint_weight_set (_candidate_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        elm_win_resize_object_add (_candidate_window, _candidate_bg);
+        evas_object_show (_candidate_bg);
+
+        /* Create _candidate_0 scroller */
+        _candidate_0_scroll = elm_scroller_add (_candidate_window);
+        elm_scroller_bounce_set (_candidate_0_scroll, EINA_TRUE, EINA_FALSE);
+        elm_scroller_policy_set (_candidate_0_scroll, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
+        evas_object_resize (_candidate_0_scroll, _candidate_scroll_0_width_min, (_item_min_height+2)*_candidate_port_line-2);
+        evas_object_move (_candidate_0_scroll, _candidate_area_1_pos[0], _candidate_area_1_pos[1]);
+        _candidate_0_table = elm_table_add (_candidate_window);
+        evas_object_size_hint_weight_set (_candidate_0_table, 0.0, 0.0);
+        evas_object_size_hint_align_set (_candidate_0_table, 0.0, 0.0);
+        elm_table_padding_set (_candidate_0_table, 0, 0);
+        elm_object_content_set (_candidate_0_scroll, _candidate_0_table);
+        evas_object_show (_candidate_0_table);
+        _candidate_area_1 = _candidate_0_scroll;
+
+        /* Create more button */
+        _more_btn = edje_object_add (evas_object_evas_get (_candidate_window));
+        if (_ise_width == 0 && _ise_height == 0)
+            edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "close_button");
+        else
+            edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "more_button");
+        evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1]);
+        evas_object_resize (_more_btn, 80 * _width_rate, 64 * _height_rate);
+        evas_object_event_callback_add (_more_btn, EVAS_CALLBACK_MOUSE_UP, ui_candidate_window_more_button_cb, NULL);
+
+        /* Add scroller background */
+        _candidate_scroll_width = _candidate_scroll_width_min;
+        _scroller_bg = edje_object_add (evas_object_evas_get (_candidate_window));
+        edje_object_file_set (_scroller_bg, _candidate_edje_file.c_str (), "scroller_bg");
+        evas_object_size_hint_weight_set (_scroller_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6);
+        evas_object_move (_scroller_bg, 0, _candidate_port_height_min);
+
+        /* Create vertical scroller */
+        _candidate_scroll = elm_scroller_add (_candidate_window);
+        elm_scroller_bounce_set (_candidate_scroll, 0, 1);
+        elm_scroller_policy_set (_candidate_scroll, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
+        evas_object_resize (_candidate_scroll, _candidate_scroll_width, _candidate_scroll_height_max);
+        evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6);
+        elm_scroller_page_size_set (_candidate_scroll, 0, _item_min_height+_v_padding);
+        evas_object_move (_candidate_scroll, 0, _candidate_port_height_min);
+        _candidate_table = elm_table_add (_candidate_window);
+        evas_object_size_hint_weight_set (_candidate_table, 0.0, 0.0);
+        evas_object_size_hint_align_set (_candidate_table, 0.0, 0.0);
+        elm_table_padding_set (_candidate_table, 0, 0);
+        elm_object_content_set (_candidate_scroll, _candidate_table);
+        evas_object_show (_candidate_table);
+        _candidate_area_2 = _candidate_scroll;
+
+        /* Create close button */
+        _close_btn = edje_object_add (evas_object_evas_get (_candidate_window));
+        if (_ise_width == 0 && _ise_height == 0)
+            edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "more_button");
+        else
+            edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "close_button");
+        evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1]);
+        evas_object_resize (_close_btn, 80 * _width_rate, 64 * _height_rate);
+        evas_object_event_callback_add (_close_btn, EVAS_CALLBACK_MOUSE_UP, ui_candidate_window_close_button_cb, NULL);
+
+        _tmp_candidate_text = evas_object_text_add (evas_object_evas_get (_candidate_window));
+        evas_object_text_font_set (_tmp_candidate_text, _candidate_font_name.c_str (), _candidate_font_size);
+
+        /* Create aux */
+        _aux_area = elm_scroller_add (_candidate_window);
+        elm_scroller_bounce_set (_aux_area, 1, 0);
+        elm_scroller_policy_set (_aux_area, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
+        evas_object_resize (_aux_area, _aux_port_width, _aux_height);
+        evas_object_move (_aux_area, _candidate_area_1_pos[0], _candidate_area_1_pos[1]);
+
+        _aux_table = elm_table_add (_candidate_window);
+        elm_object_content_set (_aux_area, _aux_table);
+        elm_table_padding_set (_aux_table, 0, 0);
+        evas_object_size_hint_weight_set (_aux_table, 0.0, 0.0);
+        evas_object_size_hint_align_set (_aux_table, 0.0, 0.0);
+        evas_object_show (_aux_table);
+
+        _aux_line = edje_object_add (evas_object_evas_get (_candidate_window));
+        edje_object_file_set (_aux_line, _candidate_edje_file.c_str (), "popup_line");
+        evas_object_resize (_aux_line, _candidate_port_width, 2);
+        evas_object_move (_aux_line, 0, _aux_height + 2);
+
+        _tmp_aux_text = evas_object_text_add (evas_object_evas_get (_candidate_window));
+        evas_object_text_font_set (_tmp_aux_text, _candidate_font_name.c_str (), _aux_font_size);
+    }
+
+    flush_memory ();
+}
+
+/**
+ * @brief Create candidate window.
+ *
+ * @return void
+ */
+static void ui_create_candidate_window (void)
+{
+    check_time ("\nEnter ui_create_candidate_window");
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    ui_destroy_candidate_window ();
+
+    _candidate_x     = 0;
+    _candidate_y     = 0;
+    _candidate_angle = 0;
+
+    ui_create_native_candidate_window ();
+
+    unsigned int set = 1;
+    // FIXME:
+
+    int angle = efl_get_angle_for_app_window ();
+    if (_candidate_angle != angle) {
+        _candidate_angle = angle;
+        ui_candidate_window_rotate (angle);
+    } else {
+        ui_settle_candidate_window ();
+    }
+
+    check_time ("Exit ui_create_candidate_window");
+}
+
+/**
+ * @brief Destroy candidate window.
+ *
+ * @return void
+ */
+static void ui_destroy_candidate_window (void)
+{
+    check_time ("Enter ui_destroy_candidate_window");
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* Delete candidate items, popup lines and seperator items */
+    for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) {
+        if (_candidate_0 [i]) {
+            evas_object_del (_candidate_0 [i]);
+            _candidate_0 [i] = NULL;
+        }
+        if (_candidate_items [i]) {
+            evas_object_del (_candidate_items [i]);
+            _candidate_items [i] = NULL;
+        }
+
+        if (_seperate_0 [i]) {
+            evas_object_del (_seperate_0 [i]);
+            _seperate_0 [i] = NULL;
+        }
+        if (_seperate_items [i]) {
+            evas_object_del (_seperate_items [i]);
+            _seperate_items [i] = NULL;
+        }
+
+        if (_line_0 [i]) {
+            evas_object_del (_line_0 [i]);
+            _line_0 [i] = NULL;
+        }
+        if (_line_items [i]) {
+            evas_object_del (_line_items [i]);
+            _line_items [i] = NULL;
+        }
+    }
+
+    _aux_items.clear ();
+    _aux_seperates.clear ();
+    /* Delete candidate window */
+    if (_candidate_window) {
+        LOGD ("calling ui_candidate_hide (true)");
+        ui_candidate_hide (true);
+
+        evas_object_del (_candidate_window);
+        _candidate_window = NULL;
+        _aux_area         = NULL;
+        _candidate_area_1 = NULL;
+        _candidate_area_2 = NULL;
+        _scroller_bg      = NULL;
+    }
+
+    if (_preedit_window) {
+        evas_object_del (_preedit_text);
+        _preedit_text = NULL;
+
+        evas_object_hide (_preedit_window);
+        evas_object_del (_preedit_window);
+        _preedit_window = NULL;
+    }
+
+    flush_memory ();
+    check_time ("Exit ui_destroy_candidate_window");
+}
+
+/**
+ * @brief Settle candidate window position.
+ */
+static void ui_settle_candidate_window (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (!_candidate_window)
+        return;
+
+    /* If both ISE and candidate window are going to be hidden,
+       let's just not move our candidate window */
+    if (_ise_state == WINDOW_STATE_WILL_HIDE && _candidate_state == WINDOW_STATE_WILL_HIDE)
+        return;
+
+    int spot_x, spot_y;
+    int x, y, width, height;
+    int pos_x = 0, pos_y = 0, ise_width = 0, ise_height = 0;
+    bool get_geometry_result = false;
+    bool reverse = false;
+
+    /* Get candidate window position */
+    ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &width, &height);
+
+    //FIXME: Ecore_X dependency.
+
+    if ((_ise_state != WINDOW_STATE_SHOW && _ise_state != WINDOW_STATE_WILL_HIDE) ||
+            get_geometry_result == false) {
+        ise_height = 0;
+        ise_width = 0;
+    }
+
+    int height2 = ui_candidate_get_valid_height ();
+
+    if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+        if (_candidate_angle == 90) {
+            spot_x = _screen_width - ise_height - height2;
+            spot_y = 0;
+        } else if (_candidate_angle == 270) {
+            spot_x = ise_height - (_candidate_height - height2);
+            spot_y = 0;
+        } else if (_candidate_angle == 180) {
+            spot_x = 0;
+            spot_y = ise_height - (_candidate_height - height2);
+        } else {
+            spot_x = 0;
+            spot_y = _screen_height - ise_height - height2;
+        }
+    } else {
+        spot_x = _spot_location_x;
+        spot_y = _spot_location_y;
+
+        rectinfo ise_rect = {0, 0, ise_width, ise_height};
+        if (_candidate_angle == 90 || _candidate_angle == 270) {
+            if (ise_rect.height <= (uint32)0 || ise_rect.height >= (uint32)_screen_width)
+                ise_rect.height = ISE_DEFAULT_HEIGHT_LANDSCAPE * _width_rate;
+        } else {
+            if (ise_rect.height <= (uint32)0 || ise_rect.height >= (uint32) _screen_height)
+                ise_rect.height = ISE_DEFAULT_HEIGHT_PORTRAIT * _height_rate;
+        }
+
+        int nOffset = _candidate_port_height_min / 3;
+        if (_candidate_angle == 270) {
+            if (ise_rect.height > 0 && spot_y + height2 > _screen_width - (int)ise_rect.height + nOffset) {
+                reverse = true;
+                spot_x = _screen_width - _spot_location_top_y - (_candidate_height - height2);
+            } else {
+                spot_x = _screen_width - _spot_location_y - _candidate_height;
+            }
+        } else if (_candidate_angle == 90) {
+            if (ise_rect.height > 0 && spot_y + height2 > _screen_width - (int)ise_rect.height + nOffset) {
+                reverse = true;
+                spot_x = _spot_location_top_y - height2;
+            } else {
+                spot_x = spot_y;
+            }
+        } else if (_candidate_angle == 180) {
+            if (ise_rect.height > 0 && spot_y + height2 > _screen_height - (int)ise_rect.height + nOffset) {
+                reverse = true;
+                spot_y = _screen_height - _spot_location_top_y - (_candidate_height - height2);
+            } else {
+                spot_y = _screen_height - _spot_location_y - _candidate_height;
+            }
+        } else {
+            if (ise_rect.height > 0 && spot_y + height2 > _screen_height - (int)ise_rect.height + nOffset) {
+                reverse = true;
+                spot_y = _spot_location_top_y - height2;
+            } else {
+                spot_y = spot_y;
+            }
+        }
+    }
+    if (_candidate_angle == 90) {
+        spot_y = (_screen_height - _candidate_width) / 2;
+        spot_x = spot_x < _indicator_height ? _indicator_height : spot_x;
+        if (spot_x > _screen_width - _candidate_height)
+            spot_x = _screen_width - _candidate_height;
+    } else if (_candidate_angle == 270) {
+        spot_y = (_screen_height - _candidate_width) / 2;
+        spot_x = spot_x < 0 ? 0 : spot_x;
+        if (spot_x > _screen_width - (_indicator_height+_candidate_height))
+            spot_x = _screen_width - (_indicator_height+_candidate_height);
+    } else if (_candidate_angle == 180) {
+        spot_x = (_screen_width - _candidate_width) / 2;
+        spot_y = spot_y < 0 ? 0 : spot_y;
+        if (spot_y > _screen_height - (_indicator_height+_candidate_height))
+            spot_y = _screen_height - (_indicator_height+_candidate_height);
+    } else {
+        spot_x = (_screen_width - _candidate_width) / 2;
+        spot_y = spot_y < _indicator_height ? _indicator_height : spot_y;
+        if (spot_y > _screen_height - _candidate_height)
+            spot_y = _screen_height - _candidate_height;
+    }
+
+    if (spot_x != x || spot_y != y) {
+        _candidate_x = spot_x;
+        _candidate_y = spot_y;
+        evas_object_move (_candidate_window, spot_x, spot_y);
+        LOGD ("Moving candidate window to : %d %d", spot_x, spot_y);
+        if (_preedit_window) {
+            if (_candidate_angle == 90) {
+                spot_x -= _preedit_height;
+                spot_y = _screen_height - _preedit_width;
+            } else if (_candidate_angle == 270) {
+                spot_x += height2;
+            } else if (_candidate_angle == 180) {
+                spot_x = _screen_width - _preedit_width;
+                spot_y += height2;
+            } else {
+                spot_y -= _preedit_height;
+            }
+            evas_object_move (_preedit_window, spot_x, spot_y);
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////
+// End of Candidate Functions
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Set transient for app window.
+ *
+ * @param window The Ecore_X_Window handler of app window.
+ */
+static void efl_set_transient_for_app_window (Ecore_X_Window window)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* Set a transient window for window stack */
+    //FIXME:
+}
+
+/**
+ * @brief Get angle for app window.
+ *
+ * @param win_obj The Evas_Object handler of application window.
+ *
+ * @return The angle of app window.
+ */
+static int efl_get_angle_for_app_window ()
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int ret;
+    int count;
+    int angle = 0;
+    unsigned char *prop_data = NULL;
+
+    //FIXME:
+
+    return angle;
+}
+
+/**
+ * @brief Get angle for ise window.
+ *
+ * @param win_obj The Evas_Object handler of ise window.
+ *
+ * @return The angle of ise window.
+ */
+static int efl_get_angle_for_ise_window ()
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int ret;
+    int count;
+    int angle = 0;
+    unsigned char *prop_data = NULL;
+
+    //FIXME:
+
+    return angle;
+}
+
+/**
+ * @brief Set showing effect for application window.
+ *
+ * @param win The Evas_Object handler of application window.
+ * @param strEffect The pointer of effect string.
+ */
+static void efl_set_showing_effect_for_app_window (Evas_Object *win, const char* strEffect)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    //FIXME:
+}
+
+/**
+ * @brief Create elementary window.
+ *
+ * @param strWinName The window name.
+ * @param strEffect The window effect string.
+ *
+ * @return The window pointer
+ */
+static Evas_Object *efl_create_window (const char *strWinName, const char *strEffect)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    Evas_Object *win = elm_win_add (NULL, strWinName, ELM_WIN_UTILITY);
+    elm_win_title_set (win, strWinName);
+
+    /* set window properties */
+    elm_win_autodel_set (win, EINA_TRUE);
+    elm_object_focus_allow_set (win, EINA_FALSE);
+    elm_win_borderless_set (win, EINA_TRUE);
+    elm_win_alpha_set (win, EINA_TRUE);
+    elm_win_prop_focus_skip_set (win, EINA_TRUE);
+    efl_set_showing_effect_for_app_window (win, strEffect);
+
+    //const char *szProfile[] = {"mobile", ""};
+    //elm_win_profiles_set (win, szProfile, 1);
+
+    return win;
+}
+
+/**
+ * @brief Create elementary control window.
+ *
+ * @return EINA_TRUE if successful, otherwise return EINA_FALSE
+ */
+static Eina_Bool efl_create_control_window (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* WMSYNC, #1 Creating and registering control window */
+    // FIXME:
+    return EINA_TRUE;
+}
+
+/**
+ * @brief Get screen resolution.
+ *
+ * @param width The screen width.
+ * @param height The screen height.
+ */
+static void efl_get_screen_resolution (int &width, int &height)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    width = 720;
+    height = 1280;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Start of PanelAgent Functions
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Initialize panel agent.
+ *
+ * @param config The config string for PanelAgent.
+ * @param display The current display.
+ * @param resident The variable indicates whether panel will be resident.
+ *
+ * @return true if initialize is successful, otherwise return false.
+ */
+static bool initialize_panel_agent (const String &config, const String &display, bool resident)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    _panel_agent = new PanelAgent ();
+
+    if (!_panel_agent || !_panel_agent->initialize (config, display, resident))
+        return false;
+
+    _panel_agent->signal_connect_reload_config              (slot (slot_reload_config));
+    _panel_agent->signal_connect_focus_in                   (slot (slot_focus_in));
+    _panel_agent->signal_connect_focus_out                  (slot (slot_focus_out));
+    _panel_agent->signal_connect_expand_candidate           (slot (slot_expand_candidate));
+    _panel_agent->signal_connect_contract_candidate         (slot (slot_contract_candidate));
+    _panel_agent->signal_connect_set_candidate_ui           (slot (slot_set_candidate_style));
+    _panel_agent->signal_connect_update_factory_info        (slot (slot_update_factory_info));
+    _panel_agent->signal_connect_update_spot_location       (slot (slot_update_spot_location));
+    _panel_agent->signal_connect_update_input_context       (slot (slot_update_input_context));
+    _panel_agent->signal_connect_update_ise_geometry        (slot (slot_update_ise_geometry));
+    _panel_agent->signal_connect_show_preedit_string        (slot (slot_show_preedit_string));
+    _panel_agent->signal_connect_show_aux_string            (slot (slot_show_aux_string));
+    _panel_agent->signal_connect_show_lookup_table          (slot (slot_show_candidate_table));
+    _panel_agent->signal_connect_hide_preedit_string        (slot (slot_hide_preedit_string));
+    _panel_agent->signal_connect_hide_aux_string            (slot (slot_hide_aux_string));
+    _panel_agent->signal_connect_hide_lookup_table          (slot (slot_hide_candidate_table));
+    _panel_agent->signal_connect_update_preedit_string      (slot (slot_update_preedit_string));
+    _panel_agent->signal_connect_update_preedit_caret       (slot (slot_update_preedit_caret));
+    _panel_agent->signal_connect_update_aux_string          (slot (slot_update_aux_string));
+    _panel_agent->signal_connect_update_lookup_table        (slot (slot_update_candidate_table));
+    _panel_agent->signal_connect_select_candidate           (slot (slot_select_candidate));
+    _panel_agent->signal_connect_get_candidate_geometry     (slot (slot_get_candidate_geometry));
+    _panel_agent->signal_connect_get_input_panel_geometry   (slot (slot_get_input_panel_geometry));
+    _panel_agent->signal_connect_set_active_ise_by_uuid     (slot (slot_set_active_ise));
+    _panel_agent->signal_connect_get_ise_list               (slot (slot_get_ise_list));
+    _panel_agent->signal_connect_get_ise_information        (slot (slot_get_ise_information));
+    _panel_agent->signal_connect_get_keyboard_ise_list      (slot (slot_get_keyboard_ise_list));
+    _panel_agent->signal_connect_get_language_list          (slot (slot_get_language_list));
+    _panel_agent->signal_connect_get_all_language           (slot (slot_get_all_language));
+    _panel_agent->signal_connect_get_ise_language           (slot (slot_get_ise_language));
+    _panel_agent->signal_connect_get_ise_info_by_uuid       (slot (slot_get_ise_info));
+    _panel_agent->signal_connect_set_keyboard_ise           (slot (slot_set_keyboard_ise));
+    _panel_agent->signal_connect_get_keyboard_ise           (slot (slot_get_keyboard_ise));
+    _panel_agent->signal_connect_accept_connection          (slot (slot_accept_connection));
+    _panel_agent->signal_connect_close_connection           (slot (slot_close_connection));
+    _panel_agent->signal_connect_exit                       (slot (slot_exit));
+
+    _panel_agent->signal_connect_register_helper_properties (slot (slot_register_helper_properties));
+    _panel_agent->signal_connect_show_ise                   (slot (slot_show_ise));
+    _panel_agent->signal_connect_hide_ise                   (slot (slot_hide_ise));
+
+    _panel_agent->signal_connect_will_hide_ack              (slot (slot_will_hide_ack));
+
+    _panel_agent->signal_connect_candidate_will_hide_ack    (slot (slot_candidate_will_hide_ack));
+    _panel_agent->signal_connect_get_ise_state              (slot (slot_get_ise_state));
+
+    std::vector<String> load_ise_list;
+    _panel_agent->get_active_ise_list (load_ise_list);
+
+    return true;
+}
+
+/**
+ * @brief Reload config slot function for PanelAgent.
+ */
+static void slot_reload_config (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (!_config.null ())
+        _config->reload ();
+}
+
+/**
+ * @brief Focus in slot function for PanelAgent.
+ */
+static void slot_focus_in (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    ui_candidate_delete_destroy_timer ();
+}
+
+/**
+ * @brief Focus out slot function for PanelAgent.
+ */
+static void slot_focus_out (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    ui_candidate_delete_destroy_timer ();
+    _destroy_timer = ecore_timer_add (ISF_CANDIDATE_DESTROY_DELAY, ui_candidate_destroy_timeout, NULL);
+}
+
+/**
+ * @brief Expand candidate slot function for PanelAgent.
+ */
+static void slot_expand_candidate (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW)
+        return;
+
+    if (_candidate_area_2 && !_candidate_area_2_visible)
+        ui_candidate_window_more_button_cb (NULL, NULL, NULL, NULL);
+}
+
+/**
+ * @brief Contract candidate slot function for PanelAgent.
+ */
+static void slot_contract_candidate (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW)
+        return;
+
+    ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL);
+}
+
+/**
+ * @brief Set candidate style slot function for PanelAgent.
+ *
+ * @param portrait_line The displayed line number for portrait.
+ * @param mode The candidate mode.
+ */
+static void slot_set_candidate_style (int portrait_line, int mode)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " display_line:" << portrait_line << " mode:" << mode << "\n";
+    if ((portrait_line != _candidate_port_line) || (mode != _candidate_mode)) {
+        _candidate_mode      = (ISF_CANDIDATE_MODE_T)mode;
+        _candidate_port_line = (ISF_CANDIDATE_PORTRAIT_LINE_T)portrait_line;
+
+        if (_candidate_mode == SOFT_CANDIDATE_WINDOW) {
+            if (_candidate_window)
+                ui_destroy_candidate_window ();
+
+            return;
+        }
+
+        if (_candidate_window)
+            ui_create_candidate_window ();
+    }
+}
+
+/**
+ * @brief Update keyboard ISE information slot function for PanelAgent.
+ *
+ * @param info The information of current Keyboard ISE.
+ */
+static void slot_update_factory_info (const PanelFactoryInfo &info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    String ise_name = info.name;
+    String ise_icon = info.icon;
+
+    String old_ise = _panel_agent->get_current_ise_name ();
+    if (old_ise != ise_name) {
+        int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+        if (hw_kbd_detect && _candidate_window) {
+            ui_destroy_candidate_window ();
+        }
+    }
+
+    TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode ();
+
+    if (TOOLBAR_HELPER_MODE == mode)
+        ise_name = _names[get_ise_index (_panel_agent->get_current_helper_uuid ())];
+
+    if (ise_name.length () > 0)
+        _panel_agent->set_current_ise_name (ise_name);
+}
+
+/**
+ * @brief Update cursor position slot function for PanelAgent.
+ *
+ * @param x The x position of current cursor.
+ * @param y The bottom y position of current cursor.
+ * @param top_y The top y position of current cursor.
+ */
+static void slot_update_spot_location (int x, int y, int top_y)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (x >= 0 && x < _screen_height && y >= 0 && y < _screen_height) {
+        _spot_location_x = x;
+        _spot_location_y = y;
+        _spot_location_top_y = top_y;
+
+        ui_settle_candidate_window ();
+    }
+}
+
+/**
+ * @brief The input context of ISE is changed.
+ *
+ * @param type  The event type.
+ * @param value The event value.
+ */
+static void slot_update_input_context (int type, int value)
+{
+}
+
+/**
+ * @brief Update ise geometry.
+ *
+ * @param x      The x position in screen.
+ * @param y      The y position in screen.
+ * @param width  The ISE window width.
+ * @param height The ISE window height.
+ */
+static void slot_update_ise_geometry (int x, int y, int width, int height)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << x << " y:" << y << " width:" << width << " height:" << height << "...\n";
+
+    LOGD ("x : %d , y : %d , width : %d , height : %d", x, y, width, height);
+
+    int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+    if (hw_kbd_detect)
+        return;
+
+    int old_height = _ise_height;
+
+    _ise_width  = width;
+    _ise_height = height;
+
+    if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+        if (old_height != height) {
+            ui_settle_candidate_window ();
+        }
+    }
+
+    if (old_height != height && _ise_state == WINDOW_STATE_SHOW) {
+        _ise_reported_geometry.valid = true;
+        _ise_reported_geometry.angle = efl_get_angle_for_ise_window ();
+        _ise_reported_geometry.geometry.pos_x = x;
+        _ise_reported_geometry.geometry.pos_y = y;
+        _ise_reported_geometry.geometry.width = width;
+        _ise_reported_geometry.geometry.height = height;
+        set_keyboard_geometry_atom_info (_app_window, _ise_reported_geometry.geometry);
+        _panel_agent->update_input_panel_event (ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
+    }
+}
+
+/**
+ * @brief Show preedit slot function for PanelAgent.
+ */
+static void slot_show_preedit_string (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_preedit_window == NULL) {
+        ui_create_preedit_window ();
+        int angle = efl_get_angle_for_app_window ();
+        elm_win_rotation_with_resize_set (_preedit_window, angle);
+
+        /* Move preedit window according to candidate window position */
+        if (_candidate_window) {
+            /* Get candidate window position */
+            int x, y, width, height;
+            ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &width, &height);
+
+            int height2 = ui_candidate_get_valid_height ();
+            if (angle == 90) {
+                x -= _preedit_height;
+                y = _screen_height - _preedit_width;
+            } else if (_candidate_angle == 270) {
+                x += height2;
+            } else if (_candidate_angle == 180) {
+                x = _screen_width - _preedit_width;
+                y += height2;
+            } else {
+                y -= _preedit_height;
+            }
+            evas_object_move (_preedit_window, x, y);
+        }
+    }
+
+    if (evas_object_visible_get (_preedit_window))
+        return;
+
+    slot_show_candidate_table ();
+    evas_object_show (_preedit_window);
+}
+
+/**
+ * @brief Show aux slot function for PanelAgent.
+ */
+static void slot_show_aux_string (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_window == NULL)
+        ui_create_candidate_window ();
+
+    if (_aux_area == NULL || _aux_area_visible)
+        return;
+
+    evas_object_show (_aux_area);
+    _aux_area_visible = true;
+    ui_candidate_window_adjust ();
+
+    LOGD ("calling ui_candidate_show ()");
+    ui_candidate_show ();
+    ui_settle_candidate_window ();
+}
+
+/**
+ * @brief Show candidate table slot function for PanelAgent.
+ */
+static void slot_show_candidate_table (void)
+{
+    int feedback_result = 0;
+
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW) {
+        _panel_agent->helper_candidate_show ();
+        return;
+    }
+
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_window == NULL)
+        ui_create_candidate_window ();
+
+    if (_candidate_state == WINDOW_STATE_SHOW &&
+        (_candidate_area_1_visible || _candidate_area_2_visible)) {
+        efl_set_transient_for_app_window (elm_win_xwindow_get (_candidate_window));
+        return;
+    }
+
+    evas_object_show (_candidate_area_1);
+    _candidate_area_1_visible = true;
+    ui_candidate_window_adjust ();
+
+    LOGD ("calling ui_candidate_show ()");
+    ui_candidate_show ();
+    ui_settle_candidate_window ();
+
+#if HAVE_FEEDBACK
+    feedback_result = feedback_initialize ();
+
+    if (FEEDBACK_ERROR_NONE == feedback_result) {
+        LOGD ("Feedback initialize successful");
+        feedback_initialized = true;
+    } else {
+        LOGW ("Feedback initialize fail : %d",feedback_result);
+        feedback_initialized = false;
+    }
+#endif
+}
+
+/**
+ * @brief Hide preedit slot function for PanelAgent.
+ */
+static void slot_hide_preedit_string (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (!_preedit_window || !evas_object_visible_get (_preedit_window))
+        return;
+
+    evas_object_hide (_preedit_window);
+}
+
+/**
+ * @brief Hide aux slot function for PanelAgent.
+ */
+static void slot_hide_aux_string (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (!_aux_area || !_aux_area_visible)
+        return;
+
+    evas_object_hide (_aux_area);
+    _aux_area_visible = false;
+    elm_scroller_region_show (_aux_area, 0, 0, 10, 10);
+    ui_candidate_window_adjust ();
+
+    LOGD ("calling ui_candidate_hide (false)");
+    ui_candidate_hide (false);
+    ui_settle_candidate_window ();
+
+    if (ui_candidate_can_be_hide ()) {
+        _candidate_show_requested = false;
+        LOGD ("setting _show_can didate_requested to FALSE");
+    }
+}
+
+/**
+ * @brief Hide candidate table slot function for PanelAgent.
+ */
+static void slot_hide_candidate_table (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int feedback_result = 0;
+
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW) {
+        _panel_agent->helper_candidate_hide ();
+        return;
+    }
+
+    if (!_candidate_area_1 || _candidate_state == WINDOW_STATE_WILL_HIDE)
+        return;
+
+    if (_candidate_area_1_visible || _candidate_area_2_visible) {
+        bool bForce = false;
+        if (_candidate_area_1_visible) {
+            if (_aux_area_visible) {
+                evas_object_hide (_candidate_area_1);
+                _candidate_area_1_visible = false;
+                evas_object_hide (_more_btn);
+            } else {
+                /* Let's not actually hide the _candidate_area_1 object, for the case that
+                   even if the application replies CANDIDATE_WILL_HIDE_ACK a little late,
+                   it is better to display the previous candidates instead of blank screen */
+                _candidate_area_1_visible = false;
+                bForce = true;
+            }
+        }
+        if (_candidate_area_2_visible) {
+            evas_object_hide (_candidate_area_2);
+            _candidate_area_2_visible = false;
+            evas_object_hide (_scroller_bg);
+            evas_object_hide (_close_btn);
+            _panel_agent->candidate_more_window_hide ();
+        }
+        ui_candidate_window_adjust ();
+
+        LOGD ("calling ui_candidate_hide (%d, true, true)", bForce);
+        ui_candidate_hide (bForce, true, true);
+        ui_settle_candidate_window ();
+    }
+
+#if HAVE_FEEDBACK
+    feedback_result = feedback_deinitialize ();
+
+    if (FEEDBACK_ERROR_NONE == feedback_result)
+        LOGD ("Feedback deinitialize successful");
+    else
+        LOGW ("Feedback deinitialize fail : %d", feedback_result);
+
+    feedback_initialized = false;
+#endif
+
+    if (ui_candidate_can_be_hide ()) {
+        _candidate_show_requested = false;
+        LOGD ("setting _show_can didate_requested to FALSE");
+    }
+}
+
+/**
+ * @brief Update preedit slot function for PanelAgent.
+ *
+ * @param str The new preedit string.
+ * @param attrs The attribute list of new preedit string.
+ */
+static void slot_update_preedit_string (const String &str, const AttributeList &attrs, int caret)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " string=" << str << "\n";
+
+    if (str.length () <= 0)
+        return;
+
+    if (_preedit_window == NULL || !evas_object_visible_get (_preedit_window)) {
+        slot_show_preedit_string ();
+    }
+
+    int x, y, width, height, candidate_width;
+    evas_object_text_text_set (_tmp_preedit_text, str.c_str ());
+    evas_object_geometry_get (_tmp_preedit_text, &x, &y, &width, &height);
+    ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &candidate_width, &height);
+    _preedit_width = (width + ISF_PREEDIT_BORDER * 2) < candidate_width ? (width + ISF_PREEDIT_BORDER * 2) : candidate_width;
+
+    /* Resize preedit window and avoid text blink */
+    int old_width, old_height;
+    evas_object_geometry_get (_preedit_window, &x, &y, &old_width, &old_height);
+    if (old_width < _preedit_width) {
+        evas_object_resize (_preedit_window, _preedit_width, _preedit_height);
+        edje_object_part_text_set (_preedit_text, "preedit", str.c_str ());
+    } else {
+        edje_object_part_text_set (_preedit_text, "preedit", str.c_str ());
+        evas_object_resize (_preedit_window, _preedit_width, _preedit_height);
+    }
+
+    /* Move preedit window */
+    if (_candidate_angle == 90 || _candidate_angle == 180) {
+        ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_preedit_window)), &x, &y, &width, &height);
+        if (_candidate_angle == 90) {
+            y = _screen_height - _preedit_width;
+        } else if (_candidate_angle == 180) {
+            x = _screen_width - _preedit_width;
+        }
+        evas_object_move (_preedit_window, x, y);
+    }
+}
+
+/**
+ * @brief Update caret slot function for PanelAgent.
+ *
+ * @param caret The caret position.
+ */
+static void slot_update_preedit_caret (int caret)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " caret=" << caret << "\n";
+}
+
+/**
+ * @brief Set hightlight text color and background color for edje object.
+ *
+ * @param item The edje object pointer.
+ * @param nForeGround The text color.
+ * @param nBackGround The background color.
+ * @param bSetBack The flag for background color.
+ */
+static void set_highlight_color (Evas_Object *item, uint32 nForeGround, uint32 nBackGround, bool bSetBack)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3;
+    if (edje_object_color_class_get (item, "text_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3)) {
+        r = SCIM_RGB_COLOR_RED(nForeGround);
+        g = SCIM_RGB_COLOR_GREEN(nForeGround);
+        b = SCIM_RGB_COLOR_BLUE(nForeGround);
+        edje_object_color_class_set (item, "text_color", r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3);
+    }
+    if (bSetBack && edje_object_color_class_get (item, "rect_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3)) {
+        r = SCIM_RGB_COLOR_RED(nBackGround);
+        g = SCIM_RGB_COLOR_GREEN(nBackGround);
+        b = SCIM_RGB_COLOR_BLUE(nBackGround);
+        edje_object_color_class_set (item, "rect_color", r, g, b, 255, r2, g2, b2, a2, r3, g3, b3, a3);
+    }
+}
+
+/**
+ * @brief Update aux slot function for PanelAgent.
+ *
+ * @param str The new aux string.
+ * @param attrs The attribute list of new aux string.
+ */
+static void slot_update_aux_string (const String &str, const AttributeList &attrs)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (_candidate_window == NULL)
+        ui_create_candidate_window ();
+
+    if (!_aux_area || (str.length () <= 0))
+        return;
+
+    if (!_aux_area_visible) {
+        LOGD ("calling ui_candidate_show ()");
+        ui_candidate_show ();
+        slot_show_aux_string ();
+    }
+
+    int x, y, width, height, item_width = 0;
+    unsigned int window_width = 0, count = 0, i;
+
+    Evas_Object *aux_edje = NULL;
+
+    /* Get highlight item index */
+    int    aux_index = -1, aux_start = 0, aux_end = 0;
+    String strAux      = str;
+    bool   bSetBack    = false;
+    uint32 nForeGround = SCIM_RGB_COLOR(62, 207, 255);
+    uint32 nBackGround = SCIM_RGB_COLOR(0, 0, 0);
+    for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) {
+        if (aux_index == -1 && ait->get_type () == SCIM_ATTR_DECORATE) {
+            aux_index = ait->get_value ();
+        } else if (ait->get_type () == SCIM_ATTR_FOREGROUND) {
+            nForeGround = ait->get_value ();
+        } else if (ait->get_type () == SCIM_ATTR_BACKGROUND) {
+            nBackGround = ait->get_value ();
+            bSetBack = true;
+        }
+    }
+
+    std::vector<String> aux_list;
+    scim_split_string_list (aux_list, strAux, '|');
+
+    if (_aux_items.size () > 0) {
+        for (i = 0; i < _aux_items.size (); i++)
+            evas_object_del (_aux_items [i]);
+        _aux_items.clear ();
+    }
+    if (_aux_seperates.size () > 0) {
+        for (i = 0; i < _aux_seperates.size (); i++)
+            evas_object_del (_aux_seperates [i]);
+        _aux_seperates.clear ();
+    }
+
+    int   seperate_width  = 4;
+    int   seperate_height = 52 * _height_rate;
+    Evas *evas = evas_object_evas_get (_candidate_window);
+    for (i = 0; i < aux_list.size (); i++) {
+        if (i > 0) {
+            Evas_Object *seperate_item = edje_object_add (evas);
+            edje_object_file_set (seperate_item, _candidate_edje_file.c_str (), "seperate_line");
+            evas_object_size_hint_min_set (seperate_item, seperate_width, seperate_height);
+            elm_table_pack (_aux_table, seperate_item, 2 * i - 1, 0, 1, 1);
+            evas_object_show (seperate_item);
+            _aux_seperates.push_back (seperate_item);
+        }
+
+        count++;
+        aux_edje = edje_object_add (evas);
+        edje_object_file_set (aux_edje, _candidate_edje_file.c_str (), "aux");
+        edje_object_text_class_set (aux_edje, "aux_text_class", _candidate_font_name.c_str (), _aux_font_size);
+        edje_object_part_text_set (aux_edje, "aux", aux_list [i].c_str ());
+        elm_table_pack (_aux_table, aux_edje, 2 * i, 0, 1, 1);
+        evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_AUX));
+        evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i));
+        evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_AUX));
+        evas_object_show (aux_edje);
+        _aux_items.push_back (aux_edje);
+/*      if (i == (unsigned int)aux_index)
+            edje_object_signal_emit (aux_edje, "aux,state,selected", "aux");
+        else
+            edje_object_signal_emit (aux_edje, "aux,state,unselected", "aux");
+*/
+        evas_object_text_text_set (_tmp_aux_text, aux_list [i].c_str ());
+        evas_object_geometry_get (_tmp_aux_text, &x, &y, &width, &height);
+        item_width = width + 2*_blank_width;
+        item_width = item_width > _item_min_width ? item_width : _item_min_width;
+        evas_object_size_hint_min_set (aux_edje, item_width, _aux_height);
+        if (aux_index == (int)i || (aux_index == -1 && i == 0)) {
+            aux_start = window_width;
+            aux_end   = window_width + item_width;
+        }
+        window_width = window_width + item_width + 4;
+    }
+
+    // Set highlight item
+    for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) {
+        if (ait->get_type () == SCIM_ATTR_DECORATE) {
+            unsigned int index = ait->get_value ();
+            if (index < _aux_items.size ())
+                set_highlight_color (_aux_items [index], nForeGround, nBackGround, bSetBack);
+        }
+    }
+
+    int w, h;
+    elm_scroller_region_get (_aux_area, &x, &y, &w, &h);
+    item_width = aux_end - aux_start;
+    if (item_width > 0) {
+        if (item_width >= w)
+            elm_scroller_region_show (_aux_area, aux_end - w, y, w, h);
+        else if (aux_end > x + w)
+            elm_scroller_region_show (_aux_area, aux_end - w, y, w, h);
+        else if (aux_start < x)
+            elm_scroller_region_show (_aux_area, aux_start, y, w, h);
+    }
+    flush_memory ();
+}
+
+/**
+ * @brief Update candidate/associate table.
+ *
+ * @param table_type The table type.
+ * @param table The lookup table for candidate or associate.
+ */
+static void update_table (int table_type, const LookupTable &table)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " (" << table.get_current_page_size () << ")\n";
+
+    int item_num = table.get_current_page_size ();
+    if (item_num < 0)
+        return;
+
+    String     mbs;
+    WideString wcs;
+
+    AttributeList attrs;
+    int i, x, y, width, height, item_0_width = 0;
+
+    int nLast      = 0;
+    std::vector<uint32> row_items;
+
+    int seperate_width  = 4;
+    int seperate_height = 52 * _height_rate;
+    int line_width      = _candidate_scroll_width;
+    int line_height     = _v_padding;
+    int total_width     = 0;
+    int current_width   = 0;
+    int line_0          = 0;
+    int line_count      = 0;
+    int more_item_count = 0;
+    int scroll_0_width  = _candidate_scroll_0_width_min;
+    int cursor_pos      = table.get_cursor_pos ();
+    int cursor_line     = 0;
+
+    if (_candidate_angle == 90 || _candidate_angle == 270)
+        scroll_0_width = 1176 * _height_rate;
+    else
+        scroll_0_width = 618 * _width_rate;
+
+    Evas *evas = evas_object_evas_get (_candidate_window);
+    for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) {
+        if (_candidate_0 [i]) {
+            evas_object_del (_candidate_0 [i]);
+            _candidate_0 [i] = NULL;
+        }
+        if (_seperate_0 [i]) {
+            evas_object_del (_seperate_0 [i]);
+            _seperate_0 [i] = NULL;
+        }
+        if (_candidate_items [i]) {
+            evas_object_del (_candidate_items [i]);
+            _candidate_items [i] = NULL;
+        }
+        if (_seperate_items [i]) {
+            evas_object_del (_seperate_items [i]);
+            _seperate_items [i] = NULL;
+        }
+        if (_line_items [i]) {
+            evas_object_del (_line_items [i]);
+            _line_items [i] = NULL;
+        }
+
+        if (i < item_num) {
+            bool   bHighLight  = false;
+            bool   bSetBack    = false;
+            uint32 nForeGround = SCIM_RGB_COLOR(249, 249, 249);
+            uint32 nBackGround = SCIM_RGB_COLOR(0, 0, 0);
+            attrs = table.get_attributes_in_current_page (i);
+            for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) {
+                if (ait->get_type () == SCIM_ATTR_DECORATE && ait->get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) {
+                    bHighLight  = true;
+                    nForeGround = SCIM_RGB_COLOR(62, 207, 255);
+                } else if (ait->get_type () == SCIM_ATTR_FOREGROUND) {
+                    bHighLight  = true;
+                    nForeGround = ait->get_value ();
+                } else if (ait->get_type () == SCIM_ATTR_BACKGROUND) {
+                    bSetBack    = true;
+                    nBackGround = ait->get_value ();
+                }
+            }
+
+            wcs = table.get_candidate_in_current_page (i);
+            mbs = utf8_wcstombs (wcs);
+
+            if (!_candidate_0 [i] && total_width <= scroll_0_width) {
+                _candidate_0 [i] = edje_object_add (evas);
+                edje_object_file_set (_candidate_0 [i], _candidate_edje_file.c_str (), _candidate_name.c_str ());
+                edje_object_text_class_set (_candidate_0 [i], "candidate_text_class", _candidate_font_name.c_str (), _candidate_font_size);
+                evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_CANDIDATE_0));
+                evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i));
+                evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_CANDIDATE_0));
+                evas_object_show (_candidate_0 [i]);
+
+                edje_object_part_text_set (_candidate_0 [i], "candidate", mbs.c_str ());
+                /* Resize _candidate_0 [i] display width */
+                evas_object_text_text_set (_tmp_candidate_text, mbs.c_str ());
+                evas_object_geometry_get (_tmp_candidate_text, &x, &y, &width, &height);
+                item_0_width = width + 2*_blank_width;
+                item_0_width = item_0_width > _item_min_width ? item_0_width : _item_min_width;
+                evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height);
+                if (bHighLight || bSetBack) {
+                    set_highlight_color (_candidate_0 [i], nForeGround, nBackGround, bSetBack);
+                }
+
+                /* Check whether this item is the last one */
+                if (i == item_num - 1) {
+                    if (_candidate_angle == 90 || _candidate_angle == 270)
+                        scroll_0_width = _candidate_land_width;
+                    else
+                        scroll_0_width = _candidate_port_width;
+                }
+
+                /* Add first item */
+                if (i == 0) {
+                    item_0_width = item_0_width > scroll_0_width ? scroll_0_width : item_0_width;
+                    evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height);
+                    elm_table_pack (_candidate_0_table, _candidate_0 [i], 0, 0, item_0_width, _item_min_height);
+                    total_width += item_0_width;
+                    continue;
+                } else {
+                    total_width += (item_0_width + seperate_width);
+                    if (total_width <= scroll_0_width) {
+                        _seperate_0 [i] = edje_object_add (evas);
+                        edje_object_file_set (_seperate_0 [i], _candidate_edje_file.c_str (), "seperate_line");
+                        evas_object_size_hint_min_set (_seperate_0 [i], seperate_width, seperate_height);
+                        elm_table_pack (_candidate_0_table, _seperate_0 [i],
+                                        total_width - item_0_width - seperate_width,
+                                        line_0*(_item_min_height+line_height) + (_item_min_height - seperate_height)/2,
+                                        seperate_width, seperate_height);
+                        evas_object_show (_seperate_0 [i]);
+
+                        elm_table_pack (_candidate_0_table, _candidate_0 [i], total_width - item_0_width, line_0*(_item_min_height+line_height), item_0_width, _item_min_height);
+                        continue;
+                    } else if ((_candidate_angle == 0 || _candidate_angle == 180) &&
+                               (_candidate_port_line > 1 && (line_0 + 1) < _candidate_port_line)) {
+                        line_0++;
+                        scroll_0_width = _candidate_scroll_0_width_min;
+                        item_0_width = item_0_width > scroll_0_width ? scroll_0_width : item_0_width;
+                        evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height);
+                        elm_table_pack (_candidate_0_table, _candidate_0 [i], 0, line_0*(_item_min_height+line_height), item_0_width, _item_min_height);
+                        total_width = item_0_width;
+
+                        row_items.push_back (i - nLast);
+                        nLast = i;
+                        continue;
+                    } else {
+                        row_items.push_back (i - nLast);
+                        nLast = i;
+                    }
+                }
+            }
+
+            if (!_candidate_items [i]) {
+                _candidate_items [i] = edje_object_add (evas);
+                edje_object_file_set (_candidate_items [i], _candidate_edje_file.c_str (), _candidate_name.c_str ());
+                edje_object_text_class_set (_candidate_items [i], "candidate_text_class", _candidate_font_name.c_str (), _candidate_font_size);
+                evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_CANDIDATE_ITEMS));
+                evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i));
+                evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_CANDIDATE_ITEMS));
+                evas_object_show (_candidate_items [i]);
+            }
+            if (bHighLight || bSetBack) {
+                set_highlight_color (_candidate_items [i], nForeGround, nBackGround, bSetBack);
+            }
+            edje_object_part_text_set (_candidate_items [i], "candidate", mbs.c_str ());
+            /* Resize _candidate_items [i] display width */
+            evas_object_text_text_set (_tmp_candidate_text, mbs.c_str ());
+            evas_object_geometry_get (_tmp_candidate_text, &x, &y, &width, &height);
+            item_0_width = width + 2*_blank_width;
+            item_0_width = item_0_width > _item_min_width ? item_0_width : _item_min_width;
+            evas_object_size_hint_min_set (_candidate_items [i], item_0_width, _item_min_height);
+            if (current_width > 0 && current_width + item_0_width > _candidate_scroll_width) {
+                current_width = 0;
+                line_count++;
+
+                row_items.push_back (i - nLast);
+                nLast = i;
+                if (cursor_pos >= i)
+                    cursor_line++;
+            }
+            if (current_width == 0 && !_line_items [i]) {
+                _line_items [i] = edje_object_add (evas);
+                edje_object_file_set (_line_items [i], _candidate_edje_file.c_str (), "popup_line");
+                evas_object_size_hint_min_set (_line_items [i], line_width, line_height);
+                x = 0;
+                y = line_count*(_item_min_height+line_height);
+                elm_table_pack (_candidate_table, _line_items [i], x, y, line_width, line_height);
+                evas_object_show (_line_items [i]);
+            }
+            if (current_width != 0 && !_seperate_items [i]) {
+                _seperate_items [i] = edje_object_add (evas);
+                edje_object_file_set (_seperate_items [i], _candidate_edje_file.c_str (), "seperate_line");
+                evas_object_size_hint_min_set (_seperate_items [i], seperate_width, seperate_height);
+                x = current_width;
+                y = line_count*(_item_min_height+line_height) + line_height + (_item_min_height - seperate_height)/2;
+                elm_table_pack (_candidate_table, _seperate_items [i], x, y, seperate_width, seperate_height);
+                evas_object_show (_seperate_items [i]);
+                current_width += seperate_width;
+            }
+            x = current_width;
+            y = line_count*(_item_min_height+line_height) + line_height;
+            elm_table_pack (_candidate_table, _candidate_items [i], x, y, item_0_width, _item_min_height);
+            current_width += item_0_width;
+            more_item_count++;
+        }
+    }
+
+    for (i = 1; i < _candidate_port_line; i++) {
+        if ((_candidate_angle == 0 || _candidate_angle == 180)) {
+            if (_line_0 [i] == NULL) {
+                _line_0 [i] = edje_object_add (evas);
+                edje_object_file_set (_line_0 [i], _candidate_edje_file.c_str (), "popup_line");
+                evas_object_size_hint_min_set (_line_0 [i], line_width, line_height);
+                x = 0;
+                y = i * (_item_min_height + line_height) - line_height;
+                elm_table_pack (_candidate_0_table, _line_0 [i], x, y, line_width, line_height);
+                evas_object_show (_line_0 [i]);
+            }
+
+            // Create blank line
+            if (line_0 + 1 < _candidate_port_line && i > line_0) {
+                int nIndex = item_num + i;
+                nIndex = nIndex < SCIM_LOOKUP_TABLE_MAX_PAGESIZE ? nIndex : SCIM_LOOKUP_TABLE_MAX_PAGESIZE - 1;
+                _seperate_0 [nIndex] = edje_object_add (evas);
+                edje_object_file_set (_seperate_0 [nIndex], _candidate_edje_file.c_str (), "seperate_line");
+                evas_object_size_hint_min_set (_seperate_0 [nIndex], seperate_width, _item_min_height);
+                elm_table_pack (_candidate_0_table, _seperate_0 [nIndex],
+                                0, i*(_item_min_height+line_height), seperate_width, _item_min_height);
+            }
+        } else if (_line_0 [i]) {
+            evas_object_del (_line_0 [i]);
+            _line_0 [i] = NULL;
+        }
+    }
+
+    row_items.push_back (item_num - nLast);     /* Add the number of last row */
+    _panel_agent->update_candidate_item_layout (row_items);
+    _panel_agent->update_displayed_candidate_number (item_num - more_item_count);
+    if (more_item_count == 0) {
+        ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL);
+        evas_object_hide (_more_btn);
+        evas_object_hide (_close_btn);
+    } else if (!_candidate_area_2_visible) {
+        evas_object_show (_more_btn);
+        evas_object_hide (_close_btn);
+    } else {
+        evas_object_hide (_more_btn);
+        evas_object_show (_close_btn);
+    }
+
+    int w, h;
+    elm_scroller_region_get (_candidate_area_2, &x, &y, &w, &h);
+
+    int line_h   = _item_min_height + _v_padding;
+    int cursor_y = cursor_line * line_h;
+    if (cursor_y < y) {
+        elm_scroller_region_show (_candidate_area_2, 0, cursor_y, w, h);
+    } else if (cursor_y >= y + h) {
+        elm_scroller_region_show (_candidate_area_2, 0, cursor_y + line_h - h, w, h);
+    }
+
+    flush_memory ();
+}
+
+/**
+ * @brief Update candidate table slot function for PanelAgent.
+ *
+ * @param table The lookup table for candidate.
+ */
+static void slot_update_candidate_table (const LookupTable &table)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW){
+        _panel_agent->update_helper_lookup_table (table);
+        return ;
+    }
+
+    if (_candidate_window == NULL)
+        ui_create_candidate_window ();
+
+    if (!_candidate_window || table.get_current_page_size () < 0)
+        return;
+
+    update_table (ISF_CANDIDATE_TABLE, table);
+}
+
+/**
+ * @brief Send selected candidate index.
+ *
+ * @param selected candidate string index number.
+ */
+static void slot_select_candidate (int index)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    _panel_agent->select_candidate (index);
+}
+
+/**
+ * @brief Get candidate geometry slot function for PanelAgent.
+ *
+ * @param info The data is used to store candidate position and size.
+ */
+static void slot_get_candidate_geometry (struct rectinfo &info)
+{
+    int x      = 0;
+    int y      = 0;
+    int width  = 0;
+    int height = 0;
+
+    if (_candidate_mode == SOFT_CANDIDATE_WINDOW) {
+        info.pos_x  = x;
+        info.pos_y  = y;
+        info.width  = width;
+        info.height = height;
+        return;
+    }
+
+    if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+        /* Get candidate window position */
+        /*ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &width, &height);*/
+        /* Get exact candidate window size */
+        /*int x2, y2;
+          evas_object_geometry_get (_candidate_window, &x2, &y2, &width, &height);*/
+
+        x      = _candidate_x;
+        y      = _candidate_y;
+        width  = _candidate_width;
+        height = _candidate_height;
+    }
+    info.pos_x  = x;
+    info.pos_y  = y;
+    info.width  = width;
+    info.height = height;
+
+    LOGD ("%d %d %d %d", info.pos_x, info.pos_y, info.width, info.height);
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << info.pos_x << " y:" << info.pos_y
+                        << " width:" << info.width << " height:" << info.height << "\n";
+}
+
+/**
+ * @brief Get input panel geometry slot function for PanelAgent.
+ *
+ * @param info The data is used to store input panel position and size.
+ */
+static void slot_get_input_panel_geometry (struct rectinfo &info)
+{
+    int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+    if (hw_kbd_detect) {
+        info.pos_x = 0;
+        info.width = 0;
+        info.height = 0;
+        if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+            info.width  = _candidate_width;
+            info.height = _candidate_height;
+        }
+        int angle = efl_get_angle_for_app_window ();
+        if (angle == 90 || angle == 270)
+            info.pos_y = _screen_width - info.height;
+        else
+            info.pos_y = _screen_height - info.height;
+    } else {
+        info = get_ise_geometry ();
+        if (_ise_state != WINDOW_STATE_SHOW) {
+            info.width = 0;
+            info.height = 0;
+        } else {
+            if (_candidate_mode == FIXED_CANDIDATE_WINDOW) {
+                if (_candidate_window && _candidate_state == WINDOW_STATE_SHOW) {
+                    int height = ui_candidate_get_valid_height ();
+
+                    if ((_candidate_height - height) > _ise_height) {
+                        info.pos_y  = info.pos_y + info.height - _candidate_height;
+                        info.height = _candidate_height;
+                    } else {
+                        info.pos_y  -= height;
+                        info.height += height;
+                    }
+                }
+            }
+        }
+    }
+
+    LOGD ("%d %d %d %d", info.pos_x, info.pos_y, info.width, info.height);
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << info.pos_x << " y:" << info.pos_y
+                        << " width:" << info.width << " height:" << info.height << "\n";
+}
+
+/**
+ * @brief Set active ISE slot function for PanelAgent.
+ *
+ * @param uuid The active ISE's uuid.
+ * @param changeDefault The flag for changeing default ISE.
+ */
+static void slot_set_active_ise (const String &uuid, bool changeDefault)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " (" << uuid << ")\n";
+
+    set_active_ise (uuid);
+}
+
+/**
+ * @brief Get all ISEs list slot function for PanelAgent.
+ *
+ * @param list The list is used to store all ISEs.
+ *
+ * @return true if this operation is successful, otherwise return false.
+ */
+static bool slot_get_ise_list (std::vector<String> &list)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* update ise list */
+    bool ret = isf_update_ise_list (ALL_ISE, _config);
+
+    list.clear ();
+    list = _uuids;
+
+    _panel_agent->update_ise_list (list);
+
+    if (ret && _initial_ise_uuid.length () > 0) {
+        String active_uuid   = _initial_ise_uuid;
+        String default_uuid  = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), String (""));
+        int    hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+        if (std::find (_uuids.begin (), _uuids.end (), default_uuid) == _uuids.end ()) {
+            if (hw_kbd_detect && _modes[get_ise_index (_initial_ise_uuid)] != TOOLBAR_KEYBOARD_MODE) {
+                active_uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID);
+            }
+            set_active_ise (active_uuid);
+        } else if (!hw_kbd_detect) {    // Check whether keyboard engine is installed
+            String IMENGINE_KEY  = String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + String ("~other");
+            String keyboard_uuid = _config->read (IMENGINE_KEY, String (""));
+            if (std::find (_uuids.begin (), _uuids.end (), keyboard_uuid) == _uuids.end ()) {
+                active_uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID);
+                _panel_agent->change_factory (active_uuid);
+                _config->write (IMENGINE_KEY, active_uuid);
+                _config->flush ();
+            }
+        }
+    }
+
+    add_ise_directory_em ();
+    return ret;
+}
+
+/**
+ * @brief Get the ISE's information.
+ *
+ * @param uuid The ISE's uuid.
+ * @param name The ISE's name.
+ * @param language The ISE's language.
+ * @param type The ISE's type.
+ * @param option The ISE's option.
+ *
+ * @return true if this operation is successful, otherwise return false.
+ */
+static bool slot_get_ise_information (String uuid, String &name, String &language, int &type, int &option, String &module_name)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (uuid.length () > 0) {
+        for (unsigned int i = 0; i < _uuids.size (); i++) {
+            if (uuid == _uuids[i]) {
+                name     = _names[i];
+                language = _langs[i];
+                type     = _modes[i];
+                option   = _options[i];
+                module_name = "";
+                return true;
+            }
+        }
+    }
+
+    std::cerr << __func__ << " is failed!!!\n";
+    return false;
+}
+
+/**
+ * @brief Get keyboard ISEs list slot function for PanelAgent.
+ *
+ * @param name_list The list is used to store keyboard ISEs.
+ *
+ * @return true if this operation is successful, otherwise return false.
+ */
+static bool slot_get_keyboard_ise_list (std::vector<String> &name_list)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* update ise list */
+    bool ret = isf_update_ise_list (ALL_ISE, _config);
+
+    std::vector<String> lang_list, uuid_list;
+    isf_get_all_languages (lang_list);
+    isf_get_keyboard_ises_in_languages (lang_list, uuid_list, name_list, false);
+
+    if (ret)
+        _panel_agent->update_ise_list (uuid_list);
+    return ret;
+}
+
+/**
+ * @brief Get enable languages list slot function for PanelAgent.
+ *
+ * @param list The list is used to store languages.
+ */
+static void slot_get_language_list (std::vector<String> &list)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    String lang_name;
+    MapStringVectorSizeT::iterator iter = _groups.begin ();
+
+    for (; iter != _groups.end (); iter++) {
+        lang_name = scim_get_language_name (iter->first);
+        list.push_back (lang_name);
+    }
+}
+
+/**
+ * @brief Get all languages list slot function for PanelAgent.
+ *
+ * @param lang The list is used to store languages.
+ */
+static void slot_get_all_language (std::vector<String> &lang)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    isf_get_all_languages (lang);
+}
+
+/**
+ * @brief Get specific ISE language list slot function for PanelAgent.
+ *
+ * @param name The ISE name.
+ * @param list The list is used to store ISE languages.
+ */
+static void slot_get_ise_language (char *name, std::vector<String> &list)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (name == NULL)
+        return;
+
+    unsigned int num = _names.size ();
+    std::vector<String> list_tmp;
+    list_tmp.clear ();
+    for (unsigned int i = 0; i < num; i++) {
+        if (!strcmp (_names[i].c_str (), name)) {
+            scim_split_string_list (list_tmp, _langs[i], ',');
+            for (i = 0; i < list_tmp.size (); i++)
+                list.push_back (scim_get_language_name (list_tmp[i]));
+            return;
+        }
+    }
+}
+
+/**
+ * @brief Get ISE information slot function for PanelAgent.
+ *
+ * @param uuid The ISE uuid.
+ * @param info The variable is used to store ISE information.
+ *
+ * @return true if this operation is successful, otherwise return false.
+ */
+static bool slot_get_ise_info (const String &uuid, ISE_INFO &info)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    for (unsigned int i = 0; i < _uuids.size (); i++) {
+        if (!uuid.compare (_uuids[i])) {
+            info.uuid   = _uuids[i];
+            info.name   = _names[i];
+            info.icon   = _icons[i];
+            info.lang   = _langs[i];
+            info.option = _options[i];
+            info.type   = _modes[i];
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief Set keyboard ISE slot function for PanelAgent.
+ *
+ * @param uuid The variable is ISE uuid.
+ */
+static void slot_set_keyboard_ise (const String &uuid)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " uuid = " << uuid << "\n";
+
+    if (uuid.length () <= 0 || std::find (_uuids.begin (), _uuids.end (), uuid) == _uuids.end ())
+        return;
+
+    String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), String (""));
+    if (_modes[get_ise_index (default_uuid)] == TOOLBAR_KEYBOARD_MODE)
+        return;
+
+    uint32 ise_option = 0;
+    String ise_uuid, ise_name;
+    isf_get_keyboard_ise (_config, ise_uuid, ise_name, ise_option);
+    if (ise_uuid == uuid)
+        return;
+
+    String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/
+    _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, uuid);
+    _config->flush ();
+    _config->reload ();
+
+    _panel_agent->change_factory (uuid);
+    _panel_agent->reload_config ();
+}
+
+/**
+ * @brief Get current keyboard ISE name and uuid slot function for PanelAgent.
+ *
+ * @param ise_name The variable is used to store ISE name.
+ * @param ise_uuid The variable is used to store ISE uuid.
+ */
+static void slot_get_keyboard_ise (String &ise_name, String &ise_uuid)
+{
+    uint32 ise_option = 0;
+    isf_get_keyboard_ise (_config, ise_uuid, ise_name, ise_option);
+
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " uuid = " << ise_uuid << "\n";
+}
+
+/**
+ * @brief Accept connection slot function for PanelAgent.
+ *
+ * @param fd The file descriptor to connect.
+ */
+static void slot_accept_connection (int fd)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    Ecore_Fd_Handler *panel_agent_read_handler = ecore_main_fd_handler_add (fd, ECORE_FD_READ, panel_agent_handler, NULL, NULL, NULL);
+    _read_handler_list.push_back (panel_agent_read_handler);
+}
+
+/**
+ * @brief Close connection slot function for PanelAgent.
+ *
+ * @param fd The file descriptor to connect.
+ */
+static void slot_close_connection (int fd)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    int i = 0;
+    std::vector<Ecore_Fd_Handler *>::iterator IterPos;
+
+    for (IterPos = _read_handler_list.begin (); IterPos != _read_handler_list.end (); ++IterPos,++i) {
+        if (ecore_main_fd_handler_fd_get (_read_handler_list[i]) == fd) {
+            ecore_main_fd_handler_del (_read_handler_list[i]);
+            _read_handler_list.erase (IterPos);
+            break;
+        }
+    }
+}
+
+/**
+ * @brief Exit panel process slot function for PanelAgent.
+ */
+static void slot_exit (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    elm_exit ();
+}
+
+static void slot_register_helper_properties (int id, const PropertyList &props)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* WMSYNC, #2 Receiving X window ID from ISE */
+    /* FIXME : We should add an API to set window id of ISE */
+}
+
+static void slot_show_ise (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* If the candidate was already in SHOW state, respect the current angle */
+    if (_candidate_state != WINDOW_STATE_SHOW) {
+        /* FIXME : Need to check if candidate_angle and window_angle should be left as separated */
+        _candidate_angle = efl_get_angle_for_app_window ();
+        _window_angle = efl_get_angle_for_app_window ();
+    }
+
+    efl_set_transient_for_app_window (_ise_window);
+
+    /* If our ISE was already in SHOW state, skip state transition to WILL_SHOW */
+    if (_ise_state != WINDOW_STATE_SHOW) {
+        _ise_state = WINDOW_STATE_WILL_SHOW;
+    }
+}
+
+static void slot_hide_ise (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* Only if we are not already in HIDE state */
+    if (_ise_state != WINDOW_STATE_HIDE) {
+        _ise_state = WINDOW_STATE_WILL_HIDE;
+    }
+    _window_angle = -1;
+
+    if (_candidate_window) {
+        int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+        if (hw_kbd_detect)
+            ui_candidate_hide (true, true, true);
+    }
+}
+
+static void slot_will_hide_ack (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* WMSYNC, #8 Let the Window Manager to actually hide keyboard window */
+    // WILL_HIDE_REQUEST_DONE Ack to WM
+    // FIXME:
+}
+
+static void slot_candidate_will_hide_ack (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    // FIXME:
+}
+
+static void slot_get_ise_state (int &state)
+{
+    if (_ise_state == WINDOW_STATE_SHOW ||
+        (hw_kbd_mode && _candidate_state == WINDOW_STATE_SHOW)) {
+        state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
+    } else {
+        /* Currently we don't have WILL_HIDE / HIDE state distinction in Ecore_IMF */
+        switch (_ise_state) {
+            case WINDOW_STATE_SHOW :
+                state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
+                break;
+            case WINDOW_STATE_WILL_SHOW :
+                state = ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW;
+                break;
+            case WINDOW_STATE_WILL_HIDE :
+                state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
+                break;
+            case WINDOW_STATE_HIDE :
+                state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
+                break;
+            default :
+                state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
+        };
+    }
+    LOGD ("state = %d", state);
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " state = " << state << "\n";
+}
+
+//////////////////////////////////////////////////////////////////////
+// End of PanelAgent-Functions
+//////////////////////////////////////////////////////////////////////
+
+
+/**
+ * @brief Callback function for ecore fd handler.
+ *
+ * @param data The data to pass to this callback.
+ * @param fd_handler The ecore fd handler.
+ *
+ * @return ECORE_CALLBACK_RENEW
+ */
+static Eina_Bool panel_agent_handler (void *data, Ecore_Fd_Handler *fd_handler)
+{
+    if (fd_handler == NULL)
+        return ECORE_CALLBACK_RENEW;
+
+    int fd = ecore_main_fd_handler_fd_get (fd_handler);
+    for (unsigned int i = 0; i < _read_handler_list.size (); i++) {
+        if (fd_handler == _read_handler_list [i]) {
+            if (!_panel_agent->filter_event (fd)) {
+                std::cerr << "_panel_agent->filter_event () is failed!!!\n";
+                ecore_main_fd_handler_del (fd_handler);
+            }
+            return ECORE_CALLBACK_RENEW;
+        }
+    }
+    std::cerr << "panel_agent_handler () has received exception event!!!\n";
+    _panel_agent->filter_exception_event (fd);
+    ecore_main_fd_handler_del (fd_handler);
+    return ECORE_CALLBACK_RENEW;
+}
+
+/**
+ * @brief Handler function for HelperManager input.
+ *
+ * @param data The data to pass to this callback.
+ * @param fd_handler The Ecore Fd handler.
+ *
+ * @return ECORE_CALLBACK_RENEW
+ */
+static Eina_Bool helper_manager_input_handler (void *data, Ecore_Fd_Handler *fd_handler)
+{
+    if (_panel_agent->has_helper_manager_pending_event ()) {
+        if (!_panel_agent->filter_helper_manager_event ()) {
+            std::cerr << "_panel_agent->filter_helper_manager_event () is failed!!!\n";
+            elm_exit ();
+        }
+    } else {
+        std::cerr << "_panel_agent->has_helper_manager_pending_event () is failed!!!\n";
+        elm_exit ();
+    }
+
+    return ECORE_CALLBACK_RENEW;
+}
+
+/**
+ * @brief Callback function for abnormal signal.
+ *
+ * @param sig The signal.
+ */
+static void signalhandler (int sig)
+{
+    SCIM_DEBUG_MAIN (1) << __FUNCTION__ << " Signal=" << sig << "\n";
+
+    elm_exit ();
+}
+
+#if HAVE_VCONF
+/**
+ * @brief Update keyboard ISE name when display language is changed.
+ *
+ * @param module_name The keyboard ISE module name.
+ * @param index The index of _module_names.
+ *
+ * @return true if successful, otherwise return false.
+ */
+static bool update_keyboard_ise_locale (const String module_name, int index)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (module_name.length () <= 0 || module_name == "socket")
+        return false;
+
+    IMEngineFactoryPointer factory;
+    IMEngineModule         ime_module;
+    ime_module.load (module_name, _config);
+
+    if (ime_module.valid ()) {
+        for (size_t j = 0; j < ime_module.number_of_factories (); ++j) {
+            try {
+                factory = ime_module.create_factory (j);
+            } catch (...) {
+                factory.reset ();
+            }
+            if (!factory.null ()) {
+                _names[index+j] = utf8_wcstombs (factory->get_name ());
+                factory.reset ();
+            }
+        }
+        ime_module.unload ();
+    } else {
+        std::cerr << module_name << " can not be loaded!!!\n";
+    }
+
+    return true;
+}
+
+/**
+ * @brief Update helper ISE name when display language is changed.
+ *
+ * @param module_name The helper ISE module name.
+ * @param index The index of _module_names.
+ *
+ * @return true if successful, otherwise return false.
+ */
+static bool update_helper_ise_locale (const String module_name, int index)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+    if (module_name.length () <= 0)
+        return false;
+
+    HelperModule helper_module;
+    HelperInfo   helper_info;
+    helper_module.load (module_name);
+    if (helper_module.valid ()) {
+        for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) {
+            helper_module.get_helper_info (j, helper_info);
+            _names[index+j] = helper_info.name;
+        }
+        helper_module.unload ();
+    } else {
+        std::cerr << module_name << " can not be loaded!!!\n";
+    }
+
+    return true;
+}
+
+/**
+ * @brief Set language and locale.
+ *
+ * @return void
+ */
+static void set_language_and_locale (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    char *lang_str = vconf_get_str (VCONFKEY_LANGSET);
+
+    if (lang_str) {
+        setenv ("LANG", lang_str, 1);
+        setlocale (LC_MESSAGES, lang_str);
+        free (lang_str);
+    } else {
+        setenv ("LANG", "en_US.utf8", 1);
+        setlocale (LC_MESSAGES, "en_US.utf8");
+    }
+}
+
+/**
+ * @brief Callback function for display language change.
+ *
+ * @param key The key node.
+ * @param data The data to pass to this callback.
+ *
+ * @return void
+ */
+static void display_language_changed_cb (keynode_t *key, void* data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    set_language_and_locale ();
+
+    /* Update all ISE names according to display language */
+    std::vector<String> module_list;
+    for (unsigned int i = 0; i < _module_names.size (); i++) {
+        if (std::find (module_list.begin (), module_list.end (), _module_names[i]) != module_list.end ())
+            continue;
+        module_list.push_back (_module_names[i]);
+        if (_module_names[i] == String (COMPOSE_KEY_MODULE)) {
+            IMEngineFactoryPointer factory;
+            factory = new ComposeKeyFactory ();
+            _names[i] = utf8_wcstombs (factory->get_name ());
+            factory.reset ();
+        } else if (_modes[i] == TOOLBAR_KEYBOARD_MODE) {
+            update_keyboard_ise_locale (_module_names[i], i);
+        } else if (_modes[i] == TOOLBAR_HELPER_MODE) {
+            update_helper_ise_locale (_module_names[i], i);
+        }
+    }
+    isf_save_ise_information ();
+
+    String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid);
+    String default_name = _names[get_ise_index (default_uuid)];
+    _panel_agent->set_current_ise_name (default_name);
+    _config->reload ();
+}
+#endif
+
+/**
+ * @brief Start default ISE.
+ *
+ * @return void
+ */
+static void start_default_ise (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid);
+    if (!set_active_ise (default_uuid)) {
+        std::cerr << __FUNCTION__ << " Failed to launch default ISE(" << default_uuid << ")\n";
+        LOGW ("Failed to launch default ISE (%s)\n", default_uuid.c_str ());
+
+        if (default_uuid != _initial_ise_uuid) {
+            std::cerr << __FUNCTION__ << " Launch initial ISE(" << _initial_ise_uuid << ")\n";
+            if (!set_active_ise (_initial_ise_uuid)) {
+                LOGW ("Failed to launch initial ISE (%s)\n", _initial_ise_uuid.c_str ());
+            } else {
+                LOGD ("Succeed to launch initial ISE (%s)\n", _initial_ise_uuid.c_str ());
+            }
+        }
+    } else {
+        LOGD ("Succeed to launch default ISE (%s)\n", default_uuid.c_str ());
+    }
+}
+
+/**
+ * @brief Check hardware keyboard.
+ *
+ * @return void
+ */
+static void check_hardware_keyboard (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_off_prepare_done_timer) {
+        ecore_timer_del (_off_prepare_done_timer);
+        _off_prepare_done_timer = NULL;
+    }
+
+    unsigned int val = 0;
+
+    _config->write (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0);
+    
+    //FIXME:
+    uint32 option = 0;
+    String uuid, name;
+    String helper_uuid  = _config->read (SCIM_CONFIG_DEFAULT_HELPER_ISE, String (""));
+    String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), String (""));
+
+    /* When switching back to S/W keyboard mode, let's hide candidate window first */
+    LOGD ("calling ui_candidate_hide (true, true, true)");
+    ui_candidate_hide (true, true, true);
+    uuid = helper_uuid.length () > 0 ? helper_uuid : _initial_ise_uuid;
+    hw_kbd_mode = false;
+    _panel_agent->reset_keyboard_ise ();
+
+    set_active_ise (uuid);
+}
+
+/**
+ * @brief : Checks whether the window manager is launched or not
+ * @return true if window manager launched, else false
+ */
+static bool check_wm_ready (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    return true;
+}
+
+/**
+ * @brief : Checks whether the system service is ready or not
+ * @return true if all system service are ready, else false
+ */
+static bool check_system_ready (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    int ret = 0;
+    int val = 0;
+    ret = vconf_get_int (ISF_SYSTEM_APPSERVICE_READY_VCONF, &val);
+
+    LOGD ("ret : %d, val : %d\n", ret, val);
+
+    if (ret == 0 && val >= ISF_SYSTEM_APPSERVICE_READY_STATE) {
+        LOGD ("Appservice was ready\n");
+        return true;
+    } else {
+        /* Register a call back function for checking system ready */
+        if (!_appsvc_callback_regist) {
+            if (vconf_notify_key_changed (ISF_SYSTEM_APPSERVICE_READY_VCONF, launch_default_soft_keyboard, NULL)) {
+                _appsvc_callback_regist = true;
+            }
+
+            if (!_system_ready_timer) {
+                _system_ready_timer = ecore_timer_add (5.0, system_ready_timeout_cb, NULL);
+            }
+        }
+
+        return false;
+    }
+}
+
+static void _launch_default_soft_keyboard (void)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    if (_appsvc_callback_regist)
+        vconf_ignore_key_changed (ISF_SYSTEM_APPSERVICE_READY_VCONF, launch_default_soft_keyboard);
+
+    if (_system_ready_timer) {
+        ecore_timer_del (_system_ready_timer);
+        _system_ready_timer = NULL;
+    }
+
+    /* Start default ISE */
+    start_default_ise ();
+    check_hardware_keyboard ();
+}
+
+/**
+ * @brief : Launches default soft keyboard for performance enhancement (It's not mandatory)
+ */
+static void launch_default_soft_keyboard (keynode_t *key, void* data)
+{
+    SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
+
+    /* Soft keyboard will be started when all system service are ready */
+    if (check_system_ready ()) {
+        _launch_default_soft_keyboard ();
+    }
+}
+
+int main (int argc, char *argv [])
+{
+    struct tms    tiks_buf;
+    _clock_start = times (&tiks_buf);
+
+    int           i;
+    int           ret             = 0;
+
+    bool          daemon          = false;
+    bool          should_resident = true;
+
+    int           new_argc        = 0;
+    char        **new_argv        = new char * [40];
+    ConfigModule *config_module   = NULL;
+    String        config_name     = String ("socket");
+    String        display_name    = String ();
+
+    Ecore_Fd_Handler *panel_agent_read_handler = NULL;
+    Ecore_Fd_Handler *helper_manager_handler   = NULL;
+
+    check_time ("\nStarting ISF WSM EFL...... ");
+    LOGD ("Starting ISF WSM EFL...... \n");
+
+    DebugOutput::disable_debug (SCIM_DEBUG_AllMask);
+    DebugOutput::enable_debug (SCIM_DEBUG_MainMask);
+
+    /* Parse command options */
+    i = 0;
+    while (i < argc) {
+        if (++i >= argc)
+            break;
+
+        if (String ("-c") == argv [i] || String ("--config") == argv [i]) {
+            if (++i >= argc) {
+                std::cerr << "no argument for option " << argv [i-1] << "\n";
+                ret = -1;
+                goto cleanup;
+            }
+            config_name = argv [i];
+            continue;
+        }
+
+        if (String ("-h") == argv [i] || String ("--help") == argv [i]) {
+            std::cout << "Usage: " << argv [0] << " [option]...\n\n"
+                 << "The options are: \n"
+                 << "  --display DISPLAY    Run on display DISPLAY.\n"
+                 << "  -c, --config NAME    Uses specified Config module.\n"
+                 << "  -d, --daemon         Run " << argv [0] << " as a daemon.\n"
+                 << "  -ns, --no-stay       Quit if no connected client.\n"
+#if ENABLE_DEBUG
+                 << "  -v, --verbose LEVEL  Enable debug info, to specific LEVEL.\n"
+                 << "  -o, --output FILE    Output debug information into FILE.\n"
+#endif
+                 << "  -h, --help           Show this help message.\n";
+            delete []new_argv;
+            return 0;
+        }
+
+        if (String ("-d") == argv [i] || String ("--daemon") == argv [i]) {
+            daemon = true;
+            continue;
+        }
+
+        if (String ("-ns") == argv [i] || String ("--no-stay") == argv [i]) {
+            should_resident = false;
+            continue;
+        }
+
+        if (String ("-v") == argv [i] || String ("--verbose") == argv [i]) {
+            if (++i >= argc) {
+                std::cerr << "no argument for option " << argv [i-1] << "\n";
+                ret = -1;
+                goto cleanup;
+            }
+            DebugOutput::set_verbose_level (atoi (argv [i]));
+            continue;
+        }
+
+        if (String ("-o") == argv [i] || String ("--output") == argv [i]) {
+            if (++i >= argc) {
+                std::cerr << "No argument for option " << argv [i-1] << "\n";
+                ret = -1;
+                goto cleanup;
+            }
+            DebugOutput::set_output (argv [i]);
+            continue;
+        }
+
+        if (String ("--display") == argv [i]) {
+            if (++i >= argc) {
+                std::cerr << "No argument for option " << argv [i-1] << "\n";
+                ret = -1;
+                goto cleanup;
+            }
+            display_name = argv [i];
+            continue;
+        }
+
+        if (String ("--") == argv [i])
+            break;
+
+        std::cerr << "Invalid command line option: " << argv [i] << "\n";
+        delete []new_argv;
+        return 0;
+    } /* End of command line parsing. */
+
+    new_argv [new_argc ++] = argv [0];
+
+    /* Store the rest argvs into new_argv. */
+    for (++i; i < argc && new_argc < 37; ++i) {
+        new_argv [new_argc ++] = argv [i];
+    }
+
+    /* Make up DISPLAY env. */
+    if (display_name.length ()) {
+        new_argv [new_argc ++] = const_cast <char*> ("--display");
+        new_argv [new_argc ++] = const_cast <char*> (display_name.c_str ());
+
+        setenv ("DISPLAY", display_name.c_str (), 1);
+    }
+
+    new_argv [new_argc] = 0;
+
+    if (!config_name.length ()) {
+        std::cerr << "No Config module is available!\n";
+        ret = -1;
+        goto cleanup;
+    }
+
+    if (config_name != "dummy") {
+        /* Load config module */
+        config_module = new ConfigModule (config_name);
+
+        if (!config_module || !config_module->valid ()) {
+            std::cerr << "Can not load " << config_name << " Config module.\n";
+            ret = -1;
+            goto cleanup;
+        }
+    } else {
+        _config = new DummyConfig ();
+    }
+
+    /* Get current display. */
+    {
+        const char *p = getenv ("DISPLAY");
+        if (p)
+            display_name = String (p);
+    }
+
+    char buf [256];
+    snprintf (buf, sizeof (buf), "config_name=%s display_name=%s", config_name.c_str (), display_name.c_str ());
+    check_time (buf);
+    try {
+        if (!initialize_panel_agent (config_name, display_name, should_resident)) {
+            check_time ("Failed to initialize Panel Agent!");
+            std::cerr << "Failed to initialize Panel Agent!\n";
+            ret = -1;
+            goto cleanup;
+        }
+    } catch (scim::Exception & e) {
+        std::cerr << e.what() << "\n";
+        ret = -1;
+        goto cleanup;
+    }
+    check_time ("initialize_panel_agent");
+
+    /* Create config instance */
+    if (_config.null () && config_module && config_module->valid ())
+        _config = config_module->create_config ();
+    if (_config.null ()) {
+        std::cerr << "Failed to create Config instance from " << config_name << " Config module.\n";
+        ret = -1;
+        goto cleanup;
+    }
+    check_time ("create config instance");
+
+    /* Initialize global variables and pointers for candidate items and etc. */
+    for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; i++) {
+        _candidate_0 [i]     = NULL;
+        _candidate_items [i] = NULL;
+        _seperate_0 [i]      = NULL;
+        _seperate_items [i]  = NULL;
+        _line_0 [i]          = NULL;
+        _line_items [i]      = NULL;
+    }
+
+    try {
+        _panel_agent->send_display_name (display_name);
+    } catch (scim::Exception & e) {
+        std::cerr << e.what() << "\n";
+        ret = -1;
+        goto cleanup;
+    }
+
+    if (daemon) {
+        check_time ("ISF WSM EFL run as daemon");
+        scim_daemon ();
+    }
+
+    /* Connect the configuration reload signal. */
+    _config->signal_connect_reload (slot (config_reload_cb));
+
+    if (!check_wm_ready ()) {
+        std::cerr << "[ISF-PANEL-EFL] WM ready timeout\n";
+        LOGW ("Window Manager ready timeout\n");
+    } else {
+        LOGD ("Window Manager is in ready state\n");
+    }
+
+    elm_init (argc, argv);
+    check_time ("elm_init");
+
+    //elm_policy_set (ELM_POLICY_THROTTLE, ELM_POLICY_THROTTLE_NEVER);
+
+    if (!efl_create_control_window ()) {
+        LOGW ("Failed to create control window\n");
+        goto cleanup;
+    }
+
+    efl_get_screen_resolution (_screen_width, _screen_height);
+
+    _width_rate       = (float)(_screen_width / 720.0);
+    _height_rate      = (float)(_screen_height / 1280.0);
+    _blank_width      = (int)(_blank_width * _width_rate);
+    _item_min_width   = (int)(_item_min_width * _width_rate);
+    _item_min_height  = (int)(_item_min_height * _height_rate);
+    _candidate_width  = (int)(_candidate_port_width * _width_rate);
+    _candidate_height = (int)(_candidate_port_height_min * _height_rate);
+    _indicator_height = (int)(_indicator_height * _height_rate);
+
+    _aux_font_size       = (int)(_aux_font_size * _width_rate);
+    _candidate_font_size = (int)(_candidate_font_size * _width_rate);
+
+    /* Load ISF configuration */
+    load_config ();
+    check_time ("load_config");
+
+    helper_manager_handler   = ecore_main_fd_handler_add (_panel_agent->get_helper_manager_id (), ECORE_FD_READ, helper_manager_input_handler, NULL, NULL, NULL);
+    panel_agent_read_handler = ecore_main_fd_handler_add (_panel_agent->get_server_id (), ECORE_FD_READ, panel_agent_handler, NULL, NULL, NULL);
+    _read_handler_list.push_back (panel_agent_read_handler);
+    check_time ("run_panel_agent");
+
+    set_language_and_locale ();
+
+#if HAVE_VCONF
+    /* Add callback function for input language and display language */
+    vconf_notify_key_changed (VCONFKEY_LANGSET, display_language_changed_cb, NULL);
+#endif
+
+    try {
+        /* Update ISE list */
+        std::vector<String> list;
+        slot_get_ise_list (list);
+
+        /* Load initial ISE information */
+        _initial_ise_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_UUID), String (SCIM_COMPOSE_KEY_FACTORY_UUID));
+
+        /* Launches default soft keyboard when all conditions are satisfied */
+        launch_default_soft_keyboard ();
+    } catch (scim::Exception & e) {
+        std::cerr << e.what () << "\n";
+    }
+
+    // FIXME:
+
+    /* Set elementary scale */
+    if (_screen_width)
+        elm_config_scale_set (_screen_width / 720.0f);
+
+    signal (SIGQUIT, signalhandler);
+    signal (SIGTERM, signalhandler);
+    signal (SIGINT,  signalhandler);
+    signal (SIGHUP,  signalhandler);
+    signal (SIGABRT, signalhandler);
+
+    check_time ("EFL WSM launch time");
+
+    elm_run ();
+
+    _config->flush ();
+    ret = 0;
+
+    if (helper_manager_handler)
+        ecore_main_fd_handler_del (helper_manager_handler);
+    for (unsigned int ii = 0; ii < _read_handler_list.size (); ++ii) {
+        ecore_main_fd_handler_del (_read_handler_list[ii]);
+    }
+    _read_handler_list.clear ();
+
+#if HAVE_VCONF
+    /* Remove callback function for input language and display language */
+    vconf_ignore_key_changed (VCONFKEY_LANGSET, display_language_changed_cb);
+#endif
+
+cleanup:
+    ui_candidate_delete_check_size_timer ();
+    ui_candidate_delete_longpress_timer ();
+    ui_candidate_delete_destroy_timer ();
+    delete_ise_directory_em ();
+    ui_close_tts ();
+
+    if (!_config.null ())
+        _config.reset ();
+    if (config_module)
+        delete config_module;
+    if (_panel_agent) {
+        try {
+            _panel_agent->stop ();
+        } catch (scim::Exception & e) {
+            std::cerr << "Exception is thrown from _panel_agent->stop (), error is " << e.what () << "\n";
+        }
+        delete _panel_agent;
+    }
+
+    delete []new_argv;
+
+    if (ret == 0) {
+        std::cerr << "Successfully exited.\n";
+        return 0;
+    } else {
+        std::cerr << "Abnormally exited.\n";
+        return -1;
+    }
+}
+
+/*
+vi:ts=4:nowrap:expandtab
+*/
diff --git a/ism/extras/efl_wsm/isf_wsm_utility.cpp b/ism/extras/efl_wsm/isf_wsm_utility.cpp
new file mode 100644 (file)
index 0000000..b16dcb8
--- /dev/null
@@ -0,0 +1,639 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Yan Wang <yan.wang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define Uses_SCIM_CONFIG_PATH
+#define Uses_SCIM_PANEL_AGENT
+#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_HELPER_MODULE
+#define Uses_SCIM_COMPOSE_KEY
+
+
+#include <string.h>
+#include "scim.h"
+#include "scim_stl_map.h"
+#include "isf_wsm_utility.h"
+#include "isf_query_utility.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dlog.h>
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of macro.
+/////////////////////////////////////////////////////////////////////////////
+#ifdef LOG_TAG
+# undef LOG_TAG
+#endif
+#define LOG_TAG                                         "ISF_WSM_EFL"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of global variables.
+/////////////////////////////////////////////////////////////////////////////
+MapStringVectorSizeT         _groups;
+std::vector<String>          _uuids;
+std::vector<String>          _names;
+std::vector<String>          _module_names;
+std::vector<String>          _langs;
+std::vector<String>          _icons;
+std::vector<uint32>          _options;
+std::vector<TOOLBAR_MODE_T>  _modes;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of internal variables.
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of internal functions.
+/////////////////////////////////////////////////////////////////////////////
+static bool add_keyboard_ise_module (const String ise_name, const ConfigPointer &config);
+static bool add_helper_ise_module   (const String ise_name);
+
+
+/**
+ * @brief Get all ISEs support languages.
+ *
+ * @param all_langs The list to store all languages.
+ */
+void isf_get_all_languages (std::vector<String> &all_langs)
+{
+    String lang_name;
+
+    for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) {
+        lang_name = scim_get_language_name_english (it->first);
+        all_langs.push_back (lang_name);
+    }
+}
+
+/**
+ * @brief Get all ISEs for the specific languages.
+ *
+ * @param lang_list The specific languages list.
+ * @param uuid_list The list to store ISEs' UUID.
+ * @param name_list The list to store ISEs' name.
+ */
+void isf_get_all_ises_in_languages (std::vector<String> lang_list, std::vector<String> &uuid_list, std::vector<String> &name_list)
+{
+    String lang_name;
+
+    for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) {
+        lang_name = scim_get_language_name_english (it->first);
+        if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) {
+            for (size_t i = 0; i < it->second.size (); i++) {
+                // Avoid to add the same ISE
+                if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) {
+                    uuid_list.push_back (_uuids[it->second[i]]);
+                    name_list.push_back (_names[it->second[i]]);
+                }
+            }
+        }
+    }
+}
+
+/**
+ * @brief Get keyboard ISE
+ *
+ * @param config The config pointer for loading keyboard ISE.
+ * @param ise_uuid The keyboard ISE uuid.
+ * @param ise_name The keyboard ISE name.
+ * @param ise_option The keyboard ISE option.
+ */
+void isf_get_keyboard_ise (const ConfigPointer &config, String &ise_uuid, String &ise_name, uint32 &ise_option)
+{
+    String uuid = config->read (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + String ("~other"), String (""));
+    if (ise_uuid.length () > 0)
+        uuid = ise_uuid;
+    for (unsigned int i = 0; i < _uuids.size (); i++) {
+        if (uuid == _uuids[i]) {
+            ise_uuid   = _uuids[i];
+            ise_name   = _names[i];
+            ise_option = _options[i];
+            return;
+        }
+    }
+    ise_name = String ("");
+    ise_uuid = String ("");
+}
+
+/**
+ * @brief Get all keyboard ISEs for the specific languages.
+ *
+ * @param lang_list The specific languages list.
+ * @param uuid_list The list to store keyboard ISEs' UUID.
+ * @param name_list The list to store keyboard ISEs' name.
+ * @param bCheckOption The flag to check whether support hardware keyboard.
+ */
+void isf_get_keyboard_ises_in_languages (const std::vector<String> &lang_list,
+                                         std::vector<String>       &uuid_list,
+                                         std::vector<String>       &name_list,
+                                         bool                       bCheckOption)
+{
+    String lang_name;
+
+    for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) {
+        lang_name = scim_get_language_name_english (it->first);
+
+        if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) {
+            for (size_t i = 0; i < it->second.size (); i++) {
+                if (_modes[it->second[i]] != TOOLBAR_KEYBOARD_MODE)
+                    continue;
+                if (bCheckOption && (_options[it->second[i]] & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD))
+                    continue;
+                if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) {
+                    uuid_list.push_back (_uuids[it->second[i]]);
+                    name_list.push_back (_names[it->second[i]]);
+                }
+            }
+        }
+    }
+}
+
+/**
+ * @brief Get all helper ISEs for the specific languages.
+ *
+ * @param lang_list The specific languages list.
+ * @param uuid_list The list to store helper ISEs' UUID.
+ * @param name_list The list to store helper ISEs' name.
+ */
+void isf_get_helper_ises_in_languages (const std::vector<String> &lang_list, std::vector<String> &uuid_list, std::vector<String> &name_list)
+{
+    String lang_name;
+
+    for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) {
+        lang_name = scim_get_language_name_english (it->first);
+        if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) {
+            for (size_t i = 0; i < it->second.size (); i++) {
+
+                if (_modes[it->second[i]]!= TOOLBAR_HELPER_MODE)
+                    continue;
+                // Avoid to add the same ISE
+                if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) {
+                    uuid_list.push_back (_uuids[it->second[i]]);
+                    name_list.push_back (_names[it->second[i]]);
+                }
+            }
+        }
+    }
+}
+
+/**
+ * @brief Save all ISEs information into cache file.
+ *
+ * @return void
+ */
+void isf_save_ise_information (void)
+{
+    if (_module_names.size () <= 0)
+        return;
+
+    std::vector<ISEINFO> info_list;
+    for (size_t i = 0; i < _module_names.size (); ++i) {
+        if (_module_names[i] == COMPOSE_KEY_MODULE)
+            continue;
+        ISEINFO info;
+        info.name     = _names[i];
+        info.uuid     = _uuids[i];
+        info.module   = _module_names[i];
+        info.language = _langs[i];
+        info.icon     = _icons[i];
+        info.mode     = _modes[i];
+        info.option   = _options[i];
+        info.locales  = "";
+        info_list.push_back (info);
+    }
+
+    String user_file_name = String (USER_ENGINE_FILE_NAME);
+    isf_write_ise_info_list (user_file_name.c_str (), info_list);
+}
+
+/**
+ * @brief Load all ISEs to initialize.
+ *
+ * @param type The loading ISE type.
+ * @param config The config pointer for loading keyboard ISE.
+ * @param uuids The ISE uuid list.
+ * @param names The ISE name list.
+ * @param module_names The ISE module name list.
+ * @param langs The ISE language list.
+ * @param icons The ISE icon list.
+ * @param modes The ISE type list.
+ * @param options The ISE option list.
+ */
+void isf_get_factory_list (LOAD_ISE_TYPE  type,
+                           const ConfigPointer &config,
+                           std::vector<String> &uuids,
+                           std::vector<String> &names,
+                           std::vector<String> &module_names,
+                           std::vector<String> &langs,
+                           std::vector<String> &icons,
+                           std::vector<TOOLBAR_MODE_T> &modes,
+                           std::vector<uint32> &options)
+{
+    uuids.clear ();
+    names.clear ();
+    module_names.clear ();
+    langs.clear ();
+    icons.clear ();
+    modes.clear ();
+    options.clear ();
+    _groups.clear ();
+
+    if (type != HELPER_ONLY) {
+        /* Add ComposeKeyFactory first. */
+        IMEngineFactoryPointer factory = new ComposeKeyFactory ();
+        uuids.push_back (factory->get_uuid ());
+        names.push_back (utf8_wcstombs (factory->get_name ()));
+        module_names.push_back (COMPOSE_KEY_MODULE);
+        langs.push_back (isf_get_normalized_language (factory->get_language ()));
+        icons.push_back (factory->get_icon_file ());
+        modes.push_back (TOOLBAR_KEYBOARD_MODE);
+        options.push_back (factory->get_option ());
+        factory.reset ();
+    }
+
+    String user_file_name = String (USER_ENGINE_FILE_NAME);
+    FILE *engine_list_file = fopen (user_file_name.c_str (), "r");
+    if (engine_list_file == NULL) {
+        std::cerr << __func__ << " Failed to open(" << user_file_name << ")\n";
+        return;
+    }
+
+    char buf[MAXLINE];
+    while (fgets (buf, MAXLINE, engine_list_file) != NULL) {
+        ISEINFO info;
+        isf_get_ise_info_from_string (buf, info);
+        if (info.mode == TOOLBAR_HELPER_MODE || type != HELPER_ONLY) {
+            names.push_back (info.name);
+            uuids.push_back (info.uuid);
+            module_names.push_back (info.module);
+            langs.push_back (info.language);
+            icons.push_back (info.icon);
+            modes.push_back (info.mode);
+            options.push_back (info.option);
+        }
+    }
+
+    fclose (engine_list_file);
+}
+
+/**
+ * @brief Load all ISEs information and ISF default languages.
+ *
+ * @param type The load ISE type.
+ * @param config The config pointer for loading keyboard ISE.
+ */
+void isf_load_ise_information (LOAD_ISE_TYPE type, const ConfigPointer &config)
+{
+    /* Load ISE engine info */
+    isf_get_factory_list (type, config, _uuids, _names, _module_names, _langs, _icons, _modes, _options);
+
+    /* Update _groups */
+    std::vector<String> ise_langs;
+    for (size_t i = 0; i < _uuids.size (); ++i) {
+        scim_split_string_list (ise_langs, _langs[i]);
+        for (size_t j = 0; j < ise_langs.size (); j++) {
+            if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ())
+                _groups[ise_langs[j]].push_back (i);
+        }
+        ise_langs.clear ();
+    }
+}
+
+/**
+ * @brief Load one keyboard ISE module.
+ *
+ * @param module_name The keboard ISE module name.
+ * @param config The config pointer for loading keyboard ISE.
+ *
+ * @return true if load module is successful, otherwise return false.
+ */
+static bool add_keyboard_ise_module (const String module_name, const ConfigPointer &config)
+{
+    if (module_name.length () <= 0 || module_name == "socket")
+        return false;
+
+    IMEngineFactoryPointer factory;
+    IMEngineModule         ime_module;
+
+    String filename = String (USER_ENGINE_FILE_NAME);
+    FILE *engine_list_file = fopen (filename.c_str (), "a");
+    if (engine_list_file == NULL) {
+        LOGD ("Failed to open %s!!!\n", filename.c_str ());
+        return false;
+    }
+
+    ime_module.load (module_name, config);
+    if (ime_module.valid ()) {
+        for (size_t j = 0; j < ime_module.number_of_factories (); ++j) {
+            try {
+                factory = ime_module.create_factory (j);
+            } catch (...) {
+                factory.reset ();
+            }
+
+            if (!factory.null ()) {
+                if (std::find (_uuids.begin (), _uuids.end (), factory->get_uuid ()) == _uuids.end ()) {
+                    String uuid = factory->get_uuid ();
+                    String name = utf8_wcstombs (factory->get_name ());
+                    String language = isf_get_normalized_language (factory->get_language ());
+                    String icon = factory->get_icon_file ();
+                    char mode[12];
+                    char option[12];
+
+                    _uuids.push_back (uuid);
+                    _names.push_back (name);
+                    _module_names.push_back (module_name);
+                    _langs.push_back (language);
+                    _icons.push_back (icon);
+                    _modes.push_back (TOOLBAR_KEYBOARD_MODE);
+                    _options.push_back (factory->get_option ());
+
+                    snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_KEYBOARD_MODE);
+                    snprintf (option, sizeof (option), "%d", factory->get_option ());
+
+                    String line = isf_combine_ise_info_string (name, uuid, module_name, language,
+                                                               icon, String (mode), String (option), factory->get_locales ());
+                    if (fputs (line.c_str (), engine_list_file) < 0) {
+                        LOGD ("Failed to write (%s)!!!\n", line.c_str ());
+                        break;
+                    }
+                }
+                factory.reset ();
+            }
+        }
+        ime_module.unload ();
+    } else {
+        LOGD ("Failed to load (%s)!!!", module_name.c_str ());
+        fclose (engine_list_file);
+        return false;
+    }
+
+    int ret = fclose (engine_list_file);
+    if (ret != 0)
+        LOGD ("Failed to fclose %s!!!\n", filename.c_str ());
+
+    return true;
+}
+
+/**
+ * @brief Load one helper ISE module.
+ *
+ * @param module_name The helper ISE module name.
+ *
+ * @return true if load module is successful, otherwise return false.
+ */
+static bool add_helper_ise_module (const String module_name)
+{
+    if (module_name.length () <= 0)
+        return false;
+
+    HelperModule helper_module;
+    HelperInfo   helper_info;
+
+    String filename = String (USER_ENGINE_FILE_NAME);
+    FILE *engine_list_file = fopen (filename.c_str (), "a");
+    if (engine_list_file == NULL) {
+        LOGD ("Failed to open %s!!!\n", filename.c_str ());
+        return false;
+    }
+
+    helper_module.load (module_name);
+    if (helper_module.valid ()) {
+        for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) {
+            helper_module.get_helper_info (j, helper_info);
+            _uuids.push_back (helper_info.uuid);
+            _names.push_back (helper_info.name);
+            _langs.push_back (isf_get_normalized_language (helper_module.get_helper_lang (j)));
+            _module_names.push_back (module_name);
+            _icons.push_back (helper_info.icon);
+            _modes.push_back (TOOLBAR_HELPER_MODE);
+            _options.push_back (helper_info.option);
+
+            char mode[12];
+            char option[12];
+            snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_HELPER_MODE);
+            snprintf (option, sizeof (option), "%d", helper_info.option);
+
+            String line = isf_combine_ise_info_string (helper_info.name, helper_info.uuid, module_name, isf_get_normalized_language (helper_module.get_helper_lang (j)),
+                                                       helper_info.icon, String (mode), String (option), String (""));
+            if (fputs (line.c_str (), engine_list_file) < 0) {
+                 LOGD ("Failed to write (%s)!!!\n", line.c_str ());
+                 break;
+            }
+        }
+        helper_module.unload ();
+    } else {
+        LOGD ("Failed to load (%s)!!!", module_name.c_str ());
+        fclose (engine_list_file);
+        return false;
+    }
+
+    int ret = fclose (engine_list_file);
+    if (ret != 0)
+        LOGD ("Failed to fclose %s!!!\n", filename.c_str ());
+
+    return true;
+}
+
+/**
+ * @brief Update ISEs information for ISE is added or removed.
+ *
+ * @param type The load ISE type.
+ * @param config The config pointer for loading keyboard ISE.
+ *
+ * @return true if ISEs list is changed, otherwise return false.
+ */
+bool isf_update_ise_list (LOAD_ISE_TYPE type, const ConfigPointer &config)
+{
+    bool ret = false;
+
+    std::vector<String> helper_list;
+    scim_get_helper_module_list (helper_list);
+
+    std::vector<String> install_modules, uninstall_modules;
+
+    /* Check keyboard ISEs */
+    if (type != HELPER_ONLY) {
+        install_modules.push_back (COMPOSE_KEY_MODULE);
+        std::vector<String> imengine_list;
+        scim_get_imengine_module_list (imengine_list);
+        for (size_t i = 0; i < imengine_list.size (); ++i) {
+            install_modules.push_back (imengine_list [i]);
+            if (std::find (_module_names.begin (), _module_names.end (), imengine_list [i]) == _module_names.end ()) {
+                if (add_keyboard_ise_module (imengine_list [i], config))
+                    ret = true;
+            }
+        }
+    }
+
+    /* Check helper ISEs */
+    for (size_t i = 0; i < helper_list.size (); ++i) {
+        install_modules.push_back (helper_list [i]);
+        if (std::find (_module_names.begin (), _module_names.end (), helper_list [i]) == _module_names.end ()) {
+            if (add_helper_ise_module (helper_list [i]))
+                ret = true;
+        }
+    }
+
+    /* Try to find uninstall ISEs */
+    bool bFindUninstall = false;
+    for (size_t i = 0; i < _module_names.size (); ++i) {
+        if (std::find (install_modules.begin (), install_modules.end (), _module_names [i]) == install_modules.end ()) {
+            ret = true;
+            bFindUninstall = true;
+            /* Avoid to add the same module */
+            if (std::find (uninstall_modules.begin (), uninstall_modules.end (), _module_names [i]) == uninstall_modules.end ()) {
+                uninstall_modules.push_back (_module_names [i]);
+                String filename = String (USER_ENGINE_FILE_NAME);
+                if (isf_remove_ise_info_from_file (filename.c_str (), _module_names [i].c_str ()) == false)
+                    LOGD ("Failed to remove %s from cache file : %s!!!", _module_names [i].c_str (), filename.c_str ());
+            }
+        }
+    }
+    if (bFindUninstall) {
+        std::vector<String>          tmp_uuids        = _uuids;
+        std::vector<String>          tmp_names        = _names;
+        std::vector<String>          tmp_module_names = _module_names;
+        std::vector<String>          tmp_langs        = _langs;
+        std::vector<String>          tmp_icons        = _icons;
+        std::vector<uint32>          tmp_options      = _options;
+        std::vector<TOOLBAR_MODE_T>  tmp_modes        = _modes;
+
+        _uuids.clear ();
+        _names.clear ();
+        _module_names.clear ();
+        _langs.clear ();
+        _icons.clear ();
+        _options.clear ();
+        _modes.clear ();
+        _groups.clear ();
+
+        for (size_t i = 0; i < tmp_module_names.size (); ++i) {
+            if (std::find (uninstall_modules.begin (), uninstall_modules.end (), tmp_module_names [i]) == uninstall_modules.end ()) {
+                _uuids.push_back (tmp_uuids [i]);
+                _names.push_back (tmp_names [i]);
+                _module_names.push_back (tmp_module_names [i]);
+                _langs.push_back (tmp_langs [i]);
+                _icons.push_back (tmp_icons [i]);
+                _options.push_back (tmp_options [i]);
+                _modes.push_back (tmp_modes [i]);
+            }
+        }
+    }
+
+    /* Update _groups */
+    if (ret) {
+        std::vector<String> ise_langs;
+        for (size_t i = 0; i < _uuids.size (); ++i) {
+            scim_split_string_list (ise_langs, _langs[i]);
+            for (size_t j = 0; j < ise_langs.size (); j++) {
+                if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ())
+                    _groups[ise_langs[j]].push_back (i);
+            }
+            ise_langs.clear ();
+        }
+    }
+
+    return ret;
+}
+
+bool isf_remove_ise_module (const String module_name, const ConfigPointer &config)
+{
+    if (std::find (_module_names.begin (), _module_names.end (), module_name) == _module_names.end ()) {
+        LOGD ("Cannot to find %s!!!", module_name.c_str ());
+        return true;
+    }
+
+    String filename = String (USER_ENGINE_FILE_NAME);
+    if (isf_remove_ise_info_from_file (filename.c_str (), module_name.c_str ())) {
+        isf_get_factory_list (ALL_ISE, config, _uuids, _names, _module_names, _langs, _icons, _modes, _options);
+
+        /* Update _groups */
+        _groups.clear ();
+        std::vector<String> ise_langs;
+        for (size_t i = 0; i < _uuids.size (); ++i) {
+            scim_split_string_list (ise_langs, _langs[i]);
+            for (size_t j = 0; j < ise_langs.size (); j++) {
+                if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ())
+                    _groups[ise_langs[j]].push_back (i);
+            }
+            ise_langs.clear ();
+        }
+        return true;
+    } else {
+        LOGD ("Failed to remove %s from cache file : %s!!!", module_name.c_str (), filename.c_str ());
+        return false;
+    }
+}
+
+bool isf_update_ise_module (const String strModulePath, const ConfigPointer &config)
+{
+    bool ret = false;
+    struct stat filestat;
+    stat (strModulePath.c_str (), &filestat);
+    if (!S_ISDIR (filestat.st_mode)) {
+        int begin = strModulePath.find_last_of (SCIM_PATH_DELIM) + 1;
+        String mod_name = strModulePath.substr (begin, strModulePath.find_last_of ('.') - begin);
+        String path     = strModulePath.substr (0, strModulePath.find_last_of (SCIM_PATH_DELIM));
+        LOGD ("module_name = %s, path = %s", mod_name.c_str (), path.c_str ());
+
+        if (mod_name.length () > 0 && path.length () > 1) {
+            if (isf_remove_ise_module (mod_name, config)) {
+                String type = path.substr (path.find_last_of (SCIM_PATH_DELIM) + 1);
+                LOGD ("type = %s", type.c_str ());
+                if (type == String ("Helper")) {
+                    if (add_helper_ise_module (mod_name))
+                        ret = true;
+                } else if (type == String ("IMEngine")) {
+                    if (add_keyboard_ise_module (mod_name, config))
+                        ret = true;
+                }
+            }
+        } else {
+            LOGD ("%s is not valid so file!!!", strModulePath.c_str ());
+        }
+    }
+
+    /* Update _groups */
+    if (ret) {
+        _groups.clear ();
+        std::vector<String> ise_langs;
+        for (size_t i = 0; i < _uuids.size (); ++i) {
+            scim_split_string_list (ise_langs, _langs[i]);
+            for (size_t j = 0; j < ise_langs.size (); j++) {
+                if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ())
+                    _groups[ise_langs[j]].push_back (i);
+            }
+            ise_langs.clear ();
+        }
+    }
+
+    return ret;
+}
+
+/*
+vi:ts=4:nowrap:ai:expandtab
+*/
diff --git a/ism/extras/efl_wsm/isf_wsm_utility.h b/ism/extras/efl_wsm/isf_wsm_utility.h
new file mode 100644 (file)
index 0000000..ba2d660
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * ISF(Input Service Framework)
+ *
+ * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Yan Wang <yan.wang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __ISF_WSM_UTILITY_H
+#define __ISF_WSM_UTILITY_H
+
+using namespace scim;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Declaration of macro.
+/////////////////////////////////////////////////////////////////////////////
+#define COMPOSE_KEY_MODULE                         "COMPOSE_KEY_MODULE"
+
+
+#if SCIM_USE_STL_EXT_HASH_MAP
+typedef __gnu_cxx::hash_map <String, std::vector <size_t>, scim_hash_string>        MapStringVectorSizeT;
+typedef std::map <String, std::vector <String> >                                    MapStringVectorString;
+typedef std::map <String ,String>                                                   MapStringString;
+#elif SCIM_USE_STL_HASH_MAP
+typedef std::hash_map <String, std::vector <size_t>, scim_hash_string>              MapStringVectorSizeT;
+typedef std::map <String, std::vector <String> >                                    MapStringVectorString;
+typedef std::map <String ,String>                                                   MapStringString;
+#else
+typedef std::map <String, std::vector <size_t> >                                    MapStringVectorSizeT;
+typedef std::map <String, std::vector <String> >                                    MapStringVectorString;
+typedef std::map <String ,String>                                                   MapStringString;
+#endif
+
+typedef enum {
+    ALL_ISE = 0,
+    HELPER_ONLY,
+    TYPE_END
+} LOAD_ISE_TYPE;
+
+void isf_get_all_languages (std::vector<String> &all_langs);
+void isf_get_all_ises_in_languages (std::vector<String> lang_list, std::vector<String> &uuid_list, std::vector<String> &name_list);
+
+void isf_get_keyboard_ise (const ConfigPointer &config, String &ise_uuid, String &ise_name, uint32 &ise_option);
+void isf_get_keyboard_ises_in_languages (const std::vector<String> &lang_list, std::vector<String> &uuid_list, std::vector<String> &name_list, bool bCheckOption = true);
+void isf_get_helper_ises_in_languages (const std::vector<String> &lang_list, std::vector<String> &uuid_list, std::vector<String> &name_list);
+
+void isf_save_ise_information (void);
+void isf_load_ise_information (LOAD_ISE_TYPE type, const ConfigPointer &config);
+bool isf_update_ise_list (LOAD_ISE_TYPE type, const ConfigPointer &config);
+bool isf_update_ise_module (const String strModulePath, const ConfigPointer &config);
+
+#endif /* __ISF_WSM_UTILITY_H */
+
+/*
+vi:ts=4:ai:nowrap:expandtab
+*/
index 6b56699..558dc8d 100644 (file)
@@ -155,6 +155,10 @@ libscim@SCIM_EPOCH@_la_LDFLAGS  = -version-info $(SCIM_CURRENT):$(SCIM_REVISION)
                          @EFL_LIBS@ \
                          -lstdc++ \
               -ltzplatform-config-1.0
+if HAVE_X
+libscim@SCIM_EPOCH@_la_CXXFLAGS += @ECOREX_CFLAGS@
+libscim@SCIM_EPOCH@_la_LDFLAGS  += @ECOREX_LIBS@
+endif
 
 libscim@SCIM_EPOCH@_la_LIBADD  = libltdlc.la
 
@@ -166,6 +170,11 @@ scim_CXXFLAGS              = @EFL_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ @VCONF_CFLAGS@
 scim_LDADD             = libscim@SCIM_EPOCH@.la
 scim_LDFLAGS           = @LTLIBINTL@ @EFL_LIBS@ @PRIVILEGE_CONTROL_LIBS@ @VCONF_LIBS@
 
+if HAVE_X
+scim_CXXFLAGS += @ECOREX_CFLAGS@
+scim_LDFLAGS  += @ECOREX_LIBS@
+endif
+
 isf_log_SOURCES                = isf_log.cpp
 isf_log_LDADD          = libscim@SCIM_EPOCH@.la
 if SCIM_BUILD_GTK_UTILS
@@ -193,5 +202,10 @@ scim_helper_launcher_CXXFLAGS      = @PRIVILEGE_CONTROL_CFLAGS@ @AIL_CFLAGS@ @EFL_CFL
 scim_helper_launcher_LDADD     = libscim@SCIM_EPOCH@.la
 scim_helper_launcher_LDFLAGS   = @LTLIBINTL@ @PRIVILEGE_CONTROL_LIBS@ @AIL_LIBS@ @EFL_LIBS@
 
+if HAVE_X
+scim_helper_launcher_CXXFLAGS += @ECOREX_CFLAGS@
+scim_helper_launcher_LDFLAGS  += @ECOREX_LIBS@
+endif
+
 
 
index b56f7e2..7d3febd 100644 (file)
 #define __ISE_CONTEXT_H
 
 #include <Ecore_IMF.h>
+#ifndef WAYLAND
 #include <Ecore_X.h>
+#endif
 
 typedef struct {
     Ecore_IMF_Input_Panel_Lang language;
     Ecore_IMF_Input_Panel_Layout layout;
     Ecore_IMF_Input_Panel_Return_Key_Type return_key_type;
+#ifndef WAYLAND
     Ecore_X_Window client_window;
+#endif
     int imdata_size;
     int cursor_pos;
     Eina_Bool return_key_disabled;
index 50323a6..39375a2 100644 (file)
@@ -291,7 +291,11 @@ static void __set_oom ()
 
 static inline int __set_dac ()
 {
+#ifdef WAYLAND
+    return 0;
+#else
     return perm_app_set_privilege("isf", NULL, NULL);
+#endif
 }
 
 static inline int __set_smack (char* path)
index 6a0703e..a647437 100644 (file)
@@ -126,6 +126,7 @@ static bool check_wm_ready (void)
 {
     SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n";
 
+#ifndef WAYLAND 
 #ifdef WAIT_WM
     int try_count = 0;
     while (check_file (ISF_SYSTEM_WM_READY_FILE) == false) {
@@ -133,6 +134,7 @@ static bool check_wm_ready (void)
         usleep (ISF_SYSTEM_WAIT_DELAY);
     }
 #endif
+#endif
 
     return true;
 }
index 7425eb3..dd11aab 100644 (file)
@@ -72,7 +72,11 @@ namespace scim {
 #define SCIM_GLOBAL_CONFIG_DISABLED_IMENGINE_FACTORIES              "/DisabledIMEngineFactories"
 #define SCIM_GLOBAL_CONFIG_SUPPORTED_UNICODE_LOCALES                "/SupportedUnicodeLocales"
 #define SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT                  "/DefaultKeyboardLayout"
+#ifdef WAYLAND
+#define SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM                    "/DefaultPanelProgram2"
+#else
 #define SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM                    "/DefaultPanelProgram"
+#endif
 #define SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE                    "/DefaultConfigModule"
 #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_FRONTEND_ADDRESS          "/DefaultSocketFrontEndAddress"
 #define SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_IMENGINE_ADDRESS          "/DefaultSocketIMEngineAddress"
index f8638e6..60066b5 100644 (file)
@@ -1,3 +1,4 @@
+%bcond_with wayland
 Name:       isf
 Summary:    Input Service Framework
 Version:    2.4.7424
@@ -15,15 +16,20 @@ BuildRequires:  gettext-tools
 BuildRequires:  pkgconfig(appcore-efl)
 BuildRequires:  pkgconfig(libprivilege-control)
 BuildRequires:  pkgconfig(elementary)
-BuildRequires:  pkgconfig(utilX)
 BuildRequires:  pkgconfig(vconf)
+%if %{with wayland}
+BuildRequires:  pkgconfig(ecore-wayland)
+BuildRequires:  pkgconfig(xkbcommon) >= 0.3.0
+%else
+BuildRequires:  pkgconfig(utilX)
 %if "%{_repository}" != "wearable"
 BuildRequires:  pkgconfig(ui-gadget-1)
 BuildRequires:  pkgconfig(minicontrol-provider)
 %endif
+BuildRequires:  pkgconfig(x11)
+%endif
 BuildRequires:  pkgconfig(ecore)
 BuildRequires:  pkgconfig(edje)
-BuildRequires:  pkgconfig(x11)
 BuildRequires:  pkgconfig(notification)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(tts)
@@ -67,14 +73,37 @@ CFLAGS+=" -D_MOBILE";
 CXXFLAGS+=" -D_MOBILE";
 %endif
 
+%if %{with wayland}
+CFLAGS+=" -DWAYLAND"
+CXXFLAGS+=" -DWAYLAND"
+%endif
+
 export GC_SECTIONS_FLAGS="-fdata-sections -ffunction-sections -Wl,--gc-sections"
+
+CFLAGS+=" -I/usr/include/elementary-1 -I/usr/include/eina-1 -I/usr/include/eina-1/eina -I/usr/include/ecore-1 "
+CFLAGS+=" -I/usr/include/evas-1 -I/usr/include/eet-1 -I/usr/include/edje-1 -I/usr/include/e_dbus-1 "
+CFLAGS+=" -I/usr/include/eio-1 -I/usr/include/ethumb-1 -I/usr/include/efreet-1 -I/usr/include/emotion-1 -I/usr/include/embryo-1 "
+CFLAGS+=" -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include/ "
 CFLAGS+=" -fvisibility=hidden ${GC_SECTIONS_FLAGS} "; export CFLAGS
+
+CXXFLAGS+=" -I/usr/include/elementary-1 -I/usr/include/eina-1 -I/usr/include/eina-1/eina -I/usr/include/ecore-1 "
+CXXFLAGS+=" -I/usr/include/evas-1 -I/usr/include/eet-1 -I/usr/include/edje-1 -I/usr/include/e_dbus-1 "
+CXXFLAGS+=" -I/usr/include/eio-1 -I/usr/include/ethumb-1 -I/usr/include/efreet-1 -I/usr/include/emotion-1 -I/usr/include/embryo-1 "
+CXXFLAGS+=" -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include/ "
 CXXFLAGS+=" -fvisibility=hidden -fvisibility-inlines-hidden ${GC_SECTIONS_FLAGS} ";export CXXFLAGS
 
 %autogen
 %configure --disable-static \
                --disable-tray-icon \
                --disable-filter-sctc \
+%if %{with wayland}
+        --disable-panel-efl \
+        --disable-setting-efl \
+        --disable-efl-immodule \
+%else
+        --disable-wsm-efl \
+        --disable-wsc-efl \
+%endif
                --disable-frontend-x11
 make %{?_smp_mflags}
 
@@ -87,12 +116,15 @@ mkdir -p %{buildroot}/opt/apps/scim/lib/scim-1.0/1.4.0/Helper
 mkdir -p %{buildroot}/opt/apps/scim/lib/scim-1.0/1.4.0/SetupUI
 mkdir -p %{buildroot}/opt/apps/scim/lib/scim-1.0/1.4.0/IMEngine
 
+%if %{with wayland}
+%else
 %if "%{_repository}" != "wearable"
 install -d %{buildroot}%{_libdir}/systemd/system/graphical.target.wants
 install -d %{buildroot}%{_libdir}/systemd/system
 install -m0644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/
 ln -sf ../../system/scim.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/scim.service
 %endif
+%endif
 
 %find_lang scim
 
@@ -115,7 +147,7 @@ cat scim.lang > isf.lang
 %dir /opt/apps/scim/lib/scim-1.0/1.4.0/Helper
 %dir /opt/apps/scim/lib/scim-1.0/1.4.0/SetupUI
 %dir /opt/apps/scim/lib/scim-1.0/1.4.0/IMEngine
-%if "%{_repository}" == "wearable"
+%if "%{_repository}" == "wearable" || %{with wayland}
 %dir /etc/scim/conf
 %{_libdir}/systemd/user/core-efl.target.wants/scim.service
 %{_libdir}/systemd/user/scim.service
@@ -128,12 +160,17 @@ cat scim.lang > isf.lang
 %{_sysconfdir}/scim/config
 %{_datadir}/scim/isf_candidate_theme1.edj
 %{_datadir}/scim/icons/*
+%if %{with wayland}
+%{_bindir}/isf-wsm-efl
+%{_bindir}/isf-wsc-efl
+%else
 %{_bindir}/isf-demo-efl
+%{_bindir}/isf-panel-efl
+%{_libdir}/*/immodules/*.so
+%endif
 %{_bindir}/scim
 %{_bindir}/isf-log
-%{_bindir}/isf-panel-efl
 %{_bindir}/isf-query-engines
-%{_libdir}/*/immodules/*.so
 %{_libdir}/scim-1.0/1.4.0/IMEngine/socket.so
 %{_libdir}/scim-1.0/1.4.0/Config/simple.so
 %{_libdir}/scim-1.0/1.4.0/Config/socket.so