discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=26d352f219f1c4ffbaa21857903d6e9290a7763a

commit 26d352f219f1c4ffbaa21857903d6e9290a7763a
Author: Seunghun Lee <shiin....@samsung.com>
Date:   Thu Aug 20 14:55:14 2015 -0400

    Add module "wl_text_input" for supporting *wl_text_input* and 
*wl_input_method* protocol in wayland.
    
    Summary:
    this patch allow to use virtual keyboard such as weston-keyboard.
    it was tested in wayland verion 1.6.
    
    Test Plan:
    <prerequisite>
    - Configure with --enable-wl-text-input
    - edit configuration file, e.cfg to enable module wl_text_input.
    
    1. run enlightenment as a wayland display server.
    2. run weston-keyboard.
    3. run weston-editor.
    
    Reviewers: raster, Sergeant_Whitespace, devilhorns, zmike
    
    Reviewed By: zmike
    
    Subscribers: ManMower, Sergeant_Whitespace, cedric, jihoon
    
    Differential Revision: https://phab.enlightenment.org/D2275
---
 configure.ac                                       |  11 +
 src/bin/e_comp_wl.h                                |   6 +
 src/bin/e_comp_wl_input.c                          |   4 +
 src/bin/e_comp_wl_input.h                          |   9 +
 src/modules/Makefile.mk                            |   2 +
 src/modules/Makefile_wl_desktop_shell.mk           |   5 +
 src/modules/Makefile_wl_text_input.mk              |  27 +
 .../wl_desktop_shell/e_input_method_protocol.c     | 114 +++
 .../wl_desktop_shell/e_input_method_protocol.h     | 418 +++++++++
 src/modules/wl_desktop_shell/e_mod_input_panel.c   | 336 ++++++++
 src/modules/wl_desktop_shell/e_mod_main.c          |  11 +
 src/modules/wl_desktop_shell/e_mod_main.h          |   7 +
 src/modules/wl_text_input/e_mod_main.c             | 933 +++++++++++++++++++++
 src/modules/wl_text_input/input-method-protocol.c  | 114 +++
 src/modules/wl_text_input/input-method-protocol.h  | 418 +++++++++
 src/modules/wl_text_input/text-protocol.c          |  92 ++
 src/modules/wl_text_input/text-protocol.h          | 448 ++++++++++
 17 files changed, 2955 insertions(+)

diff --git a/configure.ac b/configure.ac
index 6423c3b..db255d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -845,6 +845,16 @@ define([CHECK_MODULE_XWAYLAND],
 ])
 AM_CONDITIONAL([HAVE_XWAYLAND], [test "x${HAVE_XWAYLAND}" != "xno"])
 
+define([CHECK_MODULE_WL_TEXT_INPUT],
+[
+  if test "x${have_wayland}" = "xyes"; then
+    AC_E_CHECK_PKG(WL_TEXT_INPUT, [ ecore >= $efl_version eina >= $efl_version 
], [WL_TEXT_INPUT=true], [WL_TEXT_INPUT=false])
+  else
+    WL_TEXT_INPUT=false
+  fi
+])
+AM_CONDITIONAL([HAVE_WL_TEXT_INPUT], [test "x${WL_TEXT_INPUT}" = "xtrue"])
+
 AC_E_OPTIONAL_MODULE([ibar], true)
 AC_E_OPTIONAL_MODULE([clock], true)
 AC_E_OPTIONAL_MODULE([pager], true)
@@ -899,6 +909,7 @@ AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, 
[CHECK_MODULE_WL_X11])
 AC_E_OPTIONAL_MODULE([wl_wl], $have_wayland, [CHECK_MODULE_WL_WL])
 #AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
 AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
+AC_E_OPTIONAL_MODULE([wl_text_input], $have_wayland, 
[CHECK_MODULE_WL_TEXT_INPUT])
 AC_E_OPTIONAL_MODULE([policy_mobile], true)
 AC_E_OPTIONAL_MODULE([geolocation], true)
 AC_E_OPTIONAL_MODULE([xwayland], $have_wayland, [CHECK_MODULE_XWAYLAND])
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 821bd38..932e386 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -178,6 +178,12 @@ struct _E_Comp_Wl_Data
         Eina_List *resources;
         uint32_t version;
         char *name;
+
+        struct
+          {
+             struct wl_global *global;
+             struct wl_resource *resource;
+          } im;
      } seat;
 
    struct
diff --git a/src/bin/e_comp_wl_input.c b/src/bin/e_comp_wl_input.c
index 82e09ae..e457aff 100644
--- a/src/bin/e_comp_wl_input.c
+++ b/src/bin/e_comp_wl_input.c
@@ -3,6 +3,8 @@
 #include "e.h"
 #include <sys/mman.h>
 
+EAPI int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
+
 static void
 _e_comp_wl_input_update_seat_caps(void)
 {
@@ -426,6 +428,8 @@ e_comp_wl_input_init(void)
 
    wl_array_init(&e_comp_wl->kbd.keys);
 
+   E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
+
    return EINA_TRUE;
 }
 
diff --git a/src/bin/e_comp_wl_input.h b/src/bin/e_comp_wl_input.h
index 8db117e..15eef2f 100644
--- a/src/bin/e_comp_wl_input.h
+++ b/src/bin/e_comp_wl_input.h
@@ -3,6 +3,15 @@
 # ifndef E_COMP_WL_INPUT_H
 #  define E_COMP_WL_INPUT_H
 
+EAPI extern int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE;
+
+typedef struct _E_Event_Text_Input_Panel_Visibility_Change 
E_Event_Text_Input_Panel_Visibility_Change;
+
+struct _E_Event_Text_Input_Panel_Visibility_Change
+{
+   Eina_Bool visible;
+};
+
 EINTERN Eina_Bool e_comp_wl_input_init(void);
 EINTERN void e_comp_wl_input_shutdown(void);
 EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
diff --git a/src/modules/Makefile.mk b/src/modules/Makefile.mk
index 96f0c94..ed334b2 100644
--- a/src/modules/Makefile.mk
+++ b/src/modules/Makefile.mk
@@ -121,6 +121,8 @@ include src/modules/Makefile_wl_x11.mk
 
 include src/modules/Makefile_xwayland.mk
 
+include src/modules/Makefile_wl_text_input.mk
+
 include src/modules/Makefile_policy_mobile.mk
 
 include src/modules/Makefile_geolocation.mk
diff --git a/src/modules/Makefile_wl_desktop_shell.mk 
b/src/modules/Makefile_wl_desktop_shell.mk
index 58aa2d4..8e1ffe3 100644
--- a/src/modules/Makefile_wl_desktop_shell.mk
+++ b/src/modules/Makefile_wl_desktop_shell.mk
@@ -1,6 +1,8 @@
 EXTRA_DIST += src/modules/wl_desktop_shell/module.desktop.in \
 src/modules/wl_desktop_shell/e-module-wl_desktop_shell.edj \
 src/modules/wl_desktop_shell/module.desktop.in \
+src/modules/wl_desktop_shell/e_input_method_protocol.h \
+src/modules/wl_desktop_shell/e_input_method_protocol.c \
 src/modules/wl_desktop_shell/e_desktop_shell_protocol.h \
 src/modules/wl_desktop_shell/e_desktop_shell_protocol.c
 if USE_MODULE_WL_DESKTOP_SHELL
@@ -18,6 +20,9 @@ src_modules_wl_desktop_shell_module_la_LDFLAGS = 
$(MOD_LDFLAGS)
 
 src_modules_wl_desktop_shell_module_la_SOURCES = \
   src/modules/wl_desktop_shell/e_mod_main.c \
+  src/modules/wl_desktop_shell/e_mod_input_panel.c \
+  src/modules/wl_desktop_shell/e_input_method_protocol.c \
+  src/modules/wl_desktop_shell/e_input_method_protocol.h \
   src/modules/wl_desktop_shell/e_desktop_shell_protocol.c \
   src/modules/wl_desktop_shell/e_desktop_shell_protocol.h
 
diff --git a/src/modules/Makefile_wl_text_input.mk 
b/src/modules/Makefile_wl_text_input.mk
new file mode 100644
index 0000000..4c74923
--- /dev/null
+++ b/src/modules/Makefile_wl_text_input.mk
@@ -0,0 +1,27 @@
+EXTRA_DIST += \
+src/modules/wl_text_input/text-protocol.h \
+src/modules/wl_text_input/text-protocol.c \
+src/modules/wl_text_input/input-method-protocol.h \
+src/modules/wl_text_input/input-method-protocol.c
+
+if USE_MODULE_WL_TEXT_INPUT
+wl_text_inputdir = $(MDIR)/wl_text_input
+
+wl_text_inputpkgdir = $(MDIR)/wl_text_input/$(MODULE_ARCH)
+wl_text_inputpkg_LTLIBRARIES = src/modules/wl_text_input/module.la
+
+src_modules_wl_text_input_module_la_DEPENDENCIES = $(MDEPENDENCIES)
+src_modules_wl_text_input_module_la_CPPFLAGS  = $(MOD_CPPFLAGS) 
@WAYLAND_CFLAGS@
+src_modules_wl_text_input_module_la_LIBADD   = $(LIBS) @WAYLAND_LIBS@
+src_modules_wl_text_input_module_la_LDFLAGS = $(MOD_LDFLAGS)
+src_modules_wl_text_input_module_la_SOURCES = \
+  src/modules/wl_text_input/e_mod_main.c \
+  src/modules/wl_text_input/text-protocol.c \
+  src/modules/wl_text_input/text-protocol.h \
+  src/modules/wl_text_input/input-method-protocol.c \
+  src/modules/wl_text_input/input-method-protocol.h
+
+PHONIES += wl_text_input install-wl_text_input
+wl_text_input: $(wl_text_inputpkg_LTLIBRARIES) $(wl_text_input_DATA)
+install-wl_text_input: install-wl_text_inputDATA 
install-wl_text_inputpkgLTLIBRARIES
+endif
diff --git a/src/modules/wl_desktop_shell/e_input_method_protocol.c 
b/src/modules/wl_desktop_shell/e_input_method_protocol.c
new file mode 100644
index 0000000..feae244
--- /dev/null
+++ b/src/modules/wl_desktop_shell/e_input_method_protocol.c
@@ -0,0 +1,114 @@
+/* 
+ * 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_input_method_context_interface;
+extern const struct wl_interface wl_input_panel_surface_interface;
+extern const struct wl_interface wl_keyboard_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_surface_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 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = {
+       "wl_input_panel_surface", 1,
+       2, wl_input_panel_surface_requests,
+       0, NULL,
+};
+
diff --git a/src/modules/wl_desktop_shell/e_input_method_protocol.h 
b/src/modules/wl_desktop_shell/e_input_method_protocol.h
new file mode 100644
index 0000000..e4b8988
--- /dev/null
+++ b/src/modules/wl_desktop_shell/e_input_method_protocol.h
@@ -0,0 +1,418 @@
+/* 
+ * 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_SERVER_PROTOCOL_H
+#define INPUT_METHOD_SERVER_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-server.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
+ * @destroy: (none)
+ * @commit_string: commit string
+ * @preedit_string: pre-edit string
+ * @preedit_styling: pre-edit styling
+ * @preedit_cursor: pre-edit cursor
+ * @delete_surrounding_text: delete text
+ * @cursor_position: set cursor to a new position
+ * @modifiers_map: (none)
+ * @keysym: keysym
+ * @grab_keyboard: grab hardware keyboard
+ * @key: forward key event
+ * @modifiers: forward modifiers event
+ * @language: (none)
+ * @text_direction: (none)
+ *
+ * Corresponds to a text model on input method side. An input method
+ * context is created on text model 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_interface {
+       /**
+        * destroy - (none)
+        */
+       void (*destroy)(struct wl_client *client,
+                       struct wl_resource *resource);
+       /**
+        * commit_string - commit string
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        *
+        * Send the commit string text for insertion to the application.
+        *
+        * 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 will be removed.
+        */
+       void (*commit_string)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t serial,
+                             const char *text);
+       /**
+        * preedit_string - pre-edit string
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        * @commit: (none)
+        *
+        * Send the pre-edit string text to the application text input.
+        *
+        * The commit text can be used to replace the preedit text on reset
+        * (for example on unfocus).
+        *
+        * Also previously sent preedit_style and preedit_cursor requests
+        * are processed bt the text_input also.
+        */
+       void (*preedit_string)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              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 in bytes from index relative to the beginning
+        * of the composing text (as byte offset). Multiple styles can be
+        * applied to a composing text.
+        *
+        * This request should be sent before sending preedit_string
+        * request.
+        */
+       void (*preedit_styling)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               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 negative no cursor should be displayed.
+        *
+        * This request should be sent before sending preedit_string
+        * request.
+        */
+       void (*preedit_cursor)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              int32_t index);
+       /**
+        * delete_surrounding_text - delete text
+        * @index: (none)
+        * @length: (none)
+        *
+        * 
+        *
+        * This request will be handled on text_input side as part of a
+        * directly following commit_string request.
+        */
+       void (*delete_surrounding_text)(struct wl_client *client,
+                                       struct wl_resource *resource,
+                                       int32_t index,
+                                       uint32_t length);
+       /**
+        * cursor_position - set cursor to a new position
+        * @index: (none)
+        * @anchor: (none)
+        *
+        * Sets the cursor and anchor to a new position. Index is the new
+        * cursor position in bytes (when >= 0 relative to the end of
+        * inserted text else relative to beginning of inserted text).
+        * Anchor is the new anchor position in bytes (when >= 0 relative
+        * to the end of inserted text, else relative to beginning of
+        * inserted text). When there should be no selected text anchor
+        * should be the same as index.
+        *
+        * This request will be handled on text_input side as part of a
+        * directly following commit_string request.
+        */
+       void (*cursor_position)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               int32_t index,
+                               int32_t anchor);
+       /**
+        * modifiers_map - (none)
+        * @map: (none)
+        */
+       void (*modifiers_map)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_array *map);
+       /**
+        * 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_surrounfing_text, etc. The key event
+        * follows the wl_keyboard key event convention. Sym is a XKB
+        * keysym, state a wl_keyboard key_state.
+        */
+       void (*keysym)(struct wl_client *client,
+                      struct wl_resource *resource,
+                      uint32_t serial,
+                      uint32_t time,
+                      uint32_t sym,
+                      uint32_t state,
+                      uint32_t modifiers);
+       /**
+        * grab_keyboard - grab hardware keyboard
+        * @keyboard: (none)
+        *
+        * Allows an input method to receive hardware keyboard input and
+        * process key events to generate text events (with pre-edit) over
+        * the wire. This allows input methods which compose multiple key
+        * events for inputting text like it is done for CJK languages.
+        */
+       void (*grab_keyboard)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t keyboard);
+       /**
+        * key - forward key event
+        * @serial: serial from wl_keyboard::key
+        * @time: time from wl_keyboard::key
+        * @key: key from wl_keyboard::key
+        * @state: state from wl_keyboard::key
+        *
+        * Should be used when filtering key events with grab_keyboard.
+        *
+        * When the wl_keyboard::key event is not processed by the input
+        * method itself and should be sent to the client instead, forward
+        * it with this request. The arguments should be the ones from the
+        * wl_keyboard::key event.
+        *
+        * For generating custom key events use the keysym request instead.
+        */
+       void (*key)(struct wl_client *client,
+                   struct wl_resource *resource,
+                   uint32_t serial,
+                   uint32_t time,
+                   uint32_t key,
+                   uint32_t state);
+       /**
+        * modifiers - forward modifiers event
+        * @serial: serial from wl_keyboard::modifiers
+        * @mods_depressed: mods_depressed from wl_keyboard::modifiers
+        * @mods_latched: mods_latched from wl_keyboard::modifiers
+        * @mods_locked: mods_locked from wl_keyboard::modifiers
+        * @group: group from wl_keyboard::modifiers
+        *
+        * Should be used when filtering key events with grab_keyboard.
+        *
+        * When the wl_keyboard::modifiers event should be also send to the
+        * client, forward it with this request. The arguments should be
+        * the ones from the wl_keyboard::modifiers event.
+        */
+       void (*modifiers)(struct wl_client *client,
+                         struct wl_resource *resource,
+                         uint32_t serial,
+                         uint32_t mods_depressed,
+                         uint32_t mods_latched,
+                         uint32_t mods_locked,
+                         uint32_t group);
+       /**
+        * language - (none)
+        * @serial: serial of the latest known text input state
+        * @language: (none)
+        */
+       void (*language)(struct wl_client *client,
+                        struct wl_resource *resource,
+                        uint32_t serial,
+                        const char *language);
+       /**
+        * text_direction - (none)
+        * @serial: serial of the latest known text input state
+        * @direction: (none)
+        */
+       void (*text_direction)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              uint32_t serial,
+                              uint32_t direction);
+};
+
+#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT       0
+#define WL_INPUT_METHOD_CONTEXT_RESET  1
+#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE   2
+#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION  3
+#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE   4
+#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE     5
+
+#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT_SINCE_VERSION 1
+#define WL_INPUT_METHOD_CONTEXT_RESET_SINCE_VERSION    1
+#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE_SINCE_VERSION     1
+#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION_SINCE_VERSION    1
+#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE_SINCE_VERSION     1
+#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE_SINCE_VERSION       1
+
+static inline void
+wl_input_method_context_send_surrounding_text(struct wl_resource *resource_, 
const char *text, uint32_t cursor, uint32_t anchor)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT, text, cursor, anchor);
+}
+
+static inline void
+wl_input_method_context_send_reset(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_RESET);
+}
+
+static inline void
+wl_input_method_context_send_content_type(struct wl_resource *resource_, 
uint32_t hint, uint32_t purpose)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE, 
hint, purpose);
+}
+
+static inline void
+wl_input_method_context_send_invoke_action(struct wl_resource *resource_, 
uint32_t button, uint32_t index)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION, button, index);
+}
+
+static inline void
+wl_input_method_context_send_commit_state(struct wl_resource *resource_, 
uint32_t serial)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_COMMIT_STATE, 
serial);
+}
+
+static inline void
+wl_input_method_context_send_preferred_language(struct wl_resource *resource_, 
const char *language)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE, language);
+}
+
+#define WL_INPUT_METHOD_ACTIVATE       0
+#define WL_INPUT_METHOD_DEACTIVATE     1
+
+#define WL_INPUT_METHOD_ACTIVATE_SINCE_VERSION 1
+#define WL_INPUT_METHOD_DEACTIVATE_SINCE_VERSION       1
+
+static inline void
+wl_input_method_send_activate(struct wl_resource *resource_, struct 
wl_resource *id)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_ACTIVATE, id);
+}
+
+static inline void
+wl_input_method_send_deactivate(struct wl_resource *resource_, struct 
wl_resource *context)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_DEACTIVATE, context);
+}
+
+/**
+ * wl_input_panel - interface for implementing keyboards
+ * @get_input_panel_surface: (none)
+ *
+ * Only one client can bind this interface at a time.
+ */
+struct wl_input_panel_interface {
+       /**
+        * get_input_panel_surface - (none)
+        * @id: (none)
+        * @surface: (none)
+        */
+       void (*get_input_panel_surface)(struct wl_client *client,
+                                       struct wl_resource *resource,
+                                       uint32_t id,
+                                       struct wl_resource *surface);
+};
+
+
+#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_interface {
+       /**
+        * set_toplevel - set the surface type as a keyboard
+        * @output: (none)
+        * @position: (none)
+        *
+        * A keyboard surface is only shown, when a text model is active
+        */
+       void (*set_toplevel)(struct wl_client *client,
+                            struct wl_resource *resource,
+                            struct wl_resource *output,
+                            uint32_t position);
+       /**
+        * set_overlay_panel - set the surface type as an overlay panel
+        *
+        * An overlay panel is shown near the input cursor above the
+        * application window when a text model is active.
+        */
+       void (*set_overlay_panel)(struct wl_client *client,
+                                 struct wl_resource *resource);
+};
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/modules/wl_desktop_shell/e_mod_input_panel.c 
b/src/modules/wl_desktop_shell/e_mod_input_panel.c
new file mode 100644
index 0000000..a8350ad
--- /dev/null
+++ b/src/modules/wl_desktop_shell/e_mod_input_panel.c
@@ -0,0 +1,336 @@
+#define E_COMP_WL
+#include "e.h"
+#include "e_mod_main.h"
+#include "e_input_method_protocol.h"
+
+typedef struct _E_Input_Panel E_Input_Panel;
+typedef struct _E_Input_Panel_Surface E_Input_Panel_Surface;
+
+struct _E_Input_Panel
+{
+   struct wl_resource *resource;
+   Eina_List *surfaces;
+};
+
+struct _E_Input_Panel_Surface
+{
+   E_Client *ec;
+
+   Eina_Bool panel;
+   Eina_Bool showing;
+};
+
+static E_Input_Panel input_panel;
+static Eina_List *handlers = NULL;
+static struct wl_global *input_panel_global = NULL;
+
+static void
+_e_input_panel_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED, 
uint32_t position EINA_UNUSED)
+{
+   E_Input_Panel_Surface *ips;
+
+   ips = wl_resource_get_user_data(resource);
+   ips->panel = EINA_FALSE;
+}
+
+static void
+_e_input_panel_surface_cb_overlay_panel_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource)
+{
+   E_Input_Panel_Surface *ips;
+
+   ips = wl_resource_get_user_data(resource);
+   ips->panel = EINA_TRUE;
+}
+
+static const struct wl_input_panel_surface_interface 
_e_input_panel_surface_implementation = {
+     _e_input_panel_surface_cb_toplevel_set,
+     _e_input_panel_surface_cb_overlay_panel_set
+};
+
+static void
+_e_input_panel_surface_resource_destroy(struct wl_resource *resource)
+{
+   E_Input_Panel_Surface *ips;
+   E_Client *ec;
+
+   ips = wl_resource_get_user_data(resource);
+   ec = ips->ec;
+   if (!e_object_is_del(E_OBJECT(ec)))
+     {
+        if (ec->comp_data->mapped)
+          {
+             if ((ec->comp_data->shell.surface) &&
+                 (ec->comp_data->shell.unmap))
+               ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
+          }
+        if (ec->parent)
+          {
+             ec->parent->transients =
+                eina_list_remove(ec->parent->transients, ec);
+          }
+        ec->comp_data->shell.surface = NULL;
+     }
+
+   input_panel.surfaces = eina_list_remove(input_panel.surfaces, ips);
+
+   free(ips);
+}
+
+static void
+_e_input_panel_position_set(E_Client *ec, int w, int h)
+{
+   int nx, ny;
+   int zx, zy, zw, zh;
+
+   e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
+
+   nx = zx + (zw - w) / 2;
+   ny = zy + zh - h;
+
+   e_client_util_move_without_frame(ec, nx, ny);
+}
+
+static void
+_e_input_panel_surface_visible_update(E_Input_Panel_Surface *ips)
+{
+   E_Client *ec;
+
+   ec = ips->ec;
+   if ((ips->showing) &&
+       (e_pixmap_usable_get(ec->pixmap)))
+     {
+        if (!ips->panel)
+          _e_input_panel_position_set(ec, ec->client.w, ec->client.h);
+
+        ec->visible = EINA_TRUE;
+        evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
+        evas_object_show(ec->frame);
+        e_comp_object_damage(ec->frame, ec->x, ec->y, ec->w, ec->h);
+     }
+   else
+     {
+        ec->visible = EINA_FALSE;
+        evas_object_hide(ec->frame);
+     }
+}
+
+static void
+_e_input_panel_surface_configure(struct wl_resource *resource, Evas_Coord x 
EINA_UNUSED, Evas_Coord y EINA_UNUSED, Evas_Coord w, Evas_Coord h)
+{
+   E_Input_Panel_Surface *ips;
+
+   ips = wl_resource_get_user_data(resource);
+
+   e_client_util_resize_without_frame(ips->ec, w, h);
+
+   if (ips->showing)
+     _e_input_panel_surface_visible_update(ips);
+}
+
+static void
+_e_input_panel_surface_map(struct wl_resource *resource)
+{
+   E_Input_Panel_Surface *ips;
+   E_Client *ec;
+
+   ips = wl_resource_get_user_data(resource);
+   ec = ips->ec;
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     return;
+
+   // NOTE: we need to set mapped, so that avoid showing evas_object and 
continue buffer's commit process.
+   if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap)))
+     ec->comp_data->mapped = EINA_TRUE;
+}
+
+static void
+_e_input_panel_surface_unmap(struct wl_resource *resource)
+{
+   E_Input_Panel_Surface *ips;
+   E_Client *ec;
+
+   ips = wl_resource_get_user_data(resource);
+   ec = ips->ec;
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     return;
+
+   if (ec->comp_data->mapped)
+     {
+        ec->visible = EINA_FALSE;
+        evas_object_hide(ec->frame);
+        ec->comp_data->mapped = EINA_FALSE;
+     }
+}
+
+static void
+_e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource 
*resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource)
+{
+   E_Client *ec;
+   E_Input_Panel_Surface *ips;
+   E_Comp_Client_Data *cd;
+
+   ec = wl_resource_get_user_data(surface_resource);
+   if (!ec)
+     {
+        wl_resource_post_error(surface_resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Client Set On Surface");
+        return;
+     }
+
+   cd = ec->comp_data;
+   if (!cd)
+     {
+        wl_resource_post_error(surface_resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Comp Data For Client");
+        return;
+     }
+
+   /* check for existing shell surface */
+   if (ec->comp_data->shell.surface)
+     {
+        wl_resource_post_error(surface_resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Client already has shell surface");
+        return;
+     }
+
+   ips = E_NEW(E_Input_Panel_Surface, 1);
+   if (!ips)
+     {
+        wl_client_post_no_memory(client);
+        return NULL;
+     }
+
+   cd->shell.surface = wl_resource_create(client,
+                                          &wl_input_panel_surface_interface,
+                                          1, id);
+   if (!cd->shell.surface)
+     {
+        wl_client_post_no_memory(client);
+        free(ips);
+        return NULL;
+     }
+
+   ips->ec = ec;
+
+   EC_CHANGED(ec);
+   if (!ec->new_client)
+     {
+        ec->new_client = EINA_TRUE;
+        e_comp->new_clients++;
+     }
+   if (ec->ignored)
+     e_client_unignore(ec);
+
+   /* set input panel client properties */
+   ec->borderless = EINA_TRUE;
+   ec->argb = EINA_TRUE;
+   ec->lock_border = EINA_TRUE;
+   ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
+   ec->netwm.state.skip_taskbar = EINA_TRUE;
+   ec->netwm.state.skip_pager = EINA_TRUE;
+   ec->no_shape_cut = EINA_TRUE;
+   ec->border_size = 0;
+   ec->netwm.type = E_WINDOW_TYPE_UTILITY;
+   ec->comp_data->set_win_type = EINA_TRUE;
+
+
+   cd->surface = surface_resource;
+   cd->shell.configure_send = NULL;
+   cd->shell.configure = _e_input_panel_surface_configure;
+   cd->shell.ping = NULL;
+   cd->shell.map = _e_input_panel_surface_map;
+   cd->shell.unmap = _e_input_panel_surface_unmap;
+
+
+   wl_resource_set_implementation(cd->shell.surface,
+                                  &_e_input_panel_surface_implementation,
+                                  ips, 
_e_input_panel_surface_resource_destroy);
+
+   input_panel.surfaces = eina_list_append(input_panel.surfaces, ips);
+}
+
+static const struct wl_input_panel_interface _e_input_panel_implementation = {
+     _e_input_panel_cb_surface_get
+};
+
+static void
+_e_input_panel_unbind(struct wl_resource *resource EINA_UNUSED)
+{
+   input_panel.resource = NULL;
+
+   E_FREE_FUNC(input_panel.surfaces, eina_list_free);
+}
+
+static void
+_e_input_panel_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t 
version EINA_UNUSED, uint32_t id)
+{
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &wl_input_panel_interface, 1, id);
+   if (!resource)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   if (input_panel.resource)
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "interface object already bound");
+        return;
+     }
+
+   input_panel.resource = resource;
+
+   wl_resource_set_implementation(resource,
+                                  &_e_input_panel_implementation,
+                                  NULL, _e_input_panel_unbind);
+}
+
+static Eina_Bool
+_e_input_panel_cb_visible_change(void *data EINA_UNUSED, int type EINA_UNUSED, 
void *event)
+{
+   E_Event_Text_Input_Panel_Visibility_Change *ev = event;
+   E_Input_Panel_Surface *ips;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(input_panel.surfaces, l, ips)
+     {
+        if (!ips->ec) continue;
+        ips->showing = ev->visible;
+        _e_input_panel_surface_visible_update(ips);
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+EINTERN Eina_Bool
+e_input_panel_init(void)
+{
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE,
+                         _e_input_panel_cb_visible_change, NULL);
+   // TODO: add signal handler - update input panel
+
+   input_panel_global = wl_global_create(e_comp->wl_comp_data->wl.disp,
+                                         &wl_input_panel_interface, 1,
+                                         NULL, _e_input_panel_bind);
+   if (!input_panel_global)
+     {
+        ERR("failed to create wl_global for input panel");
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_input_panel_shutdown(void)
+{
+   E_FREE_FUNC(input_panel_global, wl_global_destroy);
+   E_FREE_LIST(handlers, ecore_event_handler_del);
+}
diff --git a/src/modules/wl_desktop_shell/e_mod_main.c 
b/src/modules/wl_desktop_shell/e_mod_main.c
index e6415b8..4ce8f61 100644
--- a/src/modules/wl_desktop_shell/e_mod_main.c
+++ b/src/modules/wl_desktop_shell/e_mod_main.c
@@ -1,5 +1,6 @@
 #define E_COMP_WL
 #include "e.h"
+#include "e_mod_main.h"
 #include "e_desktop_shell_protocol.h"
 
 #define XDG_SERVER_VERSION 5
@@ -1379,11 +1380,21 @@ e_modapi_init(E_Module *m)
         return NULL;
      }
 
+#ifdef HAVE_WL_TEXT_INPUT
+   if (!e_input_panel_init())
+     {
+        ERR("Could not init input panel");
+        return NULL;
+     }
+#endif
+
    return m;
 }
 
 E_API int
 e_modapi_shutdown(E_Module *m EINA_UNUSED)
 {
+   e_input_panel_shutdown();
+
    return 1;
 }
diff --git a/src/modules/wl_desktop_shell/e_mod_main.h 
b/src/modules/wl_desktop_shell/e_mod_main.h
new file mode 100644
index 0000000..6a8a75c
--- /dev/null
+++ b/src/modules/wl_desktop_shell/e_mod_main.h
@@ -0,0 +1,7 @@
+#ifndef _E_MOD_MAIN_H
+#define _E_MOD_MAIN_H
+
+Eina_Bool   e_input_panel_init(void);
+void        e_input_panel_shutdown(void);
+
+#endif
diff --git a/src/modules/wl_text_input/e_mod_main.c 
b/src/modules/wl_text_input/e_mod_main.c
new file mode 100644
index 0000000..d0c5191
--- /dev/null
+++ b/src/modules/wl_text_input/e_mod_main.c
@@ -0,0 +1,933 @@
+#define E_COMP_WL
+#include "e.h"
+#include "text-protocol.h"
+#include "input-method-protocol.h"
+
+typedef struct _E_Text_Input E_Text_Input;
+typedef struct _E_Input_Method E_Input_Method;
+typedef struct _E_Input_Method_Context E_Input_Method_Context;
+
+struct _E_Text_Input
+{
+   struct wl_resource *resource;
+
+   E_Client *ec;
+   Eina_List *input_methods;
+   Eina_Rectangle *cursor_rect;
+   Eina_Bool input_panel_visible;
+};
+
+struct _E_Input_Method
+{
+   struct wl_resource *resource;
+
+   E_Text_Input *model;
+   E_Input_Method_Context *context;
+   Eina_List *handlers;
+};
+
+struct _E_Input_Method_Context
+{
+   struct wl_resource *resource;
+
+   E_Text_Input *model;
+   E_Input_Method *input_method;
+
+   struct
+   {
+      struct wl_resource *resource;
+      Eina_List *handlers;
+      Eina_Bool grabbed;
+   } kbd;
+};
+
+static struct wl_global *text_input_manager_global;
+
+static void
+_e_text_input_event_visible_change_send(Eina_Bool visible)
+{
+   E_Event_Text_Input_Panel_Visibility_Change *ev;
+
+   ev = E_NEW(E_Event_Text_Input_Panel_Visibility_Change, 1);
+   ev->visible = visible;
+   ecore_event_add(E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE, ev, NULL, NULL);
+}
+
+static void
+_e_text_input_method_context_key_send(E_Input_Method_Context *context, 
unsigned int keycode, unsigned int timestamp, enum wl_keyboard_key_state state)
+{
+   uint32_t serial, nk;
+
+   nk = keycode - 8;
+
+   serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
+   wl_keyboard_send_key(context->kbd.resource, serial, timestamp, nk, state);
+}
+
+static Eina_Bool
+_e_text_input_method_context_ecore_cb_key_down(void *data, int ev_type 
EINA_UNUSED, Ecore_Event_Key *ev)
+{
+   E_Input_Method_Context *context = data;
+
+   _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
+                                         WL_KEYBOARD_KEY_STATE_PRESSED);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_e_text_input_method_context_ecore_cb_key_up(void *data, int ev_type 
EINA_UNUSED, Ecore_Event_Key *ev)
+{
+   E_Input_Method_Context *context = data;
+
+   _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
+                                         WL_KEYBOARD_KEY_STATE_RELEASED);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_text_input_method_context_grab_set(E_Input_Method_Context *context, 
Eina_Bool set)
+{
+   if (set == context->kbd.grabbed)
+     return;
+
+   context->kbd.grabbed = set;
+
+   if (set)
+     {
+        E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_DOWN,
+                              _e_text_input_method_context_ecore_cb_key_down,
+                              context);
+        E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_UP,
+                              _e_text_input_method_context_ecore_cb_key_up,
+                              context);
+
+        e_comp_grab_input(0, 1);
+     }
+   else
+     {
+        E_FREE_LIST(context->kbd.handlers, ecore_event_handler_del);
+        e_comp_ungrab_input(0, 1);
+     }
+}
+
+static void
+_e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method 
*input_method)
+{
+   if (input_method->model == text_input)
+     {
+        if ((input_method->context) && (input_method->resource))
+          {
+             if (input_method->context)
+               _e_text_input_method_context_grab_set(input_method->context,
+                                                     EINA_FALSE);
+
+             wl_input_method_send_deactivate(input_method->resource,
+                                             input_method->context->resource);
+          }
+
+        input_method->model = NULL;
+        input_method->context = NULL;
+
+        text_input->input_methods = 
eina_list_remove(text_input->input_methods, input_method);
+
+        wl_text_input_send_leave(text_input->resource);
+     }
+}
+
+static void
+_e_text_input_method_context_cb_destroy(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_text_input_method_context_cb_string_commit(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_commit_string(context->model->resource,
+                                      serial, text);
+}
+
+static void
+_e_text_input_method_context_cb_preedit_string(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text, 
const char *commit)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_preedit_string(context->model->resource,
+                                       serial, text, commit);
+}
+
+static void
+_e_text_input_method_context_cb_preedit_styling(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, uint32_t index, uint32_t length, 
uint32_t style)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_preedit_styling(context->model->resource,
+                                        index, length, style);
+}
+
+static void
+_e_text_input_method_context_cb_preedit_cursor(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, int32_t cursor)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_preedit_cursor(context->model->resource,
+                                       cursor);
+}
+
+static void
+_e_text_input_method_context_cb_surrounding_text_delete(struct wl_client 
*client EINA_UNUSED, struct wl_resource *resource, int32_t index, uint32_t 
length)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_delete_surrounding_text(context->model->resource,
+                                                index, length);
+}
+
+static void
+_e_text_input_method_context_cb_cursor_position(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, int32_t index, int32_t anchor)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_cursor_position(context->model->resource,
+                                        index, anchor);
+}
+
+static void
+_e_text_input_method_context_cb_modifiers_map(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, struct wl_array *map)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_modifiers_map(context->model->resource, map);
+}
+
+static void
+_e_text_input_method_context_cb_keysym(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, uint32_t serial, uint32_t time, uint32_t sym, 
uint32_t state, uint32_t modifiers)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_keysym(context->model->resource,
+                               serial, time, sym, state, modifiers);
+}
+
+static void
+_e_text_input_method_context_keyboard_unbind(struct wl_resource *resource)
+{
+   E_Input_Method_Context *context;
+
+   context = wl_resource_get_user_data(resource);
+
+   _e_text_input_method_context_grab_set(context, EINA_FALSE);
+
+   context->kbd.resource = NULL;
+}
+
+static void
+_e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct 
wl_resource *resource, uint32_t id)
+{
+   E_Input_Method_Context *context;
+   struct wl_resource *new_resource;
+
+   DBG("Input Method Context - grab keyboard %d", 
wl_resource_get_id(resource));
+
+   context = wl_resource_get_user_data(resource);
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   new_resource = wl_resource_create(client, &wl_keyboard_interface, 1, id);
+   if (!new_resource)
+     {
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+
+   wl_resource_set_implementation(new_resource, NULL, context,
+                                  
_e_text_input_method_context_keyboard_unbind);
+
+   wl_keyboard_send_keymap(new_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+                           e_comp_wl->xkb.fd,
+                           e_comp_wl->xkb.size);
+
+   context->kbd.resource = new_resource;
+
+   _e_text_input_method_context_grab_set(context, EINA_TRUE);
+}
+
+static void
+_e_text_input_method_context_cb_key(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t 
time EINA_UNUSED, uint32_t key EINA_UNUSED, uint32_t state_w EINA_UNUSED)
+{
+   DBG("Input Method Context - key %d", wl_resource_get_id(resource));
+}
+
+static void
+_e_text_input_method_context_cb_modifiers(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, uint32_t serial 
EINA_UNUSED, uint32_t mods_depressed EINA_UNUSED, uint32_t mods_latched 
EINA_UNUSED, uint32_t mods_locked EINA_UNUSED, uint32_t group EINA_UNUSED)
+{
+   DBG("Input Method Context - modifiers %d", wl_resource_get_id(resource));
+}
+
+static void
+_e_text_input_method_context_cb_language(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, uint32_t serial, const char *language)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_language(context->model->resource,
+                                 serial, language);
+}
+
+static void
+_e_text_input_method_context_cb_text_direction(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t direction)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->model)
+     wl_text_input_send_text_direction(context->model->resource,
+                                       serial, direction);
+}
+
+static const struct wl_input_method_context_interface 
_e_text_input_method_context_implementation = {
+     _e_text_input_method_context_cb_destroy,
+     _e_text_input_method_context_cb_string_commit,
+     _e_text_input_method_context_cb_preedit_string,
+     _e_text_input_method_context_cb_preedit_styling,
+     _e_text_input_method_context_cb_preedit_cursor,
+     _e_text_input_method_context_cb_surrounding_text_delete,
+     _e_text_input_method_context_cb_cursor_position,
+     _e_text_input_method_context_cb_modifiers_map,
+     _e_text_input_method_context_cb_keysym,
+     _e_text_input_method_context_cb_keyboard_grab,
+     _e_text_input_method_context_cb_key,
+     _e_text_input_method_context_cb_modifiers,
+     _e_text_input_method_context_cb_language,
+     _e_text_input_method_context_cb_text_direction
+};
+
+static void
+_e_text_input_method_context_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+   if (!context)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method Context For Resource");
+        return;
+     }
+
+   if (context->kbd.resource)
+     wl_resource_destroy(context->kbd.resource);
+
+   free(context);
+}
+
+static Eina_Bool
+_e_text_input_cb_event_client_focus_in(void *data, int type EINA_UNUSED, void 
*event)
+{
+   E_Input_Method *input_method = data;
+   E_Event_Client *ev = event;
+
+   if (!input_method->model)
+     return ECORE_CALLBACK_RENEW;
+
+   if ((!ev->ec) ||
+       (input_method->model->ec != ev->ec))
+     {
+        _e_text_input_deactivate(input_method->model, input_method);
+        _e_text_input_event_visible_change_send(EINA_FALSE);
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_text_input_cb_activate(struct wl_client *client, struct wl_resource 
*resource, struct wl_resource *seat, struct wl_resource *surface)
+{
+   E_Text_Input *text_input;
+   E_Input_Method *input_method;
+   E_Text_Input *old;
+   E_Input_Method_Context *context;
+
+   text_input = wl_resource_get_user_data(resource);
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   input_method =
+      wl_resource_get_user_data(e_comp->wl_comp_data->seat.im.resource);
+   if (!input_method)
+     {
+        wl_resource_post_error(seat,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method For Seat");
+        return;
+     }
+
+   old = input_method->model;
+   if (old == text_input)
+     return;
+
+   if (old)
+     _e_text_input_deactivate(old, input_method);
+
+   input_method->model = text_input;
+   text_input->input_methods =
+      eina_list_append(text_input->input_methods, input_method);
+
+   text_input->ec = wl_resource_get_user_data(surface);
+
+   if (input_method->resource)
+     {
+        context = E_NEW(E_Input_Method_Context, 1);
+        if (!context)
+          {
+             wl_client_post_no_memory(client);
+             ERR("Could not allocate space for Input_Method_Context");
+             return;
+          }
+
+        context->resource =
+           wl_resource_create(wl_resource_get_client(input_method->resource),
+                              &wl_input_method_context_interface, 1, 0);
+        wl_resource_set_implementation(context->resource,
+                                       
&_e_text_input_method_context_implementation,
+                                       context, 
_e_text_input_method_context_cb_resource_destroy);
+
+        context->model = text_input;
+        context->input_method = input_method;
+        input_method->context = context;
+
+        wl_input_method_send_activate(input_method->resource, 
context->resource);
+     }
+
+   if (text_input->input_panel_visible)
+     _e_text_input_event_visible_change_send(EINA_TRUE);
+
+   wl_text_input_send_enter(text_input->resource, surface);
+}
+
+static void
+_e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource, struct wl_resource *seat)
+{
+   E_Text_Input *text_input;
+   E_Input_Method *input_method;
+
+   text_input = wl_resource_get_user_data(resource);
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   input_method =
+      wl_resource_get_user_data(e_comp->wl_comp_data->seat.im.resource);
+   if (!input_method)
+     {
+        wl_resource_post_error(seat,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method For Seat");
+        return;
+     }
+
+   _e_text_input_deactivate(text_input, input_method);
+   _e_text_input_event_visible_change_send(EINA_FALSE);
+
+}
+
+static void
+_e_text_input_cb_input_panel_show(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   text_input->input_panel_visible = 1;
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (input_method->model == text_input)
+          _e_text_input_event_visible_change_send(EINA_TRUE);
+     }
+}
+
+static void
+_e_text_input_cb_input_panel_hide(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   text_input->input_panel_visible = 0;
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (input_method->model == text_input)
+          _e_text_input_event_visible_change_send(EINA_FALSE);
+     }
+}
+
+static void
+_e_text_input_cb_reset(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        wl_input_method_context_send_reset(input_method->context->resource);
+     }
+}
+
+static void
+_e_text_input_cb_surrounding_text_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, const char *text, uint32_t cursor, uint32_t 
anchor)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        
wl_input_method_context_send_surrounding_text(input_method->context->resource,
+                                                      text, cursor, anchor);
+     }
+}
+
+static void
+_e_text_input_cb_content_type_set(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource, uint32_t hint, uint32_t purpose)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        
wl_input_method_context_send_content_type(input_method->context->resource,
+                                                  hint, purpose);
+     }
+}
+
+static void
+_e_text_input_cb_cursor_rectangle_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t 
height)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   text_input->cursor_rect = eina_rectangle_new(x, y, width, height);
+
+   // TODO: issue event update input_panel
+}
+
+static void
+_e_text_input_cb_preferred_language_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, const char *language)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        
wl_input_method_context_send_preferred_language(input_method->context->resource,
+                                                        language);
+     }
+}
+
+static void
+_e_text_input_cb_state_commit(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource, uint32_t serial)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        
wl_input_method_context_send_commit_state(input_method->context->resource, 
serial);
+     }
+}
+
+static void
+_e_text_input_cb_action_invoke(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource, uint32_t button, uint32_t index)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+   Eina_List *l;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
+     {
+        if (!input_method->context) continue;
+        
wl_input_method_context_send_invoke_action(input_method->context->resource,
+                                                   button, index);
+     }
+}
+
+static const struct wl_text_input_interface _e_text_input_implementation = {
+     _e_text_input_cb_activate,
+     _e_text_input_cb_deactivate,
+     _e_text_input_cb_input_panel_show,
+     _e_text_input_cb_input_panel_hide,
+     _e_text_input_cb_reset,
+     _e_text_input_cb_surrounding_text_set,
+     _e_text_input_cb_content_type_set,
+     _e_text_input_cb_cursor_rectangle_set,
+     _e_text_input_cb_preferred_language_set,
+     _e_text_input_cb_state_commit,
+     _e_text_input_cb_action_invoke
+};
+
+static void
+_e_text_input_cb_destroy(struct wl_resource *resource)
+{
+   E_Text_Input *text_input = wl_resource_get_user_data(resource);
+   E_Input_Method *input_method;
+
+   if (!text_input)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Text Input For Resource");
+        return;
+     }
+
+   EINA_LIST_FREE(text_input->input_methods, input_method)
+      _e_text_input_deactivate(text_input, input_method);
+
+   eina_rectangle_free(text_input->cursor_rect);
+   free(text_input);
+}
+
+static void
+_e_text_input_manager_cb_text_input_create(struct wl_client *client, struct 
wl_resource *resource EINA_UNUSED, uint32_t id)
+{
+   E_Text_Input *text_input;
+
+   text_input = E_NEW(E_Text_Input, 1);
+   if (!text_input)
+     {
+        wl_client_post_no_memory(client);
+        ERR("Could not allocate space for Text_Input");
+        return;
+     }
+
+   text_input->resource = wl_resource_create(client,
+                                             &wl_text_input_interface,
+                                             1, id);
+   if (!text_input->resource)
+     {
+        wl_client_post_no_memory(client);
+        ERR("could not create wl_resource for text input");
+        return;
+     }
+
+   wl_resource_set_implementation(text_input->resource,
+                                  &_e_text_input_implementation,
+                                  text_input, _e_text_input_cb_destroy);
+}
+
+static const struct wl_text_input_manager_interface 
_e_text_input_manager_implementation = {
+     _e_text_input_manager_cb_text_input_create
+};
+
+static void
+_e_text_cb_bind_text_input_manager(struct wl_client *client, void *data 
EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
+{
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &wl_text_input_manager_interface, 1, 
id);
+   if (!resource)
+     {
+        wl_client_post_no_memory(client);
+        ERR("could not create resource for text input manager");
+        return;
+     }
+
+   wl_resource_set_implementation(resource, 
&_e_text_input_manager_implementation, NULL, NULL);
+}
+
+static void
+_e_text_input_method_cb_unbind(struct wl_resource *resource)
+{
+   E_Input_Method *input_method = wl_resource_get_user_data(resource);
+
+   e_comp->wl_comp_data->seat.im.resource = NULL;
+
+   input_method = wl_resource_get_user_data(resource);
+   if (!input_method)
+     {
+        wl_resource_post_error(resource,
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "No Input Method For Resource");
+        return;
+     }
+
+   if (input_method->model)
+     _e_text_input_deactivate(input_method->model, input_method);
+
+   E_FREE_FUNC(input_method->handlers, ecore_event_handler_del);
+
+   input_method->resource = NULL;
+   input_method->context = NULL;
+
+   free(input_method);
+}
+
+static void
+_e_text_cb_bind_input_method(struct wl_client *client, void *data EINA_UNUSED, 
uint32_t version EINA_UNUSED, uint32_t id)
+{
+   E_Input_Method *input_method;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &wl_input_method_interface, 1, id);
+   if (!resource)
+     {
+        wl_client_post_no_memory(client);
+        ERR("could not create wl_resource for input method");
+        return;
+     }
+
+   if (e_comp->wl_comp_data->seat.im.resource)
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "interface object already bound");
+        wl_resource_destroy(resource);
+        return;
+     }
+
+   /* FIXME: we need to make sure the client attempting to bind
+      this interface really provides vkbd. */
+
+   input_method = E_NEW(E_Input_Method, 1);
+   if (!input_method)
+     {
+        wl_client_post_no_memory(client);
+        wl_resource_destroy(resource);
+        ERR("Could not allocate space for Input_Method");
+        return;
+     }
+
+   wl_resource_set_implementation(resource, NULL, input_method,
+                                  _e_text_input_method_cb_unbind);
+
+   input_method->model = NULL;
+   input_method->context = NULL;
+   input_method->resource = resource;
+
+   e_comp->wl_comp_data->seat.im.resource = resource;
+
+   E_LIST_HANDLER_APPEND(input_method->handlers, E_EVENT_CLIENT_FOCUS_IN,
+                         _e_text_input_cb_event_client_focus_in, input_method);
+}
+
+EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Text_Input" };
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+   // FIXME: create only one input method object per seat.
+   e_comp->wl_comp_data->seat.im.global =
+      wl_global_create(e_comp->wl_comp_data->wl.disp, 
&wl_input_method_interface, 1,
+                       NULL, _e_text_cb_bind_input_method);
+   if (!e_comp->wl_comp_data->seat.im.global)
+     {
+        ERR("failed to create wl_global for input method");
+        return NULL;
+     }
+
+   text_input_manager_global =
+      wl_global_create(e_comp->wl_comp_data->wl.disp, 
&wl_text_input_manager_interface, 1,
+                       NULL, _e_text_cb_bind_text_input_manager);
+   if (!text_input_manager_global)
+     {
+        ERR("failed to create wl_global for text input manager");
+        wl_global_destroy(e_comp->wl_comp_data->seat.im.global);
+        return NULL;
+     }
+
+   return m;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m EINA_UNUSED)
+{
+   E_FREE_FUNC(e_comp->wl_comp_data->seat.im.global, wl_global_destroy);
+   E_FREE_FUNC(text_input_manager_global, wl_global_destroy);
+
+   return 1;
+}
diff --git a/src/modules/wl_text_input/input-method-protocol.c 
b/src/modules/wl_text_input/input-method-protocol.c
new file mode 100644
index 0000000..feae244
--- /dev/null
+++ b/src/modules/wl_text_input/input-method-protocol.c
@@ -0,0 +1,114 @@
+/* 
+ * 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_input_method_context_interface;
+extern const struct wl_interface wl_input_panel_surface_interface;
+extern const struct wl_interface wl_keyboard_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_surface_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 },
+};
+
+WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = {
+       "wl_input_panel_surface", 1,
+       2, wl_input_panel_surface_requests,
+       0, NULL,
+};
+
diff --git a/src/modules/wl_text_input/input-method-protocol.h 
b/src/modules/wl_text_input/input-method-protocol.h
new file mode 100644
index 0000000..e4b8988
--- /dev/null
+++ b/src/modules/wl_text_input/input-method-protocol.h
@@ -0,0 +1,418 @@
+/* 
+ * 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_SERVER_PROTOCOL_H
+#define INPUT_METHOD_SERVER_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-server.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
+ * @destroy: (none)
+ * @commit_string: commit string
+ * @preedit_string: pre-edit string
+ * @preedit_styling: pre-edit styling
+ * @preedit_cursor: pre-edit cursor
+ * @delete_surrounding_text: delete text
+ * @cursor_position: set cursor to a new position
+ * @modifiers_map: (none)
+ * @keysym: keysym
+ * @grab_keyboard: grab hardware keyboard
+ * @key: forward key event
+ * @modifiers: forward modifiers event
+ * @language: (none)
+ * @text_direction: (none)
+ *
+ * Corresponds to a text model on input method side. An input method
+ * context is created on text model 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_interface {
+       /**
+        * destroy - (none)
+        */
+       void (*destroy)(struct wl_client *client,
+                       struct wl_resource *resource);
+       /**
+        * commit_string - commit string
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        *
+        * Send the commit string text for insertion to the application.
+        *
+        * 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 will be removed.
+        */
+       void (*commit_string)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t serial,
+                             const char *text);
+       /**
+        * preedit_string - pre-edit string
+        * @serial: serial of the latest known text input state
+        * @text: (none)
+        * @commit: (none)
+        *
+        * Send the pre-edit string text to the application text input.
+        *
+        * The commit text can be used to replace the preedit text on reset
+        * (for example on unfocus).
+        *
+        * Also previously sent preedit_style and preedit_cursor requests
+        * are processed bt the text_input also.
+        */
+       void (*preedit_string)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              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 in bytes from index relative to the beginning
+        * of the composing text (as byte offset). Multiple styles can be
+        * applied to a composing text.
+        *
+        * This request should be sent before sending preedit_string
+        * request.
+        */
+       void (*preedit_styling)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               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 negative no cursor should be displayed.
+        *
+        * This request should be sent before sending preedit_string
+        * request.
+        */
+       void (*preedit_cursor)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              int32_t index);
+       /**
+        * delete_surrounding_text - delete text
+        * @index: (none)
+        * @length: (none)
+        *
+        * 
+        *
+        * This request will be handled on text_input side as part of a
+        * directly following commit_string request.
+        */
+       void (*delete_surrounding_text)(struct wl_client *client,
+                                       struct wl_resource *resource,
+                                       int32_t index,
+                                       uint32_t length);
+       /**
+        * cursor_position - set cursor to a new position
+        * @index: (none)
+        * @anchor: (none)
+        *
+        * Sets the cursor and anchor to a new position. Index is the new
+        * cursor position in bytes (when >= 0 relative to the end of
+        * inserted text else relative to beginning of inserted text).
+        * Anchor is the new anchor position in bytes (when >= 0 relative
+        * to the end of inserted text, else relative to beginning of
+        * inserted text). When there should be no selected text anchor
+        * should be the same as index.
+        *
+        * This request will be handled on text_input side as part of a
+        * directly following commit_string request.
+        */
+       void (*cursor_position)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               int32_t index,
+                               int32_t anchor);
+       /**
+        * modifiers_map - (none)
+        * @map: (none)
+        */
+       void (*modifiers_map)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_array *map);
+       /**
+        * 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_surrounfing_text, etc. The key event
+        * follows the wl_keyboard key event convention. Sym is a XKB
+        * keysym, state a wl_keyboard key_state.
+        */
+       void (*keysym)(struct wl_client *client,
+                      struct wl_resource *resource,
+                      uint32_t serial,
+                      uint32_t time,
+                      uint32_t sym,
+                      uint32_t state,
+                      uint32_t modifiers);
+       /**
+        * grab_keyboard - grab hardware keyboard
+        * @keyboard: (none)
+        *
+        * Allows an input method to receive hardware keyboard input and
+        * process key events to generate text events (with pre-edit) over
+        * the wire. This allows input methods which compose multiple key
+        * events for inputting text like it is done for CJK languages.
+        */
+       void (*grab_keyboard)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t keyboard);
+       /**
+        * key - forward key event
+        * @serial: serial from wl_keyboard::key
+        * @time: time from wl_keyboard::key
+        * @key: key from wl_keyboard::key
+        * @state: state from wl_keyboard::key
+        *
+        * Should be used when filtering key events with grab_keyboard.
+        *
+        * When the wl_keyboard::key event is not processed by the input
+        * method itself and should be sent to the client instead, forward
+        * it with this request. The arguments should be the ones from the
+        * wl_keyboard::key event.
+        *
+        * For generating custom key events use the keysym request instead.
+        */
+       void (*key)(struct wl_client *client,
+                   struct wl_resource *resource,
+                   uint32_t serial,
+                   uint32_t time,
+                   uint32_t key,
+                   uint32_t state);
+       /**
+        * modifiers - forward modifiers event
+        * @serial: serial from wl_keyboard::modifiers
+        * @mods_depressed: mods_depressed from wl_keyboard::modifiers
+        * @mods_latched: mods_latched from wl_keyboard::modifiers
+        * @mods_locked: mods_locked from wl_keyboard::modifiers
+        * @group: group from wl_keyboard::modifiers
+        *
+        * Should be used when filtering key events with grab_keyboard.
+        *
+        * When the wl_keyboard::modifiers event should be also send to the
+        * client, forward it with this request. The arguments should be
+        * the ones from the wl_keyboard::modifiers event.
+        */
+       void (*modifiers)(struct wl_client *client,
+                         struct wl_resource *resource,
+                         uint32_t serial,
+                         uint32_t mods_depressed,
+                         uint32_t mods_latched,
+                         uint32_t mods_locked,
+                         uint32_t group);
+       /**
+        * language - (none)
+        * @serial: serial of the latest known text input state
+        * @language: (none)
+        */
+       void (*language)(struct wl_client *client,
+                        struct wl_resource *resource,
+                        uint32_t serial,
+                        const char *language);
+       /**
+        * text_direction - (none)
+        * @serial: serial of the latest known text input state
+        * @direction: (none)
+        */
+       void (*text_direction)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              uint32_t serial,
+                              uint32_t direction);
+};
+
+#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT       0
+#define WL_INPUT_METHOD_CONTEXT_RESET  1
+#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE   2
+#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION  3
+#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE   4
+#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE     5
+
+#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT_SINCE_VERSION 1
+#define WL_INPUT_METHOD_CONTEXT_RESET_SINCE_VERSION    1
+#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE_SINCE_VERSION     1
+#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION_SINCE_VERSION    1
+#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE_SINCE_VERSION     1
+#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE_SINCE_VERSION       1
+
+static inline void
+wl_input_method_context_send_surrounding_text(struct wl_resource *resource_, 
const char *text, uint32_t cursor, uint32_t anchor)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT, text, cursor, anchor);
+}
+
+static inline void
+wl_input_method_context_send_reset(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_RESET);
+}
+
+static inline void
+wl_input_method_context_send_content_type(struct wl_resource *resource_, 
uint32_t hint, uint32_t purpose)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE, 
hint, purpose);
+}
+
+static inline void
+wl_input_method_context_send_invoke_action(struct wl_resource *resource_, 
uint32_t button, uint32_t index)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION, button, index);
+}
+
+static inline void
+wl_input_method_context_send_commit_state(struct wl_resource *resource_, 
uint32_t serial)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_COMMIT_STATE, 
serial);
+}
+
+static inline void
+wl_input_method_context_send_preferred_language(struct wl_resource *resource_, 
const char *language)
+{
+       wl_resource_post_event(resource_, 
WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE, language);
+}
+
+#define WL_INPUT_METHOD_ACTIVATE       0
+#define WL_INPUT_METHOD_DEACTIVATE     1
+
+#define WL_INPUT_METHOD_ACTIVATE_SINCE_VERSION 1
+#define WL_INPUT_METHOD_DEACTIVATE_SINCE_VERSION       1
+
+static inline void
+wl_input_method_send_activate(struct wl_resource *resource_, struct 
wl_resource *id)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_ACTIVATE, id);
+}
+
+static inline void
+wl_input_method_send_deactivate(struct wl_resource *resource_, struct 
wl_resource *context)
+{
+       wl_resource_post_event(resource_, WL_INPUT_METHOD_DEACTIVATE, context);
+}
+
+/**
+ * wl_input_panel - interface for implementing keyboards
+ * @get_input_panel_surface: (none)
+ *
+ * Only one client can bind this interface at a time.
+ */
+struct wl_input_panel_interface {
+       /**
+        * get_input_panel_surface - (none)
+        * @id: (none)
+        * @surface: (none)
+        */
+       void (*get_input_panel_surface)(struct wl_client *client,
+                                       struct wl_resource *resource,
+                                       uint32_t id,
+                                       struct wl_resource *surface);
+};
+
+
+#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_interface {
+       /**
+        * set_toplevel - set the surface type as a keyboard
+        * @output: (none)
+        * @position: (none)
+        *
+        * A keyboard surface is only shown, when a text model is active
+        */
+       void (*set_toplevel)(struct wl_client *client,
+                            struct wl_resource *resource,
+                            struct wl_resource *output,
+                            uint32_t position);
+       /**
+        * set_overlay_panel - set the surface type as an overlay panel
+        *
+        * An overlay panel is shown near the input cursor above the
+        * application window when a text model is active.
+        */
+       void (*set_overlay_panel)(struct wl_client *client,
+                                 struct wl_resource *resource);
+};
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/modules/wl_text_input/text-protocol.c 
b/src/modules/wl_text_input/text-protocol.c
new file mode 100644
index 0000000..c5b3f07
--- /dev/null
+++ b/src/modules/wl_text_input/text-protocol.c
@@ -0,0 +1,92 @@
+/* 
+ * 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_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/wl_text_input/text-protocol.h 
b/src/modules/wl_text_input/text-protocol.h
new file mode 100644
index 0000000..21ab8e1
--- /dev/null
+++ b/src/modules/wl_text_input/text-protocol.h
@@ -0,0 +1,448 @@
+/* 
+ * 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_SERVER_PROTOCOL_H
+#define TEXT_SERVER_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.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
+ * @activate: request activation
+ * @deactivate: request deactivation
+ * @show_input_panel: show input panels
+ * @hide_input_panel: hide input panels
+ * @reset: reset
+ * @set_surrounding_text: sets the surrounding text
+ * @set_content_type: set content purpose and hint
+ * @set_cursor_rectangle: (none)
+ * @set_preferred_language: sets preferred language
+ * @commit_state: (none)
+ * @invoke_action: (none)
+ *
+ * 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_interface {
+       /**
+        * activate - request activation
+        * @seat: (none)
+        * @surface: (none)
+        *
+        * Requests the text-input object to be activated (typically when
+        * the text entry gets focus). The seat argument is a wl_seat which
+        * maintains the focus for this activation. The surface argument is
+        * a wl_surface assigned to the text-input object and tracked for
+        * focus lost. The enter event is emitted on successful activation.
+        */
+       void (*activate)(struct wl_client *client,
+                        struct wl_resource *resource,
+                        struct wl_resource *seat,
+                        struct wl_resource *surface);
+       /**
+        * deactivate - request deactivation
+        * @seat: (none)
+        *
+        * Requests the text-input object to be deactivated (typically
+        * when the text entry lost focus). The seat argument is a wl_seat
+        * which was used for activation.
+        */
+       void (*deactivate)(struct wl_client *client,
+                          struct wl_resource *resource,
+                          struct wl_resource *seat);
+       /**
+        * show_input_panel - show input panels
+        *
+        * Requests input panels (virtual keyboard) to show.
+        */
+       void (*show_input_panel)(struct wl_client *client,
+                                struct wl_resource *resource);
+       /**
+        * hide_input_panel - hide input panels
+        *
+        * Requests input panels (virtual keyboard) to hide.
+        */
+       void (*hide_input_panel)(struct wl_client *client,
+                                struct wl_resource *resource);
+       /**
+        * reset - reset
+        *
+        * Should be called by an editor widget when the input state
+        * should be reset, for example after the text was changed outside
+        * of the normal input method flow.
+        */
+       void (*reset)(struct wl_client *client,
+                     struct wl_resource *resource);
+       /**
+        * set_surrounding_text - sets the surrounding text
+        * @text: (none)
+        * @cursor: (none)
+        * @anchor: (none)
+        *
+        * Sets the plain surrounding text around the input position.
+        * Text is UTF-8 encoded. Cursor is the byte offset within the
+        * surrounding text. Anchor is the byte offset of the selection
+        * anchor within the surrounding text. If there is no selected text
+        * anchor is the same as cursor.
+        */
+       void (*set_surrounding_text)(struct wl_client *client,
+                                    struct wl_resource *resource,
+                                    const char *text,
+                                    uint32_t cursor,
+                                    uint32_t anchor);
+       /**
+        * set_content_type - set content purpose and hint
+        * @hint: (none)
+        * @purpose: (none)
+        *
+        * Sets the content purpose and content hint. While the purpose
+        * is the basic purpose of an input field, the hint flags allow to
+        * modify some of the behavior.
+        *
+        * When no content type is explicitly set, a normal content purpose
+        * with default hints (auto completion, auto correction, auto
+        * capitalization) should be assumed.
+        */
+       void (*set_content_type)(struct wl_client *client,
+                                struct wl_resource *resource,
+                                uint32_t hint,
+                                uint32_t purpose);
+       /**
+        * set_cursor_rectangle - (none)
+        * @x: (none)
+        * @y: (none)
+        * @width: (none)
+        * @height: (none)
+        */
+       void (*set_cursor_rectangle)(struct wl_client *client,
+                                    struct wl_resource *resource,
+                                    int32_t x,
+                                    int32_t y,
+                                    int32_t width,
+                                    int32_t height);
+       /**
+        * set_preferred_language - sets preferred language
+        * @language: (none)
+        *
+        * Sets a specific language. This allows for example a virtual
+        * keyboard to show a language specific layout. The "language"
+        * argument is a RFC-3066 format language tag.
+        *
+        * It could be used for example in a word processor to indicate
+        * language of currently edited document or in an instant message
+        * application which tracks languages of contacts.
+        */
+       void (*set_preferred_language)(struct wl_client *client,
+                                      struct wl_resource *resource,
+                                      const char *language);
+       /**
+        * commit_state - (none)
+        * @serial: used to identify the known state
+        */
+       void (*commit_state)(struct wl_client *client,
+                            struct wl_resource *resource,
+                            uint32_t serial);
+       /**
+        * invoke_action - (none)
+        * @button: (none)
+        * @index: (none)
+        */
+       void (*invoke_action)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t button,
+                             uint32_t index);
+};
+
+#define WL_TEXT_INPUT_ENTER    0
+#define WL_TEXT_INPUT_LEAVE    1
+#define WL_TEXT_INPUT_MODIFIERS_MAP    2
+#define WL_TEXT_INPUT_INPUT_PANEL_STATE        3
+#define WL_TEXT_INPUT_PREEDIT_STRING   4
+#define WL_TEXT_INPUT_PREEDIT_STYLING  5
+#define WL_TEXT_INPUT_PREEDIT_CURSOR   6
+#define WL_TEXT_INPUT_COMMIT_STRING    7
+#define WL_TEXT_INPUT_CURSOR_POSITION  8
+#define WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT  9
+#define WL_TEXT_INPUT_KEYSYM   10
+#define WL_TEXT_INPUT_LANGUAGE 11
+#define WL_TEXT_INPUT_TEXT_DIRECTION   12
+
+#define WL_TEXT_INPUT_ENTER_SINCE_VERSION      1
+#define WL_TEXT_INPUT_LEAVE_SINCE_VERSION      1
+#define WL_TEXT_INPUT_MODIFIERS_MAP_SINCE_VERSION      1
+#define WL_TEXT_INPUT_INPUT_PANEL_STATE_SINCE_VERSION  1
+#define WL_TEXT_INPUT_PREEDIT_STRING_SINCE_VERSION     1
+#define WL_TEXT_INPUT_PREEDIT_STYLING_SINCE_VERSION    1
+#define WL_TEXT_INPUT_PREEDIT_CURSOR_SINCE_VERSION     1
+#define WL_TEXT_INPUT_COMMIT_STRING_SINCE_VERSION      1
+#define WL_TEXT_INPUT_CURSOR_POSITION_SINCE_VERSION    1
+#define WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT_SINCE_VERSION    1
+#define WL_TEXT_INPUT_KEYSYM_SINCE_VERSION     1
+#define WL_TEXT_INPUT_LANGUAGE_SINCE_VERSION   1
+#define WL_TEXT_INPUT_TEXT_DIRECTION_SINCE_VERSION     1
+
+static inline void
+wl_text_input_send_enter(struct wl_resource *resource_, struct wl_resource 
*surface)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_ENTER, surface);
+}
+
+static inline void
+wl_text_input_send_leave(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_LEAVE);
+}
+
+static inline void
+wl_text_input_send_modifiers_map(struct wl_resource *resource_, struct 
wl_array *map)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_MODIFIERS_MAP, map);
+}
+
+static inline void
+wl_text_input_send_input_panel_state(struct wl_resource *resource_, uint32_t 
state)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_INPUT_PANEL_STATE, 
state);
+}
+
+static inline void
+wl_text_input_send_preedit_string(struct wl_resource *resource_, uint32_t 
serial, const char *text, const char *commit)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_STRING, serial, 
text, commit);
+}
+
+static inline void
+wl_text_input_send_preedit_styling(struct wl_resource *resource_, uint32_t 
index, uint32_t length, uint32_t style)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_STYLING, index, 
length, style);
+}
+
+static inline void
+wl_text_input_send_preedit_cursor(struct wl_resource *resource_, int32_t index)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_CURSOR, index);
+}
+
+static inline void
+wl_text_input_send_commit_string(struct wl_resource *resource_, uint32_t 
serial, const char *text)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_COMMIT_STRING, serial, 
text);
+}
+
+static inline void
+wl_text_input_send_cursor_position(struct wl_resource *resource_, int32_t 
index, int32_t anchor)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_CURSOR_POSITION, index, 
anchor);
+}
+
+static inline void
+wl_text_input_send_delete_surrounding_text(struct wl_resource *resource_, 
int32_t index, uint32_t length)
+{
+       wl_resource_post_event(resource_, 
WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT, index, length);
+}
+
+static inline void
+wl_text_input_send_keysym(struct wl_resource *resource_, uint32_t serial, 
uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_KEYSYM, serial, time, 
sym, state, modifiers);
+}
+
+static inline void
+wl_text_input_send_language(struct wl_resource *resource_, uint32_t serial, 
const char *language)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_LANGUAGE, serial, 
language);
+}
+
+static inline void
+wl_text_input_send_text_direction(struct wl_resource *resource_, uint32_t 
serial, uint32_t direction)
+{
+       wl_resource_post_event(resource_, WL_TEXT_INPUT_TEXT_DIRECTION, serial, 
direction);
+}
+
+/**
+ * wl_text_input_manager - text input manager
+ * @create_text_input: create text input
+ *
+ * A factory for text-input objects. This object is a global singleton.
+ */
+struct wl_text_input_manager_interface {
+       /**
+        * create_text_input - create text input
+        * @id: (none)
+        *
+        * Creates a new text-input object.
+        */
+       void (*create_text_input)(struct wl_client *client,
+                                 struct wl_resource *resource,
+                                 uint32_t id);
+};
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif

-- 


Reply via email to