--- /dev/null
+From c53f2040e8257b726c87c22c4a747457b6d2cea6 Mon Sep 17 00:00:00 2001
+From: Rusty Lynch <rusty.lynch@intel.com>
+Date: Wed, 22 May 2013 09:57:50 -0700
+Subject: [PATCH] Add wm_rotation infrastructure support
+
+This adds the underlying infrastructure for ecore_evas_wm_rotation
+support with the backend implementation for all backends nulled out.
+---
+ src/lib/ecore_evas/Ecore_Evas.h | 7 +++
+ src/lib/ecore_evas/ecore_evas.c | 91 +++++++++++++++++++++++++++++
+ src/lib/ecore_evas/ecore_evas_buffer.c | 6 +-
+ src/lib/ecore_evas/ecore_evas_cocoa.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_directfb.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_ews.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_extn.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_fb.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_private.h | 21 +++++++
+ src/lib/ecore_evas/ecore_evas_psl1ght.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_sdl.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_wayland_egl.c | 4 +-
+ src/lib/ecore_evas/ecore_evas_wayland_shm.c | 4 +-
+ src/lib/ecore_evas/ecore_evas_win32.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_wince.c | 5 +-
+ src/lib/ecore_evas/ecore_evas_x.c | 4 +-
+ 16 files changed, 169 insertions(+), 13 deletions(-)
+
+diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h
+index db42d1d..c2eec61 100644
+--- a/src/lib/ecore_evas/Ecore_Evas.h
++++ b/src/lib/ecore_evas/Ecore_Evas.h
+@@ -681,6 +681,13 @@ EAPI void ecore_evas_profiles_set(Ecore_Evas *ee, const char **profiles,
+ * @since 1.7.0
+ */
+ EAPI const char *ecore_evas_profile_get(const Ecore_Evas *ee);
++
++EAPI Eina_Bool ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee);
++EAPI void ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation);
++EAPI int ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee);
++EAPI void ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count);
++EAPI Eina_Bool ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count);
++
+ /**
+ * @brief Move an Ecore_Evas.
+ *
+diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c
+index e480c86..203c6f1 100644
+--- a/src/lib/ecore_evas/ecore_evas.c
++++ b/src/lib/ecore_evas/ecore_evas.c
+@@ -1960,6 +1960,97 @@ ecore_evas_profile_get(const Ecore_Evas *ee)
+ return ee->prop.profile;
+ }
+
++EAPI Eina_Bool
++ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee)
++{
++ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
++ {
++ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
++ "ecore_evas_wm_rotation_supported_get");
++ return EINA_FALSE;
++ }
++ return ee->prop.wm_rot.supported;
++}
++
++EAPI void
++ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation)
++{
++ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
++ {
++ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
++ "ecore_evas_wm_rotation_preferred_rotation_set");
++ return;
++ }
++ if (rotation != -1)
++ {
++ if (ee->prop.wm_rot.available_rots)
++ {
++ Eina_Bool found = EINA_FALSE;
++ unsigned int i;
++ for (i = 0; i < ee->prop.wm_rot.count; i++)
++ {
++ if (ee->prop.wm_rot.available_rots[i] == rotation)
++ {
++ found = EINA_TRUE;
++ break;
++ }
++ }
++ if (!found) return;
++ }
++ }
++ IFC(ee, fn_wm_rot_preferred_rotation_set) (ee, rotation);
++ IFE;
++}
++
++EAPI int
++ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee)
++{
++ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
++ {
++ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
++ "ecore_evas_wm_rotation_preferred_rotation_get");
++ return 0;
++ }
++ return ee->prop.wm_rot.rot;
++}
++
++EAPI void
++ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count)
++{
++ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
++ {
++ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
++ "ecore_evas_wm_rotation_available_rotations_set");
++ return;
++ }
++ IFC(ee, fn_wm_rot_available_rotations_set) (ee, rotations, count);
++ IFE;
++}
++
++EAPI Eina_Bool
++ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count)
++{
++ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
++ {
++ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
++ "ecore_evas_wm_rotation_available_rotations_get");
++ return EINA_FALSE;
++ }
++ if ((!rotations) || (!count))
++ return EINA_FALSE;
++
++ if ((!ee->prop.wm_rot.available_rots) || (ee->prop.wm_rot.count == 0))
++ return EINA_FALSE;
++
++ *rotations = calloc(ee->prop.wm_rot.count, sizeof(int));
++ if (!*rotations) return EINA_FALSE;
++
++ memcpy(*rotations, ee->prop.wm_rot.available_rots, sizeof(int) * ee->prop.wm_rot.count);
++ *count = ee->prop.wm_rot.count;
++
++ return EINA_TRUE;
++}
++
+ EAPI void
+ ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
+ {
+diff --git a/src/lib/ecore_evas/ecore_evas_buffer.c b/src/lib/ecore_evas/ecore_evas_buffer.c
+index f15436c..22e9423 100644
+--- a/src/lib/ecore_evas/ecore_evas_buffer.c
++++ b/src/lib/ecore_evas/ecore_evas_buffer.c
+@@ -526,7 +526,11 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
+
+ _ecore_evas_buffer_render,
+ NULL, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
++
+ };
+ #endif
+
+diff --git a/src/lib/ecore_evas/ecore_evas_cocoa.c b/src/lib/ecore_evas/ecore_evas_cocoa.c
+index 96ea1d4..60b3f34 100644
+--- a/src/lib/ecore_evas/ecore_evas_cocoa.c
++++ b/src/lib/ecore_evas/ecore_evas_cocoa.c
+@@ -474,7 +474,10 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
+
+ NULL, // render
+ NULL,
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+ #endif
+
+diff --git a/src/lib/ecore_evas/ecore_evas_directfb.c b/src/lib/ecore_evas/ecore_evas_directfb.c
+index d9fb237..bf9fbc4 100644
+--- a/src/lib/ecore_evas/ecore_evas_directfb.c
++++ b/src/lib/ecore_evas/ecore_evas_directfb.c
+@@ -500,7 +500,10 @@ static Ecore_Evas_Engine_Func _ecore_directfb_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+ #endif
+
+diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c
+index d6969cf..c9d0b5c 100644
+--- a/src/lib/ecore_evas/ecore_evas_ews.c
++++ b/src/lib/ecore_evas/ecore_evas_ews.c
+@@ -694,7 +694,10 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func =
+
+ _ecore_evas_ews_render,
+ _ecore_evas_ews_screen_geometry_get,
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ void
+diff --git a/src/lib/ecore_evas/ecore_evas_extn.c b/src/lib/ecore_evas/ecore_evas_extn.c
+index bec246b..48376b3 100644
+--- a/src/lib/ecore_evas/ecore_evas_extn.c
++++ b/src/lib/ecore_evas/ecore_evas_extn.c
+@@ -1189,7 +1189,10 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ static Eina_Bool
+diff --git a/src/lib/ecore_evas/ecore_evas_fb.c b/src/lib/ecore_evas/ecore_evas_fb.c
+index f536565..caa1a48 100644
+--- a/src/lib/ecore_evas/ecore_evas_fb.c
++++ b/src/lib/ecore_evas/ecore_evas_fb.c
+@@ -562,7 +562,10 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+ #endif
+
+diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h
+index efeaa52..e2fd107 100644
+--- a/src/lib/ecore_evas/ecore_evas_private.h
++++ b/src/lib/ecore_evas/ecore_evas_private.h
+@@ -189,6 +189,8 @@ struct _Ecore_Evas_Engine_Func
+ int (*fn_render) (Ecore_Evas *ee);
+ void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
+ void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
++ void (*fn_wm_rot_preferred_rotation_set) (Ecore_Evas *ee, int rot);
++ void (*fn_wm_rot_available_rotations_set) (Ecore_Evas *ee, const int *rots, unsigned int count);
+ };
+
+ struct _Ecore_Evas_Engine
+@@ -221,6 +223,13 @@ struct _Ecore_Evas_Engine
+ unsigned char netwm_sync_set : 1;
+ unsigned char configure_coming : 1;
+ struct {
++ unsigned char supported: 1;
++ unsigned char prepare : 1;
++ unsigned char request : 1;
++ unsigned char done : 1;
++ unsigned char configure_coming : 1;
++ } wm_rot;
++ struct {
+ unsigned char modal : 1;
+ unsigned char sticky : 1;
+ unsigned char maximized_v : 1;
+@@ -335,6 +344,18 @@ struct _Ecore_Evas
+ char *clas;
+ char *profile;
+ struct {
++ Eina_Bool supported;
++ int angle; // v0
++ Eina_Bool win_resize; // v0
++ int w, h; // v0
++ // added for the window manager rotation protocol
++ Eina_Bool app_set; // v1: app wants to communicate with the window manager to rotate
++ int rot; // v1: decided rotation by the window manager
++ int preferred_rot; // v1: app specified rotation
++ int *available_rots;// v1: app specified available rotations
++ unsigned int count; // v1: number of elements of available rotations
++ } wm_rot;
++ struct {
+ int w, h;
+ } min,
+ max,
+diff --git a/src/lib/ecore_evas/ecore_evas_psl1ght.c b/src/lib/ecore_evas/ecore_evas_psl1ght.c
+index 98d570e..dbd160c 100644
+--- a/src/lib/ecore_evas/ecore_evas_psl1ght.c
++++ b/src/lib/ecore_evas/ecore_evas_psl1ght.c
+@@ -406,7 +406,10 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func =
+
+ NULL, // render
+ _ecore_evas_screen_geometry_get, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ EAPI Ecore_Evas *
+diff --git a/src/lib/ecore_evas/ecore_evas_sdl.c b/src/lib/ecore_evas/ecore_evas_sdl.c
+index a24394d..a77d9ed 100644
+--- a/src/lib/ecore_evas/ecore_evas_sdl.c
++++ b/src/lib/ecore_evas/ecore_evas_sdl.c
+@@ -448,7 +448,10 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- NULL // screen_dpi_get
++ NULL, // screen_dpi_get
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ static Ecore_Evas*
+diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
+index 504b5e2..25aa6e0 100644
+--- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
++++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
+@@ -178,7 +178,9 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
+ NULL,
+ _ecore_evas_wl_render,
+ _ecore_evas_wl_screen_geometry_get,
+- _ecore_evas_wl_screen_dpi_get
++ _ecore_evas_wl_screen_dpi_get,
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ /* external variables */
+diff --git a/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/src/lib/ecore_evas/ecore_evas_wayland_shm.c
+index a8e0181..7418f95 100644
+--- a/src/lib/ecore_evas/ecore_evas_wayland_shm.c
++++ b/src/lib/ecore_evas/ecore_evas_wayland_shm.c
+@@ -197,7 +197,9 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
+ NULL, // focus skip set
+ _ecore_evas_wl_render,
+ _ecore_evas_wl_screen_geometry_get,
+- _ecore_evas_wl_screen_dpi_get
++ _ecore_evas_wl_screen_dpi_get,
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ /* external variables */
+diff --git a/src/lib/ecore_evas/ecore_evas_win32.c b/src/lib/ecore_evas/ecore_evas_win32.c
+index 59d6ed8..dc91a4d 100644
+--- a/src/lib/ecore_evas/ecore_evas_win32.c
++++ b/src/lib/ecore_evas/ecore_evas_win32.c
+@@ -1121,7 +1121,10 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- _ecore_evas_win32_screen_dpi_get
++ _ecore_evas_win32_screen_dpi_get,
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ #endif /* BUILD_ECORE_EVAS_WIN32 */
+diff --git a/src/lib/ecore_evas/ecore_evas_wince.c b/src/lib/ecore_evas/ecore_evas_wince.c
+index fe0054a..d69e483 100644
+--- a/src/lib/ecore_evas/ecore_evas_wince.c
++++ b/src/lib/ecore_evas/ecore_evas_wince.c
+@@ -802,7 +802,10 @@ static Ecore_Evas_Engine_Func _ecore_wince_engine_func =
+
+ NULL, // render
+ NULL, // screen_geometry_get
+- _ecore_evas_wince_screen_dpi_get
++ _ecore_evas_wince_screen_dpi_get,
++
++ NULL, // wm_rot_preferred_rotation_set
++ NULL // wm_rot_available_rotations_set
+ };
+
+ /* API */
+diff --git a/src/lib/ecore_evas/ecore_evas_x.c b/src/lib/ecore_evas/ecore_evas_x.c
+index 75b483c..2ef7ca9 100644
+--- a/src/lib/ecore_evas/ecore_evas_x.c
++++ b/src/lib/ecore_evas/ecore_evas_x.c
+@@ -3097,7 +3097,9 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func =
+
+ NULL, // render
+ _ecore_evas_x_screen_geometry_get,
+- _ecore_evas_x_screen_dpi_get
++ _ecore_evas_x_screen_dpi_get,
++ NULL, //_wm_rot_preferred_rotation_set
++ NULL //_wm_rot_available_rotations_set
+ };
+ #endif /* BUILD_ECORE_EVAS_X11 */
+
+--
+1.8.1.4
+
--- /dev/null
+From 9b8fa78fb55b0c034ea326abb8dde6960045432a Mon Sep 17 00:00:00 2001
+From: Jan Arne Petersen <jpetersen@openismus.com>
+Date: Wed, 17 Apr 2013 11:59:46 +0200
+Subject: [PATCH] ecore_imf: Add support for wayland
+
+Add an input method module supporting the Wayland input method protocol.
+
+In v2:
+ - Missing call to ecore_wl_shutdown() in im_module_shutdown()
+ - Access the already stored 'wayland globals' with ecore_wl_globals_get()
+ - Fixed compilation by adding -I(top_srcdir)/src/efl to CFLAGS
+ - EFL formatting fixes
+
+Signed-off-by: Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
+---
+ configure.ac | 21 +
+ src/modules/immodules/Makefile.am | 4 +
+ src/modules/immodules/wayland/Makefile.am | 38 +
+ .../immodules/wayland/text-client-protocol.h | 544 ++++++++++++++
+ src/modules/immodules/wayland/text-protocol.c | 94 +++
+ src/modules/immodules/wayland/wayland_imcontext.c | 778 +++++++++++++++++++++
+ src/modules/immodules/wayland/wayland_imcontext.h | 70 ++
+ src/modules/immodules/wayland/wayland_module.c | 154 ++++
+ 9 files changed, 1704 insertions(+), 1 deletion(-)
+ create mode 100644 src/modules/immodules/wayland/Makefile.am
+ create mode 100644 src/modules/immodules/wayland/text-client-protocol.h
+ create mode 100644 src/modules/immodules/wayland/text-protocol.c
+ create mode 100644 src/modules/immodules/wayland/wayland_imcontext.c
+ create mode 100644 src/modules/immodules/wayland/wayland_imcontext.h
+ create mode 100644 src/modules/immodules/wayland/wayland_module.c
+
+diff --git a/configure.ac b/configure.ac
+index 79b8652..b18c773 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -179,6 +179,7 @@ want_ecore_evas_wayland_egl="no"
+ want_ecore_imf_xim="no"
+ want_ecore_imf_scim="no"
+ want_ecore_imf_ibus="no"
++want_ecore_imf_wayland="no"
+
+ case "$host_os" in
+ mingw32ce*)
+@@ -244,6 +245,9 @@ case "$host_os" in
+ want_ecore_imf_xim="yes"
+ want_ecore_imf_scim="yes"
+ want_ecore_imf_ibus="yes"
++ if test "${want_ecore_wayland}" = "yes"; then
++ want_ecore_imf_wayland="yes"
++ fi
+ ;;
+ esac
+
+@@ -274,6 +278,7 @@ requirements_ecore_imf_xim=""
+ requirements_ecore_imf_scim=""
+ requirements_ecore_imf_ibus=""
+ requirements_ecore_wayland=""
++requirements_ecore_imf_wayland=""
+
+ ### Additional options to configure
+
+@@ -1985,6 +1990,19 @@ ECORE_EVAS_CHECK_MODULE_FULL([wayland-egl], [wayland-egl egl >= 7.10],
+ fi
+ ])
+
++# ecore_imf_wayland
++ecore_imf_wayland_deps="no"
++echo "have_ecore_wayland: ${have_ecore_wayland}"
++if test "x${have_ecore_imf}" = "xyes" \
++ -a "x${have_wayland}" = "xyes" \
++ -a "x${have_ecore_input}" = "xyes" ; then
++ ecore_imf_wayland_deps="yes"
++ AC_DEFINE(BUILD_ECORE_IMF_WAYLAND, 1, [Ecore Imf Wayland Support])
++fi
++
++ECORE_CHECK_MODULE([imf-wayland], [${want_ecore_imf}], [Imf_Wayland], [${ecore_imf_wayland_deps}],
++ [e seu pequirements_ecore_imf_wayland="ecore-imf >= 1.7.8 ecore-wayland >= 1.7.8 ecore-input >= 1.7.8 ${requirements_ecore_imf_wayland}"])
++
+ ### Unit tests and coverage
+
+ EFL_CHECK_TESTS([enable_tests="yes"], [enable_tests="no"])
+@@ -2025,6 +2043,7 @@ AC_SUBST(requirements_ecore_imf_xim)
+ AC_SUBST(requirements_ecore_imf_scim)
+ AC_SUBST(requirements_ecore_imf_ibus)
+ AC_SUBST(requirements_ecore_wayland)
++AC_SUBST(requirements_ecore_imf_wayland)
+
+ AC_CONFIG_FILES([
+ Makefile
+@@ -2082,6 +2101,7 @@ src/modules/immodules/Makefile
+ src/modules/immodules/xim/Makefile
+ src/modules/immodules/scim/Makefile
+ src/modules/immodules/ibus/Makefile
++src/modules/immodules/wayland/Makefile
+ ecore.spec
+ $po_makefile_in
+ ])
+@@ -2148,6 +2168,7 @@ echo " Ecore_IMF....................: $have_ecore_imf"
+ echo " XIM........................: $have_ecore_imf_xim"
+ echo " SCIM.......................: $have_ecore_imf_scim"
+ echo " IBUS.......................: $have_ecore_imf_ibus"
++echo " Wayland....................: $have_ecore_imf_wayland"
+ echo " Ecore_IMF_Evas...............: $have_ecore_imf_evas"
+ echo " Ecore_Input..................: $have_ecore_input"
+ echo " Ecore_Input_Evas.............: $have_ecore_input_evas"
+diff --git a/src/modules/immodules/Makefile.am b/src/modules/immodules/Makefile.am
+index 22b6496..aef92de 100644
+--- a/src/modules/immodules/Makefile.am
++++ b/src/modules/immodules/Makefile.am
+@@ -13,3 +13,7 @@ endif
+ if BUILD_ECORE_IMF_IBUS
+ SUBDIRS += ibus
+ endif
++
++if BUILD_ECORE_IMF_WAYLAND
++SUBDIRS += wayland
++endif
+diff --git a/src/modules/immodules/wayland/Makefile.am b/src/modules/immodules/wayland/Makefile.am
+new file mode 100644
+index 0000000..d26f06c
+--- /dev/null
++++ b/src/modules/immodules/wayland/Makefile.am
+@@ -0,0 +1,38 @@
++MAINTAINERCLEANFILES = Makefile.in
++
++AM_CFLAGS = \
++-I$(top_srcdir) \
++-I$(top_srcdir)/src/lib/ecore \
++-I$(top_srcdir)/src/lib/ecore_input \
++-I$(top_srcdir)/src/lib/ecore_wayland \
++-I$(top_srcdir)/src/lib/ecore_imf \
++-I$(top_srcdir)/src/lib/ecore_evas \
++-I$(top_builddir)/src/lib/ecore \
++-I$(top_builddir)/src/lib/ecore_input \
++-I$(top_builddir)/src/lib/ecore_wayland \
++-I$(top_builddir)/src/lib/ecore_imf \
++-I$(top_builddir)/src/lib/ecore_evas \
++-DPACKAGE_LIB_DIR=\"$(libdir)\" \
++-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
++@WAYLAND_CFLAGS@ \
++@EVAS_CFLAGS@ \
++@EINA_CFLAGS@
++
++pkgdir = $(libdir)/ecore/immodules
++
++pkg_LTLIBRARIES = wayland.la
++wayland_la_SOURCES = \
++text-protocol.c \
++text-protocol.h \
++wayland_module.c \
++wayland_imcontext.c \
++wayland_imcontext.h
++
++wayland_la_LIBADD = \
++ $(top_builddir)/src/lib/ecore_imf/libecore_imf.la \
++ $(top_builddir)/src/lib/ecore_wayland/libecore_wayland.la \
++ @WAYLAND_LIBS@ \
++ @EVAS_LIBS@ \
++ @EINA_LIBS@
++wayland_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
++wayland_la_LIBTOOLFLAGS = --tag=disable-static
+diff --git a/src/modules/immodules/wayland/text-client-protocol.h b/src/modules/immodules/wayland/text-client-protocol.h
+new file mode 100644
+index 0000000..cfea94b
+--- /dev/null
++++ b/src/modules/immodules/wayland/text-client-protocol.h
+@@ -0,0 +1,544 @@
++/*
++ * 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 Unicode
++ * characters.
++ *
++ * 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 Unicode characters from index relative to the
++ * beginning of the composing text (as Unicode character 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 Unicode
++ * character 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 Unicode characters).
++ * Length is the length of deleted text (in Unicode characters).
++ *
++ * 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/src/modules/immodules/wayland/text-protocol.c b/src/modules/immodules/wayland/text-protocol.c
+new file mode 100644
+index 0000000..af549d5
+--- /dev/null
++++ b/src/modules/immodules/wayland/text-protocol.c
+@@ -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/src/modules/immodules/wayland/wayland_imcontext.c b/src/modules/immodules/wayland/wayland_imcontext.c
+new file mode 100644
+index 0000000..203976f
+--- /dev/null
++++ b/src/modules/immodules/wayland/wayland_imcontext.c
+@@ -0,0 +1,778 @@
++/*
++ * 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.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Ecore_Input.h>
++#include <Ecore_Wayland.h>
++
++#include "wayland_imcontext.h"
++
++struct _WaylandIMContext
++{
++ Ecore_IMF_Context *ctx;
++
++ struct wl_text_input_manager *text_input_manager;
++ struct wl_text_input *text_input;
++
++ Ecore_Wl_Window *window;
++ Evas *canvas;
++
++ char *preedit_text;
++ char *preedit_commit;
++ Eina_List *preedit_attrs;
++ int32_t preedit_cursor;
++
++ struct
++ {
++ Eina_List *attrs;
++ int32_t cursor;
++ } pending_preedit;
++
++ struct
++ {
++ int32_t cursor;
++ int32_t anchor;
++ uint32_t delete_index;
++ uint32_t delete_length;
++ } pending_commit;
++
++ struct
++ {
++ int x;
++ int y;
++ int width;
++ int height;
++ } cursor_location;
++
++ xkb_mod_mask_t control_mask;
++ xkb_mod_mask_t alt_mask;
++ xkb_mod_mask_t shift_mask;
++
++ uint32_t serial;
++ uint32_t reset_serial;
++};
++
++static unsigned int
++utf8_offset_to_characters(const char *str, int offset)
++{
++ int index = 0;
++ unsigned int i = 0;
++ for (; index < offset; i++)
++ eina_unicode_utf8_get_next(str, &index);
++
++ return i;
++}
++
++static void
++update_state(WaylandIMContext *imcontext)
++{
++ char *surrounding;
++ int cursor_pos;
++ Ecore_Evas *ee;
++ int canvas_x = 0, canvas_y = 0;
++
++ if (!imcontext->ctx)
++ return;
++
++ /* cursor_pos is a byte index */
++ if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos))
++ {
++ wl_text_input_set_surrounding_text(imcontext->text_input,
++ surrounding,
++ cursor_pos,
++ cursor_pos);
++ free(surrounding);
++ }
++
++ if (imcontext->canvas)
++ {
++ ee = ecore_evas_ecore_evas_get(imcontext->canvas);
++ if (ee)
++ ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
++ }
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "canvas (x: %d, y: %d)", canvas_x, canvas_y);
++
++ wl_text_input_set_cursor_rectangle(imcontext->text_input,
++ imcontext->cursor_location.x + canvas_x,
++ imcontext->cursor_location.y + canvas_y,
++ imcontext->cursor_location.width,
++ imcontext->cursor_location.height);
++
++ wl_text_input_commit_state(imcontext->text_input, ++imcontext->serial);
++}
++
++static Eina_Bool
++check_serial(WaylandIMContext *imcontext, uint32_t serial)
++{
++ Ecore_IMF_Preedit_Attr *attr;
++
++ if ((imcontext->serial - serial) > (imcontext->serial - imcontext->reset_serial))
++ {
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "outdated serial: %u, current: %u, reset: %u",
++ serial, imcontext->serial, imcontext->reset_serial);
++
++ /* Clear pending data */
++ imcontext->pending_commit.delete_index = 0;
++ imcontext->pending_commit.delete_length = 0;
++ imcontext->pending_commit.cursor = 0;
++ imcontext->pending_commit.anchor = 0;
++
++ imcontext->pending_preedit.cursor = 0;
++ EINA_LIST_FREE(imcontext->pending_preedit.attrs, attr) free(attr);
++ imcontext->pending_preedit.attrs = NULL;
++
++ return EINA_FALSE;
++ }
++
++ return EINA_TRUE;
++}
++
++static void
++clear_preedit(WaylandIMContext *imcontext)
++{
++ Ecore_IMF_Preedit_Attr *attr;
++
++ imcontext->preedit_cursor = 0;
++
++ free(imcontext->preedit_text);
++ imcontext->preedit_text = NULL;
++
++ free(imcontext->preedit_commit);
++ imcontext->preedit_commit = NULL;
++
++ EINA_LIST_FREE(imcontext->preedit_attrs, attr)
++ free(attr);
++
++ imcontext->preedit_attrs = NULL;
++}
++
++static void
++text_input_commit_string(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t serial,
++ const char *text)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++ Eina_Bool old_preedit = EINA_FALSE;
++ char *surrounding;
++ int cursor_pos, cursor;
++ Ecore_IMF_Event_Delete_Surrounding ev;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "commit event (text: `%s', current pre-edit: `%s')",
++ text,
++ imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ old_preedit = imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
++
++ if (!imcontext->ctx)
++ return;
++
++ if (!check_serial(imcontext, serial))
++ return;
++
++ if (old_preedit)
++ {
++ ecore_imf_context_preedit_end_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
++ }
++
++ clear_preedit(imcontext);
++
++ if (imcontext->pending_commit.delete_length > 0)
++ {
++ /* cursor_pos is a byte index */
++ if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos))
++ {
++ ev.ctx = imcontext->ctx;
++ /* offset and n_chars are in characters */
++ ev.offset = utf8_offset_to_characters(surrounding, cursor_pos + imcontext->pending_commit.delete_index);
++ ev.n_chars = utf8_offset_to_characters(surrounding,
++ cursor_pos + imcontext->pending_commit.delete_index + imcontext->pending_commit.delete_length) - ev.offset;
++
++ /* cursor in characters */
++ cursor = utf8_offset_to_characters(surrounding, cursor_pos);
++
++ ev.offset -= cursor;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "delete on commit (text: `%s', offset `%d', length: `%d')",
++ surrounding, ev.offset, ev.n_chars);
++
++ ecore_imf_context_delete_surrounding_event_add(imcontext->ctx, ev.offset, ev.n_chars);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
++ }
++ }
++
++ imcontext->pending_commit.delete_index = 0;
++ imcontext->pending_commit.delete_length = 0;
++ imcontext->pending_commit.cursor = 0;
++ imcontext->pending_commit.anchor = 0;
++
++ ecore_imf_context_commit_event_add(imcontext->ctx, text);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text);
++}
++
++static void
++commit_preedit(WaylandIMContext *imcontext)
++{
++ if (!imcontext->preedit_commit)
++ return;
++
++ if (!imcontext->ctx)
++ return;
++
++ ecore_imf_context_commit_event_add(imcontext->ctx, imcontext->preedit_commit);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)imcontext->preedit_commit);
++}
++
++static void
++text_input_preedit_string(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t serial,
++ const char *text,
++ const char *commit)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++ Eina_Bool old_preedit = EINA_FALSE;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "preedit event (text: `%s', current pre-edit: `%s')",
++ text,
++ imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ if (!check_serial(imcontext, serial))
++ return;
++
++ old_preedit = imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
++
++ clear_preedit(imcontext);
++
++ imcontext->preedit_text = strdup(text);
++ imcontext->preedit_commit = strdup(commit);
++ imcontext->preedit_cursor = utf8_offset_to_characters(text, imcontext->pending_preedit.cursor);
++ imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
++
++ imcontext->pending_preedit.attrs = NULL;
++
++ if (!old_preedit)
++ {
++ ecore_imf_context_preedit_start_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
++ }
++
++ ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
++
++ if (strlen(imcontext->preedit_text) == 0)
++ {
++ ecore_imf_context_preedit_end_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
++ }
++}
++
++static void
++text_input_delete_surrounding_text(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ int32_t index,
++ uint32_t length)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "delete surrounding text (index: %d, length: %u)",
++ index,
++ length);
++
++ imcontext->pending_commit.delete_index = index;
++ imcontext->pending_commit.delete_length = length;
++}
++
++static void
++text_input_cursor_position(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ int32_t index,
++ int32_t anchor)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "cursor_position for next commit (index: %d, anchor: %d)",
++ index,
++ anchor);
++
++ imcontext->pending_commit.cursor = index;
++ imcontext->pending_commit.anchor = anchor;
++}
++
++static void
++text_input_preedit_styling(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t index,
++ uint32_t length,
++ uint32_t style)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++ Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
++
++ switch (style)
++ {
++ case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT:
++ case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE:
++ case WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT:
++ case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT:
++ case WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE:
++ case WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE:
++ attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
++ break;
++ case WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION:
++ attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
++ break;
++ }
++
++ attr->start_index = index;
++ attr->end_index = index + length;
++
++ imcontext->pending_preedit.attrs = eina_list_append(imcontext->pending_preedit.attrs, attr);
++}
++
++static void
++text_input_preedit_cursor(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ int32_t index)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ imcontext->pending_preedit.cursor = index;
++}
++
++static xkb_mod_index_t
++modifiers_get_index(struct wl_array *modifiers_map,
++ const char *name)
++{
++ xkb_mod_index_t index = 0;
++ char *p = modifiers_map->data;
++
++ while ((const char *)p < ((const char *)modifiers_map->data + modifiers_map->size))
++ {
++ if (strcmp(p, name) == 0)
++ return index;
++
++ index++;
++ p += strlen(p) + 1;
++ }
++
++ return XKB_MOD_INVALID;
++}
++
++static xkb_mod_mask_t
++modifiers_get_mask(struct wl_array *modifiers_map,
++ const char *name)
++{
++ xkb_mod_index_t index = modifiers_get_index(modifiers_map, name);
++
++ if (index == XKB_MOD_INVALID)
++ return XKB_MOD_INVALID;
++
++ return 1 << index;
++}
++static void
++text_input_modifiers_map(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ struct wl_array *map)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ imcontext->shift_mask = modifiers_get_mask(map, "Shift");
++ imcontext->control_mask = modifiers_get_mask(map, "Control");
++ imcontext->alt_mask = modifiers_get_mask(map, "Mod1");
++}
++
++static void
++text_input_keysym(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t serial EINA_UNUSED,
++ uint32_t time,
++ uint32_t sym,
++ uint32_t state,
++ uint32_t modifiers)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++ char string[32], key[32], keyname[32];
++ Ecore_Event_Key *e;
++
++ memset(key, 0, sizeof(key));
++ xkb_keysym_get_name(sym, key, sizeof(key));
++
++ memset(keyname, 0, sizeof(keyname));
++ xkb_keysym_get_name(sym, keyname, sizeof(keyname));
++ if (keyname[0] == '\0')
++ snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
++
++ memset(string, 0, sizeof(string));
++ xkb_keysym_to_utf8(sym, string, 32);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "key event (key: %s)",
++ keyname);
++
++ e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + strlen(string) + 3);
++ if (!e)
++ return;
++
++ e->keyname = (char *)(e + 1);
++ e->key = e->keyname + strlen(keyname) + 1;
++ e->string = e->key + strlen(key) + 1;
++ e->compose = e->string;
++
++ strcpy((char *)e->keyname, keyname);
++ strcpy((char *)e->key, key);
++ strcpy((char *)e->string, string);
++
++ e->window = imcontext->window->id;
++ e->event_window = imcontext->window->id;
++ e->timestamp = time;
++
++ e->modifiers = 0;
++ if (modifiers & imcontext->shift_mask)
++ e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
++
++ if (modifiers & imcontext->control_mask)
++ e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
++
++ if (modifiers & imcontext->alt_mask)
++ e->modifiers |= ECORE_EVENT_MODIFIER_ALT;
++
++ if (state)
++ ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
++ else
++ ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
++}
++
++static void
++text_input_enter(void *data,
++ struct wl_text_input *text_input EINA_UNUSED,
++ struct wl_surface *surface EINA_UNUSED)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ update_state(imcontext);
++
++ imcontext->reset_serial = imcontext->serial;
++}
++
++static void
++text_input_leave(void *data,
++ struct wl_text_input *text_input)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)data;
++
++ wl_text_input_hide_input_panel(text_input);
++
++ /* clear preedit */
++ commit_preedit(imcontext);
++ clear_preedit(imcontext);
++
++ ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
++
++ ecore_imf_context_preedit_end_event_add(imcontext->ctx);
++ ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
++}
++
++static void
++text_input_input_panel_state(void *data EINA_UNUSED,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t state EINA_UNUSED)
++{
++}
++
++static void
++text_input_language(void *data EINA_UNUSED,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t serial EINA_UNUSED,
++ const char *language EINA_UNUSED)
++{
++}
++
++static void
++text_input_text_direction(void *data EINA_UNUSED,
++ struct wl_text_input *text_input EINA_UNUSED,
++ uint32_t serial EINA_UNUSED,
++ uint32_t direction EINA_UNUSED)
++{
++}
++
++static const struct wl_text_input_listener text_input_listener =
++{
++ text_input_enter,
++ text_input_leave,
++ text_input_modifiers_map,
++ text_input_input_panel_state,
++ text_input_preedit_string,
++ text_input_preedit_styling,
++ text_input_preedit_cursor,
++ text_input_commit_string,
++ text_input_cursor_position,
++ text_input_delete_surrounding_text,
++ text_input_keysym,
++ text_input_language,
++ text_input_text_direction
++};
++
++EAPI void
++wayland_im_context_add(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_add");
++
++ imcontext->ctx = ctx;
++
++ imcontext->text_input = wl_text_input_manager_create_text_input(imcontext->text_input_manager);
++ wl_text_input_add_listener(imcontext->text_input, &text_input_listener, imcontext);
++}
++
++EAPI void
++wayland_im_context_del(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_del");
++
++ wl_text_input_destroy(imcontext->text_input);
++
++ clear_preedit(imcontext);
++}
++
++EAPI void
++wayland_im_context_reset(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ commit_preedit(imcontext);
++ clear_preedit(imcontext);
++
++ wl_text_input_reset(imcontext->text_input);
++
++ update_state(imcontext);
++
++ imcontext->reset_serial = imcontext->serial;
++}
++
++EAPI void
++wayland_im_context_focus_in(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++ Ecore_Wl_Input *input;
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "focus-in");
++
++ if (!imcontext->window)
++ return;
++
++ input = imcontext->window->keyboard_device;
++ if (!input || !input->seat)
++ return;
++
++ wl_text_input_show_input_panel(imcontext->text_input);
++ wl_text_input_activate(imcontext->text_input,
++ input->seat,
++ ecore_wl_window_surface_get(imcontext->window));
++}
++
++EAPI void
++wayland_im_context_focus_out(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "focus-out");
++
++ if (!imcontext->window)
++ return;
++
++ wl_text_input_deactivate(imcontext->text_input,
++ imcontext->window->display->input->seat);
++}
++
++EAPI void
++wayland_im_context_preedit_string_get(Ecore_IMF_Context *ctx,
++ char **str,
++ int *cursor_pos)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "pre-edit string requested (preedit: `%s')",
++ imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ if (str)
++ *str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ if (cursor_pos)
++ *cursor_pos = imcontext->preedit_cursor;
++}
++
++EAPI void
++wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
++ char **str,
++ Eina_List **attrs,
++ int *cursor_pos)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "pre-edit string with attributes requested (preedit: `%s')",
++ imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ if (str)
++ *str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
++
++ if (attrs)
++ {
++ Eina_List *l;
++ Ecore_IMF_Preedit_Attr *a, *attr;
++
++ EINA_LIST_FOREACH(imcontext->preedit_attrs, l, a)
++ {
++ attr = malloc(sizeof(*attr));
++ attr = memcpy(attr, a, sizeof(*attr));
++ *attrs = eina_list_append(*attrs, attr);
++ }
++ }
++
++ if (cursor_pos)
++ *cursor_pos = imcontext->preedit_cursor;
++}
++
++EAPI void
++wayland_im_context_cursor_position_set(Ecore_IMF_Context *ctx,
++ int cursor_pos)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
++ "set cursor position (cursor: %d)",
++ cursor_pos);
++
++ update_state(imcontext);
++}
++
++EAPI void
++wayland_im_context_use_preedit_set(Ecore_IMF_Context *ctx EINA_UNUSED,
++ Eina_Bool use_preedit EINA_UNUSED)
++{
++}
++
++EAPI void
++wayland_im_context_client_window_set(Ecore_IMF_Context *ctx,
++ void *window)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "client window set (window: %p)", window);
++
++ if (window != NULL)
++ imcontext->window = ecore_wl_window_find((Ecore_Window)window);
++}
++
++EAPI void
++wayland_im_context_client_canvas_set(Ecore_IMF_Context *ctx,
++ void *canvas)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "client canvas set (canvas: %p)", canvas);
++
++ if (canvas != NULL)
++ imcontext->canvas = canvas;
++}
++
++EAPI void
++wayland_im_context_show(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_show");
++
++ wl_text_input_show_input_panel(imcontext->text_input);
++}
++
++EAPI void
++wayland_im_context_hide(Ecore_IMF_Context *ctx)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_hide");
++
++ wl_text_input_hide_input_panel(imcontext->text_input);
++}
++
++EAPI Eina_Bool
++wayland_im_context_filter_event(Ecore_IMF_Context *ctx EINA_UNUSED,
++ Ecore_IMF_Event_Type type EINA_UNUSED,
++ Ecore_IMF_Event *event EINA_UNUSED)
++{
++ return EINA_FALSE;
++}
++
++EAPI void
++wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int width, int height)
++{
++ WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "cursor_location_set (x: %d, y: %d, w: %d, h: %d)", x, y, width, height);
++
++ if ((imcontext->cursor_location.x != x) ||
++ (imcontext->cursor_location.y != y) ||
++ (imcontext->cursor_location.width != width) ||
++ (imcontext->cursor_location.height != height))
++ {
++ imcontext->cursor_location.x = x;
++ imcontext->cursor_location.y = y;
++ imcontext->cursor_location.width = width;
++ imcontext->cursor_location.height = height;
++
++ update_state(imcontext);
++ }
++}
++
++
++WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager)
++{
++ WaylandIMContext *context = calloc(1, sizeof(WaylandIMContext));
++
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "new context created");
++ context->text_input_manager = text_input_manager;
++
++ return context;
++}
++
++/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
++*/
+diff --git a/src/modules/immodules/wayland/wayland_imcontext.h b/src/modules/immodules/wayland/wayland_imcontext.h
+new file mode 100644
+index 0000000..fb6906c
+--- /dev/null
++++ b/src/modules/immodules/wayland/wayland_imcontext.h
+@@ -0,0 +1,70 @@
++/*
++ * 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 __WAYLAND_IM_CONTEXT_H_
++#define __WAYLAND_IM_CONTEXT_H_
++
++#include <Ecore_IMF.h>
++#include "text-client-protocol.h"
++
++typedef struct _WaylandIMContext WaylandIMContext;
++
++EAPI void wayland_im_context_add (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_del (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_reset (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_focus_in (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_focus_out (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_preedit_string_get (Ecore_IMF_Context *ctx,
++ char **str,
++ int *cursor_pos);
++EAPI void wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
++ char **str,
++ Eina_List **attr,
++ int *cursor_pos);
++
++EAPI void wayland_im_context_cursor_position_set(Ecore_IMF_Context *ctx,
++ int cursor_pos);
++EAPI void wayland_im_context_use_preedit_set (Ecore_IMF_Context *ctx,
++ Eina_Bool use_preedit);
++EAPI void wayland_im_context_client_window_set (Ecore_IMF_Context *ctx,
++ void *window);
++EAPI void wayland_im_context_client_canvas_set (Ecore_IMF_Context *ctx,
++ void *canvas);
++EAPI void wayland_im_context_show (Ecore_IMF_Context *ctx);
++EAPI void wayland_im_context_hide (Ecore_IMF_Context *ctx);
++EAPI Eina_Bool wayland_im_context_filter_event (Ecore_IMF_Context *ctx,
++ Ecore_IMF_Event_Type type,
++ Ecore_IMF_Event *event);
++EAPI void wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx,
++ int x,
++ int y,
++ int width,
++ int height);
++
++WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager);
++
++extern int _ecore_imf_wayland_log_dom;
++
++#endif
++
++/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
++ */
+diff --git a/src/modules/immodules/wayland/wayland_module.c b/src/modules/immodules/wayland/wayland_module.c
+new file mode 100644
+index 0000000..642b017
+--- /dev/null
++++ b/src/modules/immodules/wayland/wayland_module.c
+@@ -0,0 +1,154 @@
++/*
++ * 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 <Ecore.h>
++#include <Ecore_IMF.h>
++#include <Ecore_Wayland.h>
++#include <stdio.h>
++
++#include "wayland_imcontext.h"
++#include "text-client-protocol.h"
++
++int _ecore_imf_wayland_log_dom = -1;
++
++static const Ecore_IMF_Context_Info wayland_im_info =
++{
++ "wayland",
++ "Wayland",
++ "*",
++ NULL,
++ 0
++};
++
++static Ecore_IMF_Context_Class wayland_imf_class =
++{
++ wayland_im_context_add, /* add */
++ wayland_im_context_del, /* del */
++ wayland_im_context_client_window_set, /* client_window_set */
++ wayland_im_context_client_canvas_set, /* client_canvas_set */
++ wayland_im_context_show, /* show */
++ wayland_im_context_hide, /* hide */
++ wayland_im_context_preedit_string_get, /* get_preedit_string */
++ wayland_im_context_focus_in, /* focus_in */
++ wayland_im_context_focus_out, /* focus_out */
++ wayland_im_context_reset, /* reset */
++ wayland_im_context_cursor_position_set, /* cursor_position_set */
++ wayland_im_context_use_preedit_set, /* use_preedit_set */
++ NULL, /* input_mode_set */
++ wayland_im_context_filter_event, /* filter_event */
++ wayland_im_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */
++ NULL, /* prediction_allow_set */
++ NULL, /* autocapital_type_set */
++ NULL, /* control panel show */
++ NULL, /* control panel hide */
++ NULL, /* input_panel_layout_set */
++ NULL, /* input_panel_layout_get, */
++ NULL, /* input_panel_language_set, */
++ NULL, /* input_panel_language_get, */
++ wayland_im_context_cursor_location_set, /* cursor_location_set */
++ NULL, /* input_panel_imdata_set */
++ NULL, /* input_panel_imdata_get */
++ NULL, /* input_panel_return_key_type_set */
++ NULL, /* input_panel_return_key_disabled_set */
++ NULL, /* input_panel_caps_lock_mode_set */
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ NULL
++};
++
++static struct wl_text_input_manager *text_input_manager = NULL;
++
++static Ecore_IMF_Context *
++im_module_exit(void)
++{
++ return NULL;
++}
++
++static Ecore_IMF_Context *
++im_module_create()
++{
++ Ecore_IMF_Context *ctx = NULL;
++ WaylandIMContext *ctxd = NULL;
++
++ if (!text_input_manager)
++ {
++ Ecore_Wl_Global *global;
++ struct wl_registry *registry = ecore_wl_registry_get();
++ struct wl_list *globals = ecore_wl_globals_get();
++
++ if (!registry || !globals)
++ return NULL;
++
++ wl_list_for_each(global, globals, link)
++ {
++ if (!strcmp(global->interface, "wl_text_input_manager"))
++ {
++ text_input_manager = wl_registry_bind(registry, global->id, &wl_text_input_manager_interface, 1);
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "bound wl_text_input_manager interface");
++ break;
++ }
++ }
++ }
++
++ ctxd = wayland_im_context_new(text_input_manager);
++ if (!ctxd)
++ {
++ return NULL;
++ }
++
++ ctx = ecore_imf_context_new(&wayland_imf_class);
++ if (!ctx)
++ {
++ free(ctxd);
++ return NULL;
++ }
++
++ ecore_imf_context_data_set(ctx, ctxd);
++
++ return ctx;
++}
++
++static Eina_Bool
++im_module_init(void)
++{
++ _ecore_imf_wayland_log_dom = eina_log_domain_register("ecore_imf_wayland", EINA_COLOR_YELLOW);
++
++ ecore_imf_module_register(&wayland_im_info, im_module_create, im_module_exit);
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module initalized");
++
++ return EINA_TRUE;
++}
++
++static void
++im_module_shutdown(void)
++{
++ EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module shutdown");
++}
++
++EINA_MODULE_INIT(im_module_init);
++EINA_MODULE_SHUTDOWN(im_module_shutdown);
++
++/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
++*/
+--
+1.8.1.4
+