Ui text: introduce this new text widget
authorDaniel Hirt <daniel.hirt@samsung.com>
Wed, 8 Jun 2016 15:37:35 +0000 (15:37 +0000)
committerTom Hacohen <tom@stosb.com>
Thu, 16 Jun 2016 18:15:20 +0000 (19:15 +0100)
This composite object utilizes the Efl.Canvas.Text, Efl.Canvas.Text.Cursor and
Efl.Ui.Interactive API to server as a proper replacement for the Elm Entry
widget.

@feature

data/elementary/themes/edc/elm/entry.edc
src/Makefile_Elementary.am
src/bin/elementary/Makefile.am
src/bin/elementary/test.c
src/bin/elementary/test_efl_ui_text.c [new file with mode: 0644]
src/bin/elementary/test_entry.c
src/lib/elementary/Elementary.h.in
src/lib/elementary/Makefile.am
src/lib/elementary/efl_ui_text.c [new file with mode: 0644]
src/lib/elementary/efl_ui_text.eo [new file with mode: 0644]
src/lib/elementary/elm_entry_common.h

index fcccb0c..7750ece 100644 (file)
@@ -1179,6 +1179,110 @@ group { name: "elm/entry/handler/end/default";
    }
 }
 
+group { name: "elm/efl_ui_text/base/default";
+   sounds {   
+      sample { name: "key-tap1" LOSSY 64;
+         source: "kbd-tap.wav";
+      }
+      sample { name: "key-tap2" LOSSY 64;
+         source: "kbd-tap2.wav";
+      }
+      sample { name: "key-tap3" LOSSY 64;
+         source: "kbd-tap3.wav";
+      }
+      sample { name: "key-tap4" LOSSY 64;
+         source: "kbd-tap4.wav";
+      }
+      sample { name: "key-tap5" LOSSY 64;
+         source: "kbd-tap5.wav";
+      }
+   }
+   
+//   data.item: "context_menu_orientation" "horizontal";
+   parts {
+      part { name: "elm.swallow.background"; type: SWALLOW;
+         description { state: "default" 0.0;
+            rel1.offset: 1 1;
+            rel2.offset: -2 -2;
+         }
+      }
+      part { name: "elm.text"; type: SWALLOW;
+         scale: 1;
+         entry_mode: EDITABLE;
+         select_mode: DEFAULT;
+//         select_mode: EXPLICIT;
+         cursor_mode: BEFORE;
+         multiline: 1;
+         source: "elm/entry/selection/default"; // selection under
+//         source2: "X"; // selection over
+//         source3: "X"; // cursor under
+         source4: "elm/entry/cursor/default"; // cursorover
+//         source5: "elm/entry/anchor/default"; // anchor under
+         source6: "elm/entry/anchor/default"; // anchor over
+         description { state: "default" 0.0;
+            /* we gotta use 0 0 here, because of scrolled entries */
+            fixed: 0 0;
+            rel1.offset: 2 2;
+            rel2.offset: -3 -3;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+         }
+      }
+   }
+   programs {
+      program {
+         signal: "load"; source: "";
+         action: FOCUS_SET;
+         target: "elm.text";
+      }
+      program {
+         signal: "elm,state,disabled"; source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "elm.text";
+      }
+      program {
+         signal: "elm,state,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.text";
+      }
+      #if 0
+      program {
+         signal: "elm,guide,disabled"; source: "elm";
+         action: STATE_SET "hidden" 0.0;
+         target: "elm.guide";
+      }
+      program {
+         signal: "elm,guide,enabled"; source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.guide";
+      }
+      #endif
+      program { name: "key-down";
+         signal: "entry,keydown"; source: "elm.text";
+         script {
+            new buf[32];
+            snprintf(buf, 31, "key-down%i", (rand() % 5) + 1);
+            run_program(get_program_id(buf));
+         }
+      }
+      program { name: "key-down1";
+         action: PLAY_SAMPLE "key-tap1" 1.0 INPUT;
+      }
+      program { name: "key-down2";
+         action: PLAY_SAMPLE "key-tap2" 1.0 INPUT;
+      }
+      program { name: "key-down3";
+         action: PLAY_SAMPLE "key-tap3" 1.0 INPUT;
+      }
+      program { name: "key-down4";
+         action: PLAY_SAMPLE "key-tap4" 1.0 INPUT;
+      }
+      program { name: "key-down5";
+         action: PLAY_SAMPLE "key-tap5" 1.0 INPUT;
+      }
+   }
+}
 ///////////////////////////////////////////////////////////////////////////////
 // emoticon images from:
 // Tanya - Latvia
index 49e1ea1..78890f7 100644 (file)
@@ -139,6 +139,7 @@ elm_public_eolian_files = \
        lib/elementary/elm_scroller_internal_part.eo \
        lib/elementary/elm_code_widget.eo \
     lib/elementary/efl_ui_text_interactive.eo \
+       lib/elementary/efl_ui_text.eo \
        $(NULL)
 
 # Private classes (not exposed or shipped)
@@ -693,6 +694,7 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_grid.c \
        lib/elementary/efl_ui_grid_static.c \
        lib/elementary/efl_ui_grid_private.h \
+       lib/elementary/efl_ui_text.c \
        $(NULL)
 
 
index 5acd88f..8f64a68 100644 (file)
@@ -135,6 +135,7 @@ test_win_plug.c \
 test_win_state.c \
 test_win_wm_rotation.c \
 test_win_dialog.c \
+test_efl_ui_text.c \
 test.h
 
 elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \
index 6dd37be..cfd0f30 100644 (file)
@@ -285,6 +285,7 @@ void test_code_mirror(void *data, Evas_Object *obj, void *event_info);
 void test_code_log(void *data, Evas_Object *obj, void *event_info);
 void test_code_diff(void *data, Evas_Object *obj, void *event_info);
 void test_code_diff_inline(void *data, Evas_Object *obj, void *event_info);
+void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info);
 
 Evas_Object *win, *tbx; // TODO: refactoring
 void *tt;
@@ -630,6 +631,7 @@ add_tests:
    ADD_TEST(NULL, "Entries", "Entry Anchor", test_entry_anchor);
    ADD_TEST(NULL, "Entries", "Entry Anchor2", test_entry_anchor2);
    ADD_TEST(NULL, "Entries", "Entry Emoticon", test_entry_emoticon);
+   ADD_TEST(NULL, "Entries", "Efl UI Text", test_efl_ui_text);
 
    //------------------------------//
    ADD_TEST(NULL, "Advanced Entries", "Code Entry Markup", test_code_welcome);
@@ -912,7 +914,6 @@ add_tests:
 
    ADD_TEST(NULL, "Widgets Disable/Enable", "Box", test_box_disable);
    ADD_TEST(NULL, "Widgets Disable/Enable", "Layout", test_layout_disable);
-
 #undef ADD_TEST
 
    if (autorun)
diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c
new file mode 100644 (file)
index 0000000..00964aa
--- /dev/null
@@ -0,0 +1,6 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#define EO_BETA_API
+#include <Elementary.h>
+
index 8ea2aa5..36e6a95 100644 (file)
@@ -2816,3 +2816,128 @@ test_entry_emoticon(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
    evas_object_resize(win, 400, 500);
    evas_object_show(win);
 }
+
+static void
+my_efl_ui_text_bt_5(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *en = data;
+   efl_ui_text_scrollable_set(en, !efl_ui_text_scrollable_get(en));
+}
+
+void
+test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *win, *bx, *bx2, *bx3, *bt, *en, *ck;
+
+   win = elm_win_util_standard_add("entry", "Entry");
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   en = eo_add(EFL_UI_TEXT_CLASS, win);
+   printf("Added Efl.Ui.Text object\n");
+//   elm_entry_line_wrap_set(en, ELM_WRAP_NONE);
+   efl_text_set(en, "Hello world!\nGoodbye world!\n"
+         "Another line\nAnd another line\nYet another line!");
+   evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, en);
+   evas_object_show(en);
+   elm_object_focus_set(en, EINA_TRUE);
+
+   bx2 = elm_box_add(win);
+   elm_box_horizontal_set(bx2, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Clr");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_1, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Prnt");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_2, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Sel");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_3, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Ins");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_4, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Scrl");
+   evas_object_smart_callback_add(bt, "clicked", my_efl_ui_text_bt_5, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Wr");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_6, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Edit");
+   evas_object_smart_callback_add(bt, "clicked", my_entry_bt_7, en);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx2, bt);
+   elm_object_focus_allow_set(bt, EINA_FALSE);
+   evas_object_show(bt);
+
+   bx3 = elm_box_add(win);
+   elm_box_horizontal_set(bx3, EINA_TRUE);
+   evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(bx3, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   ck = elm_check_add(win);
+   elm_object_text_set(ck, "Context Menu Disable");
+   evas_object_smart_callback_add(ck, "changed", changed_cb1, ck);
+   elm_box_pack_end(bx3, ck);
+   evas_object_show(ck);
+
+   ck = elm_check_add(win);
+   elm_object_text_set(ck, "Select Allow");
+//   elm_check_state_set(ck, elm_entry_select_allow_get(en));
+   evas_object_smart_callback_add(ck, "changed", select_allow_check_changed_cb, en);
+   elm_box_pack_end(bx3, ck);
+   evas_object_show(ck);
+
+   elm_box_pack_end(bx, bx3);
+   elm_box_pack_end(bx, bx2);
+   evas_object_show(bx3);
+   evas_object_show(bx2);
+
+   evas_object_show(win);
+}
index e9f1365..539d769 100644 (file)
@@ -277,6 +277,7 @@ EAPI extern Elm_Version *elm_version;
 # include <efl_ui_win.eo.h>
 # include <efl_ui_win_standard.eo.h>
 # include <efl_ui_text_interactive.eo.h>
+# include <efl_ui_text.eo.h>
 #endif
 
 /* include deprecated calls last of all */
index 13854bc..6abaa8d 100644 (file)
@@ -498,6 +498,8 @@ includesub_HEADERS = \
        elm_helper.h \
        efl_ui_box_private.h \
        efl_ui_grid_private.h \
+       efl_ui_text.h \
+       efl_ui_text.eo.h \
        $(NULL)
 
 includesubdir = $(includedir)/elementary-@VMAJ@/
@@ -630,6 +632,7 @@ libelementary_la_SOURCES = \
        efl_ui_box_layout.c \
        efl_ui_grid.c \
        efl_ui_grid_static.c \
+       efl_ui_text.c \
        $(NULL)
 
 libelementary_la_CFLAGS = @ELEMENTARY_CFLAGS@
diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c
new file mode 100644 (file)
index 0000000..3147cc1
--- /dev/null
@@ -0,0 +1,5647 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
+#define ELM_INTERFACE_ATSPI_TEXT_EDITABLE_PROTECTED
+#define ELM_LAYOUT_PROTECTED
+#define EO_BASE_BETA
+
+#include <Elementary.h>
+#include <Elementary_Cursor.h>
+#include "elm_priv.h"
+
+//#include "elm_entry_internal_part.eo.h"
+//#include "elm_part_helper.h"
+//
+#include "elm_interface_scrollable.h"
+#include "elm_widget_layout.h"
+#include "elm_entry_common.h"
+#include "elm_widget_entry.h"
+#include "efl_ui_text.eo.h"
+
+typedef struct _Efl_Ui_Text_Data        Efl_Ui_Text_Data;
+typedef struct _Efl_Ui_Text_Rectangle   Efl_Ui_Text_Rectangle;
+
+/**
+ * Base widget smart data extended with entry instance data.
+ */
+struct _Efl_Ui_Text_Data
+{
+   Evas_Object                          *hit_rect, *entry_edje, *scr_edje;
+
+   Evas_Object                          *hoversel;
+   Evas_Object                          *mgf_bg;
+   Evas_Object                          *mgf_clip;
+   Evas_Object                          *mgf_proxy;
+   Eo                                   *cursor;
+   Eo                                   *cursor_bidi;
+   Evas_Object                          *start_handler;
+   Evas_Object                          *end_handler;
+   Ecore_Job                            *deferred_recalc_job;
+   Ecore_Timer                          *longpress_timer;
+   Ecore_Timer                          *delay_write;
+   /* for deferred appending */
+   Ecore_Idler                          *append_text_idler;
+   char                                 *append_text_left;
+   int                                   append_text_position;
+   int                                   append_text_len;
+   /* Only for clipboard */
+   const char                           *cut_sel;
+   const char                           *text;
+   const char                           *file;
+   Elm_Text_Format                       format;
+   Evas_Coord                            last_w, ent_mw, ent_mh;
+   Evas_Coord                            downx, downy;
+   Evas_Coord                            ox, oy;
+   Eina_List                            *items; /** context menu item list */
+   Eina_List                            *item_providers;
+   Eina_List                            *markup_filters;
+   Ecore_Job                            *hov_deljob;
+   Mod_Api                              *api; // module api if supplied
+   int                                   cursor_pos;
+   Elm_Scroller_Policy                   policy_h, policy_v;
+   Elm_Wrap_Type                         line_wrap;
+   Elm_Input_Panel_Layout                input_panel_layout;
+   Elm_Autocapital_Type                  autocapital_type;
+   Elm_Input_Panel_Lang                  input_panel_lang;
+   Elm_Input_Panel_Return_Key_Type       input_panel_return_key_type;
+   Elm_Input_Hints                       input_hints;
+   Eo                                   *sel_handler_cursor;
+   Eina_List                            *rects;
+   void                                 *input_panel_imdata;
+   int                                   input_panel_imdata_len;
+   int                                   input_panel_layout_variation;
+   int                                   validators;
+   struct
+     {
+        Evas_Object *hover_parent; /**< hover parent object. entry is a hover parent object by default */
+        Evas_Object *pop; /**< hidden icon for hover target */
+        Evas_Object *hover; /**< hover object */
+        const char  *hover_style; /**< style of a hover object */
+     } anchor_hover;
+
+   Elm_Cnp_Mode                          cnp_mode;
+   Elm_Sel_Format                        drop_format;
+
+   Eina_Bool                             input_panel_return_key_disabled : 1;
+   Eina_Bool                             drag_selection_asked : 1;
+   Eina_Bool                             sel_handler_disabled : 1;
+   Eina_Bool                             start_handler_down : 1;
+   Eina_Bool                             start_handler_shown : 1;
+   Eina_Bool                             end_handler_down : 1;
+   Eina_Bool                             end_handler_shown : 1;
+   Eina_Bool                             input_panel_enable : 1;
+   Eina_Bool                             prediction_allow : 1;
+   Eina_Bool                             selection_asked : 1;
+   Eina_Bool                             auto_return_key : 1;
+   Eina_Bool                             have_selection : 1;
+   Eina_Bool                             deferred_cur : 1;
+   Eina_Bool                             context_menu : 1;
+   Eina_Bool                             long_pressed : 1;
+   Eina_Bool                             cur_changed : 1;
+   Eina_Bool                             single_line : 1;
+   Eina_Bool                             can_write : 1;
+   Eina_Bool                             auto_save : 1;
+   Eina_Bool                             password : 1;
+   Eina_Bool                             editable : 1;
+   Eina_Bool                             disabled : 1;
+   Eina_Bool                             h_bounce : 1;
+   Eina_Bool                             v_bounce : 1;
+   Eina_Bool                             has_text : 1;
+   Eina_Bool                             use_down : 1;
+   Eina_Bool                             sel_mode : 1;
+   Eina_Bool                             sel_allow : 1;
+   Eina_Bool                             changed : 1;
+   Eina_Bool                             scroll : 1;
+   Eina_Bool                             input_panel_show_on_demand : 1;
+};
+
+#define EFL_UI_TEXT_DATA_GET(o, sd) \
+  Efl_Ui_Text_Data * sd = eo_data_scope_get(o, EFL_UI_TEXT_CLASS)
+
+#define EFL_UI_TEXT_DATA_GET_OR_RETURN(o, ptr)         \
+  EFL_UI_TEXT_DATA_GET(o, ptr);                        \
+  if (EINA_UNLIKELY(!ptr))                           \
+    {                                                \
+       CRI("No widget data for object %p (%s)",      \
+           o, evas_object_type_get(o));              \
+       return;                                       \
+    }
+
+#define EFL_UI_TEXT_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+  EFL_UI_TEXT_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                            \
+    {                                                 \
+       CRI("No widget data for object %p (%s)",       \
+           o, evas_object_type_get(o));               \
+       return val;                                    \
+    }
+
+#define EFL_UI_TEXT_CHECK(obj)                              \
+  if (EINA_UNLIKELY(!eo_isa((obj), EFL_UI_TEXT_CLASS))) \
+    return
+
+struct _Efl_Ui_Text_Rectangle
+{
+   Eina_Rectangle          rect;
+   Evas_Object             *obj_bg, *obj;
+};
+
+#define MY_CLASS EFL_UI_TEXT_CLASS
+
+#define MY_CLASS_NAME "Efl_Ui_Text"
+#define MY_CLASS_NAME_LEGACY "efl ui text"
+
+#include "efl_ui_internal_text_interactive.h"
+
+/* Maximum chunk size to be inserted to the entry at once
+ * FIXME: This size is arbitrary, should probably choose a better size.
+ * Possibly also find a way to set it to a low value for weak computers,
+ * and to a big value for better computers. */
+#define EFL_UI_TEXT_CHUNK_SIZE 10000
+#define EFL_UI_TEXT_DELAY_WRITE_TIME 2.0
+
+#define ELM_PRIV_ENTRY_SIGNALS(cmd) \
+   cmd(SIG_ABORTED, "aborted", "") \
+   cmd(SIG_ACTIVATED, "activated", "") \
+   cmd(SIG_ANCHOR_CLICKED, "anchor,clicked", "") \
+   cmd(SIG_ANCHOR_DOWN, "anchor,down", "") \
+   cmd(SIG_ANCHOR_HOVER_OPENED, "anchor,hover,opened", "") \
+   cmd(SIG_ANCHOR_IN, "anchor,in", "") \
+   cmd(SIG_ANCHOR_OUT, "anchor,out", "") \
+   cmd(SIG_ANCHOR_UP, "anchor,up", "") \
+   cmd(SIG_CHANGED, "changed", "") \
+   cmd(SIG_CHANGED_USER, "changed,user", "") \
+   cmd(SIG_CLICKED, "clicked", "") \
+   cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
+   cmd(SIG_CLICKED_TRIPLE, "clicked,triple", "") \
+   cmd(SIG_CURSOR_CHANGED, "cursor,changed", "") \
+   cmd(SIG_CURSOR_CHANGED_MANUAL, "cursor,changed,manual", "") \
+   cmd(SIG_FOCUSED, "focused", "") \
+   cmd(SIG_UNFOCUSED, "unfocused", "") \
+   cmd(SIG_LONGPRESSED, "longpressed", "") \
+   cmd(SIG_MAX_LENGTH, "maxlength,reached", "") \
+   cmd(SIG_PREEDIT_CHANGED, "preedit,changed", "") \
+   cmd(SIG_PRESS, "press", "") \
+   cmd(SIG_REDO_REQUEST, "redo,request", "") \
+   cmd(SIG_SELECTION_CHANGED, "selection,changed", "") \
+   cmd(SIG_SELECTION_CLEARED, "selection,cleared", "") \
+   cmd(SIG_SELECTION_COPY, "selection,copy", "") \
+   cmd(SIG_SELECTION_CUT, "selection,cut", "") \
+   cmd(SIG_SELECTION_PASTE, "selection,paste", "") \
+   cmd(SIG_SELECTION_START, "selection,start", "") \
+   cmd(SIG_TEXT_SET_DONE, "text,set,done", "") \
+   cmd(SIG_THEME_CHANGED, "theme,changed", "") \
+   cmd(SIG_UNDO_REQUEST, "undo,request", "") \
+   cmd(SIG_REJECTED, "rejected", "")
+
+ELM_PRIV_ENTRY_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
+
+#define ENTRY_PASSWORD_MASK_CHARACTER 0x002A
+
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+   ELM_PRIV_ENTRY_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
+   {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
+   {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
+   {NULL, NULL}
+};
+#undef ELM_PRIV_ENTRY_SIGNALS
+
+static const Elm_Layout_Part_Alias_Description _content_aliases[] =
+{
+   {"icon", "elm.swallow.icon"},
+   {"end", "elm.swallow.end"},
+   {NULL, NULL}
+};
+
+static Eina_List *entries = NULL;
+
+struct _Mod_Api
+{
+   void (*obj_hook)(Evas_Object *obj);
+   void (*obj_unhook)(Evas_Object *obj);
+   void (*obj_longpress)(Evas_Object *obj);
+};
+
+static void _create_selection_handlers(Evas_Object *obj, Efl_Ui_Text_Data *sd);
+static void _magnifier_move(void *data);
+static void _update_decorations(Eo *obj);
+static void _create_text_cursors(Efl_Ui_Text_Data *sd);
+static Eina_Bool _efl_ui_text_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
+static Eina_Bool _efl_ui_text_selection_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
+static Eina_Bool _efl_ui_text_cursor_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
+static void _efl_ui_text_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
+static void _efl_ui_text_select_none(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd);
+static void _efl_ui_text_select_all(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd);
+static void _efl_ui_text_anchor_hover_end(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd);
+static void _efl_ui_text_anchor_hover_parent_set(Eo *obj, Efl_Ui_Text_Data *sd, Evas_Object *parent);
+static const char* _efl_ui_text_selection_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd);
+
+static Mod_Api *
+_module_find(Evas_Object *obj EINA_UNUSED)
+{
+   static Elm_Module *m = NULL;
+
+   if (m) goto ok;  // already found - just use
+   if (!(m = _elm_module_find_as("entry/api"))) return NULL;
+   // get module api
+   m->api = malloc(sizeof(Mod_Api));
+   if (!m->api) return NULL;
+
+   ((Mod_Api *)(m->api))->obj_hook = // called on creation
+     _elm_module_symbol_get(m, "obj_hook");
+   ((Mod_Api *)(m->api))->obj_unhook = // called on deletion
+     _elm_module_symbol_get(m, "obj_unhook");
+   ((Mod_Api *)(m->api))->obj_longpress = // called on long press menu
+     _elm_module_symbol_get(m, "obj_longpress");
+ok: // ok - return api
+   return m->api;
+}
+
+static char *
+_file_load(const char *file)
+{
+   Eina_File *f;
+   char *text = NULL;
+   void *tmp = NULL;
+
+   f = eina_file_open(file, EINA_FALSE);
+   if (!f) return NULL;
+
+   tmp = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+   if (!tmp) goto on_error;
+
+   text = malloc(eina_file_size_get(f) + 1);
+   if (!text) goto on_error;
+
+   memcpy(text, tmp, eina_file_size_get(f));
+   text[eina_file_size_get(f)] = 0;
+
+   if (eina_file_map_faulted(f, tmp))
+     {
+        ELM_SAFE_FREE(text, free);
+     }
+
+ on_error:
+   if (tmp) eina_file_map_free(f, tmp);
+   eina_file_close(f);
+
+   return text;
+}
+
+static char *
+_plain_load(const char *file)
+{
+#if 0
+   char *text;
+
+   text = _file_load(file);
+   if (text)
+     {
+        char *text2;
+
+        text2 = efl_ui_text_utf8_to_markup(text);
+        free(text);
+        return text2;
+     }
+
+   return NULL;
+#else
+   (void) file;
+   return NULL;
+#endif
+}
+
+static Eina_Bool
+_load_do(Evas_Object *obj)
+{
+   char *text;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (!sd->file)
+     {
+        elm_object_text_set(obj, "");
+        return EINA_TRUE;
+     }
+
+   switch (sd->format)
+     {
+      case ELM_TEXT_FORMAT_PLAIN_UTF8:
+        text = _plain_load(sd->file);
+        break;
+
+      case ELM_TEXT_FORMAT_MARKUP_UTF8:
+        text = _file_load(sd->file);
+        break;
+
+      default:
+        text = NULL;
+        break;
+     }
+
+   if (text)
+     {
+        elm_object_text_set(obj, text);
+        free(text);
+
+        return EINA_TRUE;
+     }
+   else
+     {
+        elm_object_text_set(obj, "");
+
+        return EINA_FALSE;
+     }
+}
+
+static void
+_utf8_markup_save(const char *file,
+                  const char *text)
+{
+   FILE *f;
+
+   if (!text)
+     {
+        ecore_file_unlink(file);
+        return;
+     }
+
+   f = fopen(file, "wb");
+   if (!f)
+     {
+        ERR("Failed to open %s for writing", file);
+        return;
+     }
+
+   if (fputs(text, f) == EOF)
+     ERR("Failed to write text to file %s", file);
+   fclose(f);
+}
+
+static void
+_utf8_plain_save(const char *file,
+                 const char *text)
+{
+#if 0
+   char *text2;
+
+   text2 = efl_ui_text_markup_to_utf8(text);
+   if (!text2)
+     return;
+
+   _utf8_markup_save(file, text2);
+   free(text2);
+#else
+   (void) file;
+   (void) text;
+#endif
+}
+
+static void
+_save_do(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (!sd->file) return;
+   switch (sd->format)
+     {
+      case ELM_TEXT_FORMAT_PLAIN_UTF8:
+        _utf8_plain_save(sd->file, elm_object_text_get(obj));
+        break;
+
+      case ELM_TEXT_FORMAT_MARKUP_UTF8:
+        _utf8_markup_save(sd->file, elm_object_text_get(obj));
+        break;
+
+      default:
+        break;
+     }
+}
+
+static Eina_Bool
+_delay_write(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   _save_do(data);
+   sd->delay_write = NULL;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_efl_ui_text_guide_update(Evas_Object *obj,
+                        Eina_Bool has_text)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if ((has_text) && (!sd->has_text))
+     edje_object_signal_emit(sd->entry_edje, "elm,guide,disabled", "elm");
+   else if ((!has_text) && (sd->has_text))
+     edje_object_signal_emit(sd->entry_edje, "elm,guide,enabled", "elm");
+
+   sd->has_text = has_text;
+}
+
+static void
+_validate(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   Eina_Bool res;
+   Elm_Validate_Content vc;
+   Eina_Strbuf *buf;
+
+   if (sd->validators == 0) return;
+
+   vc.text = edje_object_part_text_get(sd->entry_edje, "elm.text");
+   res = eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_VALIDATE, (void *)&vc);
+   buf = eina_strbuf_new();
+   eina_strbuf_append_printf(buf, "validation,%s,%s", vc.signal, res == EO_CALLBACK_STOP ? "fail" : "pass");
+   edje_object_signal_emit(sd->scr_edje, eina_strbuf_string_get(buf), "elm");
+   eina_tmpstr_del(vc.signal);
+   eina_strbuf_free(buf);
+}
+
+static void
+_filter_free(Elm_Entry_Markup_Filter *tf)
+{
+   if (tf->func == elm_entry_filter_limit_size)
+     {
+        Elm_Entry_Filter_Limit_Size *lim = tf->data;
+
+        free(lim);
+     }
+   else if (tf->func == elm_entry_filter_accept_set)
+     {
+        Elm_Entry_Filter_Accept_Set *as = tf->data;
+
+        if (as)
+          {
+             eina_stringshare_del(as->accepted);
+             eina_stringshare_del(as->rejected);
+
+             free(as);
+          }
+     }
+   free(tf);
+}
+
+static void
+_mirrored_set(Evas_Object *obj,
+              Eina_Bool rtl)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   edje_object_mirrored_set(sd->entry_edje, rtl);
+
+   if (sd->anchor_hover.hover)
+     elm_widget_mirrored_set(sd->anchor_hover.hover, rtl);
+}
+
+static void
+_hide_selection_handler(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (!sd->start_handler) return;
+
+   if (sd->start_handler_shown)
+     {
+        edje_object_signal_emit(sd->start_handler, "elm,handler,hide", "elm");
+        sd->start_handler_shown = EINA_FALSE;
+     }
+   if (sd->end_handler_shown)
+     {
+        edje_object_signal_emit(sd->end_handler, "elm,handler,hide", "elm");
+        sd->end_handler_shown = EINA_FALSE;
+     }
+}
+
+static Eina_Rectangle *
+_viewport_region_get(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   Eina_Rectangle *rect = eina_rectangle_new(0, 0, 0, 0);
+   Evas_Object *parent;
+
+   if (!rect) return NULL;
+   if (sd->scroll)
+     elm_interface_scrollable_content_viewport_geometry_get
+           (obj, &rect->x, &rect->y, &rect->w, &rect->h);
+   else
+     evas_object_geometry_get(sd->entry_edje, &rect->x, &rect->y, &rect->w, &rect->h);
+
+   parent = elm_widget_parent_get(obj);
+   while (parent)
+     {
+        if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
+          {
+             Eina_Rectangle r;
+             EINA_RECTANGLE_SET(&r, 0, 0, 0, 0);
+             evas_object_geometry_get(parent, &r.x, &r.y, &r.w, &r.h);
+             if (!eina_rectangle_intersection(rect, &r))
+               {
+                  rect->x = rect->y = rect->w = rect->h = 0;
+                  break;
+               }
+          }
+        parent = elm_widget_parent_get(parent);
+     }
+
+   return rect;
+}
+
+static void
+_update_selection_handler(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   Evas_Coord sx, sy, sh;
+   Evas_Coord ent_x, ent_y;
+   Evas_Coord ex, ey, eh;
+   int start_pos, end_pos, last_pos;
+
+   if (!sd->sel_handler_disabled)
+     {
+        Eina_Rectangle *rect;
+        Evas_Coord hx, hy;
+        Eina_Bool hidden = EINA_FALSE;
+
+        if (!sd->start_handler)
+          _create_selection_handlers(obj, sd);
+
+        rect = _viewport_region_get(obj);
+        start_pos = edje_object_part_text_cursor_pos_get
+           (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
+        end_pos = edje_object_part_text_cursor_pos_get
+           (sd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
+
+        evas_object_geometry_get(sd->entry_edje, &ent_x, &ent_y, NULL, NULL);
+        last_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
+                                                        EDJE_CURSOR_MAIN);
+        edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+                                             EDJE_CURSOR_MAIN, start_pos);
+        edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+                                                  &sx, &sy, NULL, &sh);
+        edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+                                             EDJE_CURSOR_MAIN, end_pos);
+        edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+                                                  &ex, &ey, NULL, &eh);
+        edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+                                             EDJE_CURSOR_MAIN, last_pos);
+        if (start_pos < end_pos)
+          {
+             hx = ent_x + sx;
+             hy = ent_y + sy + sh;
+             evas_object_move(sd->start_handler, hx, hy);
+          }
+        else
+          {
+             hx = ent_x + ex;
+             hy = ent_y + ey + eh;
+             evas_object_move(sd->start_handler, hx, hy);
+          }
+        if (!eina_rectangle_xcoord_inside(rect, hx) ||
+            !eina_rectangle_ycoord_inside(rect, hy))
+          {
+             hidden = EINA_TRUE;
+          }
+        if (!sd->start_handler_shown && !hidden)
+          {
+             edje_object_signal_emit(sd->start_handler,
+                                     "elm,handler,show", "elm");
+             sd->start_handler_shown = EINA_TRUE;
+          }
+        else if (sd->start_handler_shown && hidden)
+          {
+             edje_object_signal_emit(sd->start_handler,
+                                     "elm,handler,hide", "elm");
+             sd->start_handler_shown = EINA_FALSE;
+          }
+
+        hidden = EINA_FALSE;
+        if (start_pos < end_pos)
+          {
+             hx = ent_x + ex;
+             hy = ent_y + ey + eh;
+             evas_object_move(sd->end_handler, hx, hy);
+          }
+        else
+          {
+             hx = ent_x + sx;
+             hy = ent_y + sy + sh;
+             evas_object_move(sd->end_handler, hx, hy);
+          }
+        if (!eina_rectangle_xcoord_inside(rect, hx) ||
+            !eina_rectangle_ycoord_inside(rect, hy))
+          {
+             hidden = EINA_TRUE;
+          }
+        if (!sd->end_handler_shown && !hidden)
+          {
+             edje_object_signal_emit(sd->end_handler,
+                                     "elm,handler,show", "elm");
+             sd->end_handler_shown = EINA_TRUE;
+          }
+        else if (sd->end_handler_shown && hidden)
+          {
+             edje_object_signal_emit(sd->end_handler,
+                                     "elm,handler,hide", "elm");
+             sd->end_handler_shown = EINA_FALSE;
+          }
+        eina_rectangle_free(rect);
+     }
+   else
+     {
+        if (sd->start_handler_shown)
+          {
+             edje_object_signal_emit(sd->start_handler,
+                                     "elm,handler,hide", "elm");
+             sd->start_handler_shown = EINA_FALSE;
+          }
+        if (sd->end_handler_shown)
+          {
+             edje_object_signal_emit(sd->end_handler,
+                                     "elm,handler,hide", "elm");
+             sd->end_handler_shown = EINA_FALSE;
+          }
+     }
+}
+
+static const char *
+_efl_ui_text_theme_group_get(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->editable)
+     {
+        if (sd->password) return "base-password";
+        else
+          {
+             if (sd->single_line) return "base-single";
+             else
+               {
+                  switch (sd->line_wrap)
+                    {
+                     case ELM_WRAP_CHAR:
+                       return "base-charwrap";
+
+                     case ELM_WRAP_WORD:
+                       return "base";
+
+                     case ELM_WRAP_MIXED:
+                       return "base-mixedwrap";
+
+                     case ELM_WRAP_NONE:
+                     default:
+                       return "base-nowrap";
+                    }
+               }
+          }
+     }
+   else
+     {
+        if (sd->password) return "base-password";
+        else
+          {
+             if (sd->single_line) return "base-single-noedit";
+             else
+               {
+                  switch (sd->line_wrap)
+                    {
+                     case ELM_WRAP_CHAR:
+                       return "base-noedit-charwrap";
+
+                     case ELM_WRAP_WORD:
+                       return "base-noedit";
+
+                     case ELM_WRAP_MIXED:
+                       return "base-noedit-mixedwrap";
+
+                     case ELM_WRAP_NONE:
+                     default:
+                       return "base-nowrap-noedit";
+                    }
+               }
+          }
+     }
+}
+
+static void
+_edje_entry_user_insert(Evas_Object *obj, const char *data)
+{
+   if (!data) return;
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   sd->changed = EINA_TRUE;
+   edje_object_part_text_user_insert(sd->entry_edje, "elm.text", data);
+   elm_layout_sizing_eval(obj);
+}
+
+static Eina_Bool
+_selection_data_cb(void *data EINA_UNUSED,
+                   Evas_Object *obj,
+                   Elm_Selection_Data *sel_data)
+{
+   char *buf;
+
+   if (!sel_data->data) return EINA_FALSE;
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   buf = malloc(sel_data->len + 1);
+   if (!buf)
+     {
+        ERR("Failed to allocate memory, obj: %p", obj);
+        return EINA_FALSE;
+     }
+   memcpy(buf, sel_data->data, sel_data->len);
+   buf[sel_data->len] = '\0';
+
+   if ((sel_data->format & ELM_SEL_FORMAT_IMAGE) &&
+       (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE))
+     {
+        char *entry_tag;
+        int len;
+        static const char *tag_string =
+           "<item absize=240x180 href=file://%s></item>";
+
+        len = strlen(tag_string) + strlen(buf);
+        entry_tag = alloca(len + 1);
+        snprintf(entry_tag, len + 1, tag_string, buf);
+        _edje_entry_user_insert(obj, entry_tag);
+     }
+   else if (sel_data->format & ELM_SEL_FORMAT_MARKUP)
+     {
+        _edje_entry_user_insert(obj, buf);
+     }
+   else
+     {
+        Efl_Canvas_Text_Cursor *cur, *start, *end;
+        efl_ui_text_interactive_selection_cursors_get(obj, &start, &end);
+        if (!efl_canvas_text_cursor_equal(start, end))
+          {
+             efl_canvas_text_range_delete(obj, start, end);
+          }
+        cur = efl_canvas_text_cursor_get(obj);
+        efl_canvas_text_cursor_text_insert(cur, buf);
+     }
+   free(buf);
+
+   return EINA_TRUE;
+}
+
+static void
+_dnd_enter_cb(void *data EINA_UNUSED,
+              Evas_Object *obj)
+{
+   elm_object_focus_set(obj, EINA_TRUE);
+}
+
+static void
+_dnd_leave_cb(void *data EINA_UNUSED,
+              Evas_Object *obj)
+{
+   if (_elm_config->desktop_entry)
+     elm_object_focus_set(obj, EINA_FALSE);
+}
+
+static void
+_dnd_pos_cb(void *data EINA_UNUSED,
+            Evas_Object *obj,
+            Evas_Coord x,
+            Evas_Coord y,
+            Elm_Xdnd_Action action EINA_UNUSED)
+{
+   int pos;
+   Evas_Coord ox, oy, ex, ey;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+   evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+   x = x + ox - ex;
+   y = y + oy - ey;
+
+   edje_object_part_text_cursor_coord_set
+      (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, x, y);
+   pos = edje_object_part_text_cursor_pos_get
+      (sd->entry_edje, "elm.text", EDJE_CURSOR_USER);
+   edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+                                        EDJE_CURSOR_MAIN, pos);
+}
+
+static Eina_Bool
+_dnd_drop_cb(void *data EINA_UNUSED,
+              Evas_Object *obj,
+              Elm_Selection_Data *drop)
+{
+   Eina_Bool rv;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   rv = edje_object_part_text_cursor_coord_set
+       (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, drop->x, drop->y);
+
+   if (!rv) WRN("Warning: Failed to position cursor: paste anyway");
+
+   rv = _selection_data_cb(NULL, obj, drop);
+
+   return rv;
+}
+
+static Elm_Sel_Format
+_get_drop_format(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if ((sd->editable) && (!sd->single_line) && (!sd->password) && (!sd->disabled))
+     return ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE;
+   return ELM_SEL_FORMAT_MARKUP;
+}
+
+/* we can't reuse layout's here, because it's on entry_edje only */
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_disable(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   elm_drop_target_del(obj, sd->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+   if (elm_object_disabled_get(obj))
+     {
+        edje_object_signal_emit(sd->entry_edje, "elm,state,disabled", "elm");
+        if (sd->scroll)
+          {
+             edje_object_signal_emit(sd->scr_edje, "elm,state,disabled", "elm");
+             elm_interface_scrollable_freeze_set(obj, EINA_TRUE);
+          }
+        sd->disabled = EINA_TRUE;
+     }
+   else
+     {
+        edje_object_signal_emit(sd->entry_edje, "elm,state,enabled", "elm");
+        if (sd->scroll)
+          {
+             edje_object_signal_emit(sd->scr_edje, "elm,state,enabled", "elm");
+             elm_interface_scrollable_freeze_set(obj, EINA_FALSE);
+          }
+        sd->disabled = EINA_FALSE;
+        sd->drop_format = _get_drop_format(obj);
+        elm_drop_target_add(obj, sd->drop_format,
+                            _dnd_enter_cb, NULL,
+                            _dnd_leave_cb, NULL,
+                            _dnd_pos_cb, NULL,
+                            _dnd_drop_cb, NULL);
+     }
+
+   return EINA_TRUE;
+}
+
+/* It gets the background object from from_edje object and
+ * sets the background object to to_edje object.
+ * The background object has to be moved to proper Edje object
+ * when scrollable status is changed. */
+static void
+_efl_ui_text_background_switch(Evas_Object *from_edje, Evas_Object *to_edje)
+{
+   Evas_Object *bg_obj;
+
+   if (!from_edje || !to_edje) return;
+
+   if (edje_object_part_exists(from_edje, "elm.swallow.background") &&
+       edje_object_part_exists(to_edje, "elm.swallow.background") &&
+       !edje_object_part_swallow_get(to_edje, "elm.swallow.background"))
+     {
+        bg_obj = edje_object_part_swallow_get(from_edje, "elm.swallow.background");
+
+        if (bg_obj)
+          {
+             edje_object_part_unswallow(from_edje, bg_obj);
+             edje_object_part_swallow(to_edje, "elm.swallow.background", bg_obj);
+          }
+     }
+}
+
+/* we can't issue the layout's theming code here, cause it assumes an
+ * unique edje object, always */
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_theme_apply(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   const char *str;
+   const char *t;
+   const char *style = elm_widget_style_get(obj);
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
+
+   Eina_Bool int_ret = EINA_FALSE;
+   int_ret = elm_obj_widget_theme_apply(eo_super(obj, MY_CLASS));
+   if (!int_ret) return EINA_FALSE;
+
+   evas_event_freeze(evas_object_evas_get(obj));
+
+   edje_object_mirrored_set
+     (wd->resize_obj, elm_widget_mirrored_get(obj));
+
+   edje_object_scale_set
+     (wd->resize_obj,
+     elm_widget_scale_get(obj) * elm_config_scale_get());
+
+   _mirrored_set(obj, elm_widget_mirrored_get(obj));
+
+   t = eina_stringshare_add(elm_object_text_get(obj));
+
+   elm_widget_theme_object_set
+     (obj, sd->entry_edje, "efl_ui_text", _efl_ui_text_theme_group_get(obj), style);
+
+   if (sd->sel_allow && _elm_config->desktop_entry)
+     edje_obj_part_text_select_allow_set
+        (sd->entry_edje, "elm.text", EINA_TRUE);
+   else
+     edje_obj_part_text_select_allow_set
+        (sd->entry_edje, "elm.text", EINA_FALSE);
+
+   elm_object_text_set(obj, t);
+   eina_stringshare_del(t);
+
+   if (elm_widget_disabled_get(obj))
+     edje_object_signal_emit(sd->entry_edje, "elm,state,disabled", "elm");
+
+   edje_object_part_text_input_panel_layout_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Panel_Layout)sd->input_panel_layout);
+   edje_object_part_text_input_panel_layout_variation_set
+     (sd->entry_edje, "elm.text", sd->input_panel_layout_variation);
+   edje_object_part_text_autocapital_type_set
+     (sd->entry_edje, "elm.text", (Edje_Text_Autocapital_Type)sd->autocapital_type);
+   edje_object_part_text_prediction_allow_set
+     (sd->entry_edje, "elm.text", sd->prediction_allow);
+   edje_object_part_text_input_hint_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Hints)sd->input_hints);
+   edje_object_part_text_input_panel_enabled_set
+     (sd->entry_edje, "elm.text", sd->input_panel_enable);
+   edje_object_part_text_input_panel_imdata_set
+     (sd->entry_edje, "elm.text", sd->input_panel_imdata,
+     sd->input_panel_imdata_len);
+   edje_object_part_text_input_panel_return_key_type_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Panel_Return_Key_Type)sd->input_panel_return_key_type);
+   edje_object_part_text_input_panel_return_key_disabled_set
+     (sd->entry_edje, "elm.text", sd->input_panel_return_key_disabled);
+   edje_object_part_text_input_panel_show_on_demand_set
+     (sd->entry_edje, "elm.text", sd->input_panel_show_on_demand);
+
+   // elm_entry_cursor_pos_set -> cursor,changed -> widget_show_region_set
+   // -> smart_objects_calculate will call all smart calculate functions,
+   // and one of them can delete elm_entry.
+   evas_object_ref(obj);
+
+   if (elm_widget_focus_get(obj))
+     {
+        edje_object_signal_emit(sd->entry_edje, "elm,action,focus", "elm");
+        if (sd->scroll)
+          edje_object_signal_emit(sd->scr_edje, "elm,action,focus", "elm");
+     }
+
+   edje_object_message_signal_process(sd->entry_edje);
+
+   Evas_Object* clip = evas_object_clip_get(sd->entry_edje);
+   evas_object_clip_set(sd->hit_rect, clip);
+
+   if (sd->scroll)
+     {
+        Eina_Bool ok = EINA_FALSE;
+
+        elm_interface_scrollable_mirrored_set(obj, elm_widget_mirrored_get(obj));
+
+        if (sd->single_line)
+          ok = elm_widget_theme_object_set
+          (obj, sd->scr_edje, "scroller", "entry_single", style);
+        if (!ok)
+          elm_widget_theme_object_set
+          (obj, sd->scr_edje, "scroller", "entry", style);
+
+        _efl_ui_text_background_switch(sd->entry_edje, sd->scr_edje);
+
+        str = edje_object_data_get(sd->scr_edje, "focus_highlight");
+     }
+   else
+     {
+        _efl_ui_text_background_switch(sd->scr_edje, sd->entry_edje);
+
+        str = edje_object_data_get(sd->entry_edje, "focus_highlight");
+     }
+
+   if ((str) && (!strcmp(str, "on")))
+     elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
+   else
+     elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
+
+   if (sd->start_handler)
+     {
+        elm_widget_theme_object_set(obj, sd->start_handler,
+                                    "entry", "handler/start", style);
+        elm_widget_theme_object_set(obj, sd->end_handler,
+                                    "entry", "handler/end", style);
+     }
+
+   sd->changed = EINA_TRUE;
+   elm_layout_sizing_eval(obj);
+
+   sd->has_text = !sd->has_text;
+   _efl_ui_text_guide_update(obj, !sd->has_text);
+   evas_event_thaw(evas_object_evas_get(obj));
+   evas_event_thaw_eval(evas_object_evas_get(obj));
+
+   eo_event_callback_call(obj, ELM_LAYOUT_EVENT_THEME_CHANGED, NULL);
+
+   evas_object_unref(obj);
+
+   return EINA_TRUE;
+}
+
+static void
+_cursor_geometry_recalc(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_CURSOR_CHANGED, NULL);
+
+   if (!sd->deferred_recalc_job)
+     {
+        Evas_Coord cx, cy, cw, ch;
+
+        edje_object_part_text_cursor_geometry_get
+          (sd->entry_edje, "elm.text", &cx, &cy, &cw, &ch);
+        if (sd->cur_changed)
+          {
+             sd->cur_changed = EINA_FALSE;
+             elm_widget_show_region_set(obj, cx, cy, cw, ch, EINA_FALSE);
+          }
+     }
+   else
+     sd->deferred_cur = EINA_TRUE;
+}
+
+static void
+_deferred_recalc_job(void *data)
+{
+   Evas_Coord minh = -1, resw = -1, resh = -1, minw = -1, fw = 0, fh = 0;
+   Eo *sw;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->deferred_recalc_job = NULL;
+
+   sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+   evas_object_geometry_get(sd->entry_edje, NULL, NULL, &resw, &resh);
+   //FIXME: will not work with complex themes.
+   evas_object_resize(sw, resw, resh);
+   efl_canvas_text_size_formatted_get(sw, &minw, &minh);
+   evas_object_size_hint_min_set(sw, minw, minh);
+   edje_object_size_min_restricted_calc(sd->entry_edje, &minw, &minh, resw, 0);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+   /* This is a hack to workaround the way min size hints are treated.
+    * If the minimum width is smaller than the restricted width, it
+    * means the minimum doesn't matter. */
+   if (minw <= resw)
+     {
+        Evas_Coord ominw = -1;
+
+        evas_object_size_hint_min_get(data, &ominw, NULL);
+        minw = ominw;
+     }
+
+   sd->ent_mw = minw;
+   sd->ent_mh = minh;
+
+   elm_coords_finger_size_adjust(1, &fw, 1, &fh);
+   if (sd->scroll)
+     {
+        Evas_Coord vmw = 0, vmh = 0;
+
+        edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
+        if (sd->single_line)
+          {
+             evas_object_size_hint_min_set(data, vmw, minh + vmh);
+             evas_object_size_hint_max_set(data, -1, minh + vmh);
+          }
+        else
+          {
+             evas_object_size_hint_min_set(data, vmw, vmh);
+             evas_object_size_hint_max_set(data, -1, -1);
+          }
+     }
+   else
+     {
+        if (sd->single_line)
+          {
+             evas_object_size_hint_min_set(data, minw, minh);
+             evas_object_size_hint_max_set(data, -1, minh);
+          }
+        else
+          {
+             evas_object_size_hint_min_set(data, fw, minh);
+             evas_object_size_hint_max_set(data, -1, -1);
+          }
+     }
+
+   if (sd->deferred_cur)
+     {
+        Evas_Coord cx, cy, cw, ch;
+
+        edje_object_part_text_cursor_geometry_get
+          (sd->entry_edje, "elm.text", &cx, &cy, &cw, &ch);
+        if (sd->cur_changed)
+          {
+             sd->cur_changed = EINA_FALSE;
+             elm_widget_show_region_set(data, cx, cy, cw, ch, EINA_FALSE);
+          }
+     }
+   _update_decorations(data);
+}
+
+EOLIAN static void
+_efl_ui_text_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   Evas_Coord minw = -1, minh = -1;
+   Evas_Coord resw, resh;
+
+   evas_object_geometry_get(obj, NULL, NULL, &resw, &resh);
+
+   if (sd->line_wrap)
+     {
+        if ((resw == sd->last_w) && (!sd->changed))
+          {
+             if (sd->scroll)
+               {
+                  Evas_Coord vw = 0, vh = 0, w = 0, h = 0;
+
+                  elm_interface_scrollable_content_viewport_geometry_get
+                        (obj, NULL, NULL, &vw, &vh);
+
+                  w = sd->ent_mw;
+                  h = sd->ent_mh;
+                  if (vw > sd->ent_mw) w = vw;
+                  if (vh > sd->ent_mh) h = vh;
+                  evas_object_resize(sd->entry_edje, w, h);
+
+                  return;
+               }
+
+             return;
+          }
+
+        evas_event_freeze(evas_object_evas_get(obj));
+        sd->changed = EINA_FALSE;
+        sd->last_w = resw;
+        if (sd->scroll)
+          {
+             Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
+
+             evas_object_resize(sd->scr_edje, resw, resh);
+             edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
+             elm_interface_scrollable_content_viewport_geometry_get
+                   (obj, NULL, NULL, &vw, &vh);
+             edje_object_size_min_restricted_calc
+               (sd->entry_edje, &minw, &minh, vw, 0);
+             elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+             /* This is a hack to workaround the way min size hints
+              * are treated.  If the minimum width is smaller than the
+              * restricted width, it means the minimum doesn't
+              * matter. */
+             if (minw <= vw)
+               {
+                  Evas_Coord ominw = -1;
+
+                  evas_object_size_hint_min_get(sd->entry_edje, &ominw, NULL);
+                  minw = ominw;
+               }
+             sd->ent_mw = minw;
+             sd->ent_mh = minh;
+
+             if ((minw > 0) && (vw < minw)) vw = minw;
+             if (minh > vh) vh = minh;
+
+             if (sd->single_line) h = vmh + minh;
+             else h = vmh;
+
+             evas_object_resize(sd->entry_edje, vw, vh);
+             evas_object_size_hint_min_set(obj, w, h);
+
+             if (sd->single_line)
+               evas_object_size_hint_max_set(obj, -1, h);
+             else
+               evas_object_size_hint_max_set(obj, -1, -1);
+          }
+        else
+          {
+             ecore_job_del(sd->deferred_recalc_job);
+             sd->deferred_recalc_job =
+               ecore_job_add(_deferred_recalc_job, obj);
+          }
+
+        evas_event_thaw(evas_object_evas_get(obj));
+        evas_event_thaw_eval(evas_object_evas_get(obj));
+     }
+   else
+     {
+        if (!sd->changed) return;
+        evas_event_freeze(evas_object_evas_get(obj));
+        sd->changed = EINA_FALSE;
+        sd->last_w = resw;
+        if (sd->scroll)
+          {
+             Evas_Coord vw = 0, vh = 0, vmw = 0, vmh = 0, w = -1, h = -1;
+
+             edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
+             sd->ent_mw = minw;
+             sd->ent_mh = minh;
+             elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+             elm_interface_scrollable_content_viewport_geometry_get
+                   (obj, NULL, NULL, &vw, &vh);
+
+             if (minw > vw) vw = minw;
+             if (minh > vh) vh = minh;
+
+             evas_object_resize(sd->entry_edje, vw, vh);
+             edje_object_size_min_calc(sd->scr_edje, &vmw, &vmh);
+             if (sd->single_line) h = vmh + minh;
+             else h = vmh;
+
+             evas_object_size_hint_min_set(obj, w, h);
+             if (sd->single_line)
+               evas_object_size_hint_max_set(obj, -1, h);
+             else
+               evas_object_size_hint_max_set(obj, -1, -1);
+          }
+        else
+          {
+             edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
+             sd->ent_mw = minw;
+             sd->ent_mh = minh;
+             elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+             evas_object_size_hint_min_set(obj, minw, minh);
+
+             if (sd->single_line)
+               evas_object_size_hint_max_set(obj, -1, minh);
+             else
+               evas_object_size_hint_max_set(obj, -1, -1);
+          }
+        evas_event_thaw(evas_object_evas_get(obj));
+        evas_event_thaw_eval(evas_object_evas_get(obj));
+     }
+
+   _cursor_geometry_recalc(obj);
+}
+
+static void
+_return_key_enabled_check(Evas_Object *obj)
+{
+   Eina_Bool return_key_disabled = EINA_FALSE;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (!sd->auto_return_key) return;
+
+   if (efl_canvas_text_is_empty_get(obj) == EINA_TRUE)
+     return_key_disabled = EINA_TRUE;
+
+   efl_ui_text_input_panel_return_key_disabled_set(obj, return_key_disabled);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_on_focus(Eo *obj, Efl_Ui_Text_Data *sd, Elm_Object_Item *item EINA_UNUSED)
+{
+   Evas_Object *top;
+   Eina_Bool top_is_win = EINA_FALSE;
+
+   if (!sd->editable) return EINA_FALSE;
+
+   top = elm_widget_top_get(obj);
+   if (top && eo_isa(top, ELM_WIN_CLASS))
+     top_is_win = EINA_TRUE;
+
+   if (elm_widget_focus_get(obj))
+     {
+#if 0
+        evas_object_focus_set(sd->entry_edje, EINA_TRUE);
+#else
+        Eo *sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+        evas_object_focus_set(sw, EINA_TRUE);
+
+#endif
+        edje_object_signal_emit(sd->entry_edje, "elm,action,focus", "elm");
+        if (sd->scroll)
+          edje_object_signal_emit(sd->scr_edje, "elm,action,focus", "elm");
+
+        if (top && top_is_win && sd->input_panel_enable && !sd->input_panel_show_on_demand &&
+            !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
+          elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
+        eo_event_callback_call(obj, ELM_WIDGET_EVENT_FOCUSED, NULL);
+        if (_elm_config->atspi_mode)
+          elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
+        _return_key_enabled_check(obj);
+        _validate(obj);
+     }
+   else
+     {
+        edje_object_signal_emit(sd->entry_edje, "elm,action,unfocus", "elm");
+        if (sd->scroll)
+          edje_object_signal_emit(sd->scr_edje, "elm,action,unfocus", "elm");
+#if 0
+        evas_object_focus_set(sd->entry_edje, EINA_FALSE);
+#else
+        Eo *sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+        evas_object_focus_set(sw, EINA_FALSE);
+#endif
+        if (top && top_is_win && sd->input_panel_enable &&
+            !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
+          elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
+        eo_event_callback_call(obj, ELM_WIDGET_EVENT_UNFOCUSED, NULL);
+        if (_elm_config->atspi_mode)
+          elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
+
+        if (_elm_config->selection_clear_enable)
+          {
+             if ((sd->have_selection) && (!sd->hoversel))
+               {
+                  sd->sel_mode = EINA_FALSE;
+                  elm_widget_scroll_hold_pop(obj);
+                  edje_object_part_text_select_allow_set(sd->entry_edje, "elm.text", EINA_FALSE);
+                  edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+                  edje_object_part_text_select_none(sd->entry_edje, "elm.text");
+               }
+          }
+        edje_object_signal_emit(sd->scr_edje, "validation,default", "elm");
+     }
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_on_focus_region(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   Evas_Coord edje_x, edje_y, elm_x, elm_y;
+
+   edje_object_part_text_cursor_geometry_get
+     (sd->entry_edje, "elm.text", x, y, w, h);
+
+   if (sd->single_line)
+     {
+        evas_object_geometry_get(sd->entry_edje, NULL, NULL, NULL, h);
+        if (y) *y = 0;
+     }
+
+   evas_object_geometry_get(sd->entry_edje, &edje_x, &edje_y, NULL, NULL);
+
+   evas_object_geometry_get(obj, &elm_x, &elm_y, NULL, NULL);
+
+   if (x) *x += edje_x - elm_x;
+   if (y) *y += edje_y - elm_y;
+
+   return EINA_TRUE;
+}
+
+static void
+_show_region_hook(void *data EINA_UNUSED,
+                  Evas_Object *obj)
+{
+   Evas_Coord x, y, w, h;
+
+   elm_widget_show_region_get(obj, &x, &y, &w, &h);
+
+   elm_interface_scrollable_content_region_show(obj, x, y, w, h);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_sub_object_del(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Evas_Object *sobj)
+{
+   Eina_Bool ret = EINA_FALSE;
+   /* unfortunately entry doesn't follow the signal pattern
+    * elm,state,icon,{visible,hidden}, so we have to replicate this
+    * smart function */
+   if (sobj == elm_layout_content_get(obj, "elm.swallow.icon"))
+     {
+        elm_layout_signal_emit(obj, "elm,action,hide,icon", "elm");
+     }
+   else if (sobj == elm_layout_content_get(obj, "elm.swallow.end"))
+     {
+        elm_layout_signal_emit(obj, "elm,action,hide,end", "elm");
+     }
+
+   ret = elm_obj_widget_sub_object_del(eo_super(obj, MY_CLASS), sobj);
+   if (!ret) return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static void
+_hoversel_position(Evas_Object *obj)
+{
+   Evas_Coord cx, cy, cw, ch, x, y, mw, mh, w, h;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   cx = cy = 0;
+   cw = ch = 1;
+   evas_object_geometry_get(sd->entry_edje, &x, &y, &w, &h);
+   if (sd->use_down)
+     {
+        cx = sd->downx - x;
+        cy = sd->downy - y;
+        cw = 1;
+        ch = 1;
+     }
+   else
+     edje_object_part_text_cursor_geometry_get
+       (sd->entry_edje, "elm.text", &cx, &cy, &cw, &ch);
+
+   evas_object_size_hint_min_get(sd->hoversel, &mw, &mh);
+   if (cx + mw > w)
+     cx = w - mw;
+   if (cy + mh > h)
+     cy = h - mh;
+   evas_object_move(sd->hoversel, x + cx, y + cy);
+   evas_object_resize(sd->hoversel, mw, mh);
+}
+
+static void
+_hover_del_job(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   ELM_SAFE_FREE(sd->hoversel, evas_object_del);
+   sd->hov_deljob = NULL;
+}
+
+static Eina_Bool
+_hover_dismissed_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->use_down = 0;
+   if (sd->hoversel) evas_object_hide(sd->hoversel);
+   if (sd->sel_mode)
+     {
+        if (!_elm_config->desktop_entry)
+          {
+             if (!sd->password)
+               edje_object_part_text_select_allow_set
+                 (sd->entry_edje, "elm.text", EINA_TRUE);
+          }
+     }
+   elm_widget_scroll_freeze_pop(data);
+   ecore_job_del(sd->hov_deljob);
+   sd->hov_deljob = ecore_job_add(_hover_del_job, data);
+
+   return EINA_TRUE;
+}
+
+static void
+_hover_selected_cb(void *data,
+                   Evas_Object *obj EINA_UNUSED,
+                   void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (!sd->sel_allow) return;
+
+   sd->sel_mode = EINA_TRUE;
+   edje_object_part_text_select_none(sd->entry_edje, "elm.text");
+
+   if (!_elm_config->desktop_entry)
+     {
+        if (!sd->password)
+          edje_object_part_text_select_allow_set
+            (sd->entry_edje, "elm.text", EINA_TRUE);
+     }
+   edje_object_signal_emit(sd->entry_edje, "elm,state,select,on", "elm");
+
+   if (!_elm_config->desktop_entry)
+     elm_widget_scroll_hold_push(data);
+}
+
+static char *
+_item_tags_remove(const char *str)
+{
+   char *ret;
+   Eina_Strbuf *buf;
+
+   if (!str)
+     return NULL;
+
+   buf = eina_strbuf_new();
+   if (!buf)
+     return NULL;
+
+   if (!eina_strbuf_append(buf, str))
+     {
+        eina_strbuf_free(buf);
+        return NULL;
+     }
+
+   while (EINA_TRUE)
+     {
+        const char *temp = eina_strbuf_string_get(buf);
+        char *start_tag = NULL;
+        char *end_tag = NULL;
+        size_t sindex;
+        size_t eindex;
+
+        start_tag = strstr(temp, "<item");
+        if (!start_tag)
+          start_tag = strstr(temp, "</item");
+        if (start_tag)
+          end_tag = strstr(start_tag, ">");
+        else
+          break;
+        if (!end_tag || start_tag > end_tag)
+          break;
+
+        sindex = start_tag - temp;
+        eindex = end_tag - temp + 1;
+        if (!eina_strbuf_remove(buf, sindex, eindex))
+          break;
+     }
+
+   ret = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+
+   return ret;
+}
+
+void
+_efl_ui_text_entry_paste(Evas_Object *obj,
+                       const char *entry)
+{
+   char *str = NULL;
+
+   if (!entry) return;
+
+   EFL_UI_TEXT_CHECK(obj);
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->cnp_mode == ELM_CNP_MODE_NO_IMAGE)
+     {
+        str = _item_tags_remove(entry);
+        if (!str) str = strdup(entry);
+     }
+   else
+     str = strdup(entry);
+   if (!str) str = (char *)entry;
+
+   _edje_entry_user_insert(obj, str);
+
+   if (str != entry) free(str);
+}
+
+static void
+_paste_cb(Eo *obj)
+{
+   Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   eo_event_callback_call
+     (obj, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_PASTE, NULL);
+
+   sd->selection_asked = EINA_TRUE;
+
+   if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
+     formats = ELM_SEL_FORMAT_TEXT;
+   else if (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
+     formats |= ELM_SEL_FORMAT_IMAGE;
+
+   elm_cnp_selection_get
+     (obj, ELM_SEL_TYPE_CLIPBOARD, formats, _selection_data_cb, NULL);
+}
+
+static void
+_hoversel_item_paste_cb(void *data,
+          Evas_Object *obj EINA_UNUSED,
+          void *event_info EINA_UNUSED)
+{
+   _paste_cb(data);
+}
+
+static void
+_selection_clear(void *data, Elm_Sel_Type selection)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (!sd->have_selection) return;
+   if ((selection == ELM_SEL_TYPE_CLIPBOARD) ||
+       (selection == ELM_SEL_TYPE_PRIMARY))
+     {
+        _efl_ui_text_select_none(data, sd);
+     }
+}
+
+static void
+_selection_store(Elm_Sel_Type seltype,
+                 Evas_Object *obj)
+{
+   char *sel;
+   Efl_Canvas_Text_Cursor *start, *end;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   efl_ui_text_interactive_selection_cursors_get(obj, &start, &end);
+   sel = efl_canvas_text_range_text_get(obj, start, end);
+
+   if ((!sel) || (!sel[0])) return;  /* avoid deleting our own selection */
+
+   elm_cnp_selection_set
+     (obj, seltype, sd->cnp_mode, sel, strlen(sel));
+   elm_cnp_selection_loss_callback_set(obj, seltype, _selection_clear, obj);
+   if (seltype == ELM_SEL_TYPE_CLIPBOARD)
+     eina_stringshare_replace(&sd->cut_sel, sel);
+
+   free(sel);
+}
+
+static void
+_cut_cb(Eo *obj)
+{
+   Efl_Canvas_Text_Cursor *start, *end;
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   eo_event_callback_call
+     (obj, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_CUT, NULL);
+   /* Store it */
+   sd->sel_mode = EINA_FALSE;
+   if (!_elm_config->desktop_entry)
+     edje_object_part_text_select_allow_set
+       (sd->entry_edje, "elm.text", EINA_FALSE);
+   edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+
+   if (!_elm_config->desktop_entry)
+     elm_widget_scroll_hold_pop(obj);
+
+   _selection_store(ELM_SEL_TYPE_CLIPBOARD, obj);
+   efl_ui_text_interactive_selection_cursors_get(obj, &start, &end);
+   efl_canvas_text_range_delete(obj, start, end);
+}
+
+static void
+_hoversel_item_cut_cb(void *data,
+        Evas_Object *obj EINA_UNUSED,
+        void *event_info EINA_UNUSED)
+{
+   _cut_cb(data);
+}
+
+static void
+_copy_cb(Eo *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   eo_event_callback_call
+     (obj, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_COPY, NULL);
+   sd->sel_mode = EINA_FALSE;
+   if (!_elm_config->desktop_entry)
+     {
+        edje_object_part_text_select_allow_set
+          (sd->entry_edje, "elm.text", EINA_FALSE);
+        edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+        elm_widget_scroll_hold_pop(obj);
+     }
+   _selection_store(ELM_SEL_TYPE_CLIPBOARD, obj);
+}
+
+static void
+_hoversel_item_copy_cb(void *data,
+         Evas_Object *obj EINA_UNUSED,
+         void *event_info EINA_UNUSED)
+{
+   _copy_cb(data);
+}
+
+static void
+_hover_cancel_cb(void *data,
+                 Evas_Object *obj EINA_UNUSED,
+                 void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->sel_mode = EINA_FALSE;
+   if (!_elm_config->desktop_entry)
+     edje_object_part_text_select_allow_set
+       (sd->entry_edje, "elm.text", EINA_FALSE);
+   edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+   if (!_elm_config->desktop_entry)
+     elm_widget_scroll_hold_pop(data);
+   edje_object_part_text_select_none(sd->entry_edje, "elm.text");
+}
+
+static void
+_hover_item_clicked_cb(void *data,
+                       Evas_Object *obj EINA_UNUSED,
+                       void *event_info EINA_UNUSED)
+{
+   Elm_Entry_Context_Menu_Item *it = data;
+   if (!it) return;
+
+   if (it->func) it->func(it->data, it->obj, it);
+}
+
+static void
+_menu_call(Evas_Object *obj)
+{
+   Evas_Object *top;
+   const Eina_List *l;
+   const Elm_Entry_Context_Menu_Item *it;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->anchor_hover.hover) return;
+
+   eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_CONTEXT_OPEN, NULL);
+
+   if ((sd->api) && (sd->api->obj_longpress))
+     {
+        sd->api->obj_longpress(obj);
+     }
+   else if (sd->context_menu)
+     {
+        const char *context_menu_orientation;
+        Eina_Bool ownersel;
+
+        ownersel = elm_selection_selection_has_owner(obj);
+        if (!sd->items)
+          {
+             /* prevent stupid blank hoversel */
+             if (sd->have_selection && sd->password) return;
+             if (_elm_config->desktop_entry && (!sd->have_selection) && ((!sd->editable) || (!ownersel)))
+               return;
+          }
+        if (sd->hoversel) evas_object_del(sd->hoversel);
+        else elm_widget_scroll_freeze_push(obj);
+
+        sd->hoversel = elm_hoversel_add(obj);
+        context_menu_orientation = edje_object_data_get
+            (sd->entry_edje, "context_menu_orientation");
+
+        if ((context_menu_orientation) &&
+            (!strcmp(context_menu_orientation, "horizontal")))
+          elm_hoversel_horizontal_set(sd->hoversel, EINA_TRUE);
+
+        elm_object_style_set(sd->hoversel, "entry");
+        elm_widget_sub_object_add(obj, sd->hoversel);
+        elm_object_text_set(sd->hoversel, "Text");
+        top = elm_widget_top_get(obj);
+
+        if (top) elm_hoversel_hover_parent_set(sd->hoversel, top);
+
+        eo_event_callback_add
+          (sd->hoversel, ELM_HOVERSEL_EVENT_DISMISSED, _hover_dismissed_cb, obj);
+        if (sd->have_selection)
+          {
+             if (!sd->password)
+               {
+                  elm_hoversel_item_add
+                     (sd->hoversel, E_("Copy"), NULL, ELM_ICON_NONE,
+                      _hoversel_item_copy_cb, obj);
+                  if (sd->editable)
+                    {
+                       elm_hoversel_item_add
+                          (sd->hoversel, E_("Cut"), NULL, ELM_ICON_NONE,
+                           _hoversel_item_cut_cb, obj);
+                       if (ownersel)
+                         elm_hoversel_item_add
+                            (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
+                             _hoversel_item_paste_cb, obj);
+                    }
+                  elm_hoversel_item_add
+                    (sd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
+                    _hover_cancel_cb, obj);
+               }
+          }
+        else
+          {
+             if (!sd->sel_mode)
+               {
+                  if (sd->sel_allow && !_elm_config->desktop_entry)
+                    {
+                       if (!sd->password)
+                         elm_hoversel_item_add
+                           (sd->hoversel, E_("Select"), NULL, ELM_ICON_NONE,
+                           _hover_selected_cb, obj);
+                    }
+                  if (ownersel)
+                    {
+                       if (sd->editable)
+                         elm_hoversel_item_add
+                           (sd->hoversel, E_("Paste"), NULL, ELM_ICON_NONE,
+                           _hoversel_item_paste_cb, obj);
+                    }
+               }
+             else
+               elm_hoversel_item_add
+                  (sd->hoversel, E_("Cancel"), NULL, ELM_ICON_NONE,
+                   _hover_cancel_cb, obj);
+          }
+
+        EINA_LIST_FOREACH(sd->items, l, it)
+          {
+             elm_hoversel_item_add(sd->hoversel, it->label, it->icon_file,
+                                   it->icon_type, _hover_item_clicked_cb, it);
+          }
+
+        if (sd->hoversel)
+          {
+             _hoversel_position(obj);
+             evas_object_show(sd->hoversel);
+             elm_hoversel_hover_begin(sd->hoversel);
+          }
+
+        if (!_elm_config->desktop_entry)
+          {
+             edje_object_part_text_select_allow_set
+               (sd->entry_edje, "elm.text", EINA_FALSE);
+             edje_object_part_text_select_abort(sd->entry_edje, "elm.text");
+          }
+     }
+}
+
+static void
+_magnifier_proxy_update(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   _magnifier_move(data);
+}
+
+static void
+_magnifier_create(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   double scale = _elm_config->magnifier_scale;
+   Evas *e;
+   Evas_Coord w, h, mw, mh;
+
+   evas_object_del(sd->mgf_proxy);
+   evas_object_del(sd->mgf_bg);
+   evas_object_del(sd->mgf_clip);
+
+   e = evas_object_evas_get(data);
+
+   //Bg
+   sd->mgf_bg = edje_object_add(e);
+   _elm_theme_object_set(data, sd->mgf_bg, "entry", "magnifier", "default");
+   evas_object_show(sd->mgf_bg);
+
+   //Proxy
+   sd->mgf_proxy = evas_object_image_add(e);
+   evas_object_event_callback_add(sd->mgf_proxy, EVAS_CALLBACK_RESIZE,
+                                  _magnifier_proxy_update, data);
+   evas_object_event_callback_add(sd->mgf_proxy, EVAS_CALLBACK_MOVE,
+                                  _magnifier_proxy_update, data);
+   edje_object_part_swallow(sd->mgf_bg, "elm.swallow.content", sd->mgf_proxy);
+   evas_object_image_source_set(sd->mgf_proxy, data);
+   evas_object_geometry_get(data, NULL, NULL, &w, &h);
+
+   //Clipper
+   sd->mgf_clip = evas_object_rectangle_add(e);
+   evas_object_color_set(sd->mgf_clip, 0, 0, 0, 0);
+   evas_object_show(sd->mgf_clip);
+   evas_object_clip_set(sd->mgf_proxy, sd->mgf_clip);
+
+   mw = (Evas_Coord)(scale * (float) w);
+   mh = (Evas_Coord)(scale * (float) h);
+   if ((mw <= 0) || (mh <= 0)) return;
+
+   evas_object_layer_set(sd->mgf_bg, EVAS_LAYER_MAX);
+   evas_object_layer_set(sd->mgf_proxy, EVAS_LAYER_MAX);
+}
+
+static void
+_magnifier_move(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   Evas_Coord x, y, w, h;
+   Evas_Coord px, py, pw, ph;
+   Evas_Coord cx, cy, ch;
+   Evas_Coord ex, ey;
+   Evas_Coord mx, my, mw, mh;
+   Evas_Coord diffx = 0;
+   Evas_Object *top;
+   double fx, fy, fw, fh;
+   double scale = _elm_config->magnifier_scale;
+
+   edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+                                             &cx, &cy, NULL, &ch);
+   if (sd->scroll)
+     {
+        Evas_Coord ox, oy;
+        evas_object_geometry_get(sd->scr_edje, &ex, &ey, NULL, NULL);
+        elm_interface_scrollable_content_pos_get(data, &ox, &oy);
+        ex -= ox;
+        ey -= oy;
+     }
+   else
+     {
+        evas_object_geometry_get(data, &ex, &ey, NULL, NULL);
+     }
+   cx += ex;
+   cy += ey;
+
+   //Move the Magnifier
+   edje_object_parts_extends_calc(sd->mgf_bg, &x, &y, &w, &h);
+   evas_object_move(sd->mgf_bg, cx - x - (w / 2), cy - y - h);
+
+   mx = cx - x - (w / 2);
+   my = cy - y - h;
+   mw = w;
+   mh = h;
+
+   // keep magnifier inside window
+   top = elm_widget_top_get(data);
+   if (top && eo_isa(top, ELM_WIN_CLASS))
+     {
+        Evas_Coord wh, ww;
+        evas_object_geometry_get(top, NULL, NULL, &ww, &wh);
+        if (mx < 0)
+          {
+             diffx = mx;
+             mx = 0;
+          }
+        if (mx + mw > ww)
+          {
+             diffx = - (ww - (mx + mw));
+             mx = ww - mw;
+          }
+        if (my < 0)
+          my = 0;
+        if (my + mh > wh)
+          my = wh - mh;
+        evas_object_move(sd->mgf_bg, mx, my);
+     }
+
+   //Set the Proxy Render Area
+   evas_object_geometry_get(data, &x, &y, &w, &h);
+   evas_object_geometry_get(sd->mgf_proxy, &px, &py, &pw, &ph);
+
+   fx = -((cx - x) * scale) + (pw * 0.5) + diffx;
+   fy = -((cy - y) * scale) + (ph * 0.5) - (ch * 0.5 * scale);
+   fw = w * scale;
+   fh = h * scale;
+   evas_object_image_fill_set(sd->mgf_proxy, fx, fy, fw, fh);
+
+   //Update Clipper Area
+   int tx = fx;
+   int ty = fy;
+   int tw = fw;
+   int th = fh;
+   if (tx > 0) px += tx;
+   if (ty > 0) py += ty;
+   if (-(tx - pw) > tw) pw -= (-((tx - pw) + tw));
+   if (-(ty - ph) > th) ph -= (-((ty - ph) + th));
+   evas_object_move(sd->mgf_clip, px, py);
+   evas_object_resize(sd->mgf_clip, pw, ph);
+}
+
+static void
+_magnifier_hide(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+   edje_object_signal_emit(sd->mgf_bg, "elm,action,hide,magnifier", "elm");
+   elm_widget_scroll_freeze_pop(data);
+   evas_object_hide(sd->mgf_clip);
+}
+
+static void
+_magnifier_show(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+   edje_object_signal_emit(sd->mgf_bg, "elm,action,show,magnifier", "elm");
+   elm_widget_scroll_freeze_push(data);
+   evas_object_show(sd->mgf_clip);
+}
+
+static Eina_Bool
+_long_press_cb(void *data)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (_elm_config->magnifier_enable)
+     {
+        _magnifier_create(data);
+        _magnifier_show(data);
+        _magnifier_move(data);
+     }
+   /* Context menu will not appear if context menu disabled is set
+    * as false on a long press callback */
+   else if (!_elm_config->context_menu_disabled &&
+            (!_elm_config->desktop_entry))
+     _menu_call(data);
+
+   sd->long_pressed = EINA_TRUE;
+
+   sd->longpress_timer = NULL;
+   eo_event_callback_call
+     (data, EVAS_CLICKABLE_INTERFACE_EVENT_LONGPRESSED, NULL);
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_key_down_cb(void *data,
+               Evas *evas EINA_UNUSED,
+               Evas_Object *obj EINA_UNUSED,
+               void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+   Eina_Bool on_hold = EINA_FALSE;
+
+   /* First check if context menu disabled is false or not, and
+    * then check for key id */
+   if ((!_elm_config->context_menu_disabled) && !strcmp(ev->key, "Menu"))
+     {
+        _menu_call(data);
+        on_hold = EINA_TRUE;
+     }
+   else
+     {
+        Eina_Bool control = evas_key_modifier_is_set(ev->modifiers, "Control");
+
+        /* Ctrl operations */
+        if (control)
+          {
+             if (!strncmp(ev->key, "c", 1))
+               {
+                  _copy_cb(data);
+                  on_hold = EINA_TRUE;
+               }
+             else if (!strncmp(ev->key, "x", 1))
+               {
+                  _cut_cb(data);
+                  on_hold = EINA_TRUE;
+               }
+             else if (!strncmp(ev->key, "v", 1))
+               {
+                  _paste_cb(data);
+                  on_hold = EINA_TRUE;
+               }
+          }
+     }
+
+   if (on_hold) ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+}
+
+static void
+_mouse_down_cb(void *data,
+               Evas *evas EINA_UNUSED,
+               Evas_Object *obj EINA_UNUSED,
+               void *event_info)
+{
+   Evas_Event_Mouse_Down *ev = event_info;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (sd->disabled) return;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+   sd->downx = ev->canvas.x;
+   sd->downy = ev->canvas.y;
+   sd->long_pressed = EINA_FALSE;
+
+    if (ev->button == 1)
+      {
+         ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+         sd->longpress_timer = ecore_timer_add
+           (_elm_config->longpress_timeout, _long_press_cb, data);
+      }
+    /* If right button is pressed and context menu disabled is true,
+     * then only context menu will appear */
+   else if (ev->button == 3 && (!_elm_config->context_menu_disabled))
+     {
+        if (_elm_config->desktop_entry)
+          {
+             sd->use_down = 1;
+             _menu_call(data);
+          }
+     }
+}
+
+static void
+_mouse_up_cb(void *data,
+             Evas *evas EINA_UNUSED,
+             Evas_Object *obj EINA_UNUSED,
+             void *event_info)
+{
+   Evas_Event_Mouse_Up *ev = event_info;
+   Eina_Bool top_is_win = EINA_FALSE;
+   Evas_Object *top;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (sd->disabled) return;
+   if (ev->button == 1)
+     {
+        ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+        /* Since context menu disabled flag was checked at long press start while mouse
+         * down, hence the same should be checked at mouse up from a long press
+         * as well */
+        if ((sd->long_pressed) && (_elm_config->magnifier_enable))
+          {
+             _magnifier_hide(data);
+             if (!_elm_config->context_menu_disabled)
+               {
+                  _menu_call(data);
+               }
+          }
+        else
+          {
+             top = elm_widget_top_get(data);
+             if (top)
+               {
+                  if (eo_isa(top, ELM_WIN_CLASS))
+                    top_is_win = EINA_TRUE;
+
+                  if (top_is_win && sd->input_panel_enable && sd->input_panel_show_on_demand &&
+                      !edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text"))
+                    elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
+               }
+          }
+     }
+  /* Since context menu disabled flag was checked at mouse right key down,
+   * hence the same should be stopped at mouse up of right key as well */
+   else if ((ev->button == 3) && (!_elm_config->context_menu_disabled) &&
+            (!_elm_config->desktop_entry))
+     {
+         sd->use_down = 1;
+         _menu_call(data);
+     }
+}
+
+static void
+_mouse_move_cb(void *data,
+               Evas *evas EINA_UNUSED,
+               Evas_Object *obj EINA_UNUSED,
+               void *event_info)
+{
+   Evas_Event_Mouse_Move *ev = event_info;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (sd->disabled) return;
+   if (ev->buttons == 1)
+     {
+        if ((sd->long_pressed) && (_elm_config->magnifier_enable))
+          {
+             Evas_Coord x, y;
+             Eina_Bool rv;
+
+             evas_object_geometry_get(sd->entry_edje, &x, &y, NULL, NULL);
+             rv = edje_object_part_text_cursor_coord_set
+               (sd->entry_edje, "elm.text", EDJE_CURSOR_USER,
+               ev->cur.canvas.x - x, ev->cur.canvas.y - y);
+             if (rv)
+               {
+                  edje_object_part_text_cursor_copy
+                    (sd->entry_edje, "elm.text", EDJE_CURSOR_USER, EDJE_CURSOR_MAIN);
+               }
+             else
+               WRN("Warning: Cannot move cursor");
+
+             _magnifier_move(data);
+          }
+     }
+   if (!sd->sel_mode)
+     {
+        if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+          {
+             ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+          }
+        else if (sd->longpress_timer)
+          {
+             Evas_Coord dx, dy;
+
+             dx = sd->downx - ev->cur.canvas.x;
+             dx *= dx;
+             dy = sd->downy - ev->cur.canvas.y;
+             dy *= dy;
+             if ((dx + dy) >
+                 ((_elm_config->finger_size / 2) *
+                  (_elm_config->finger_size / 2)))
+               {
+                  ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+               }
+          }
+     }
+   else if (sd->longpress_timer)
+     {
+        Evas_Coord dx, dy;
+
+        dx = sd->downx - ev->cur.canvas.x;
+        dx *= dx;
+        dy = sd->downy - ev->cur.canvas.y;
+        dy *= dy;
+        if ((dx + dy) >
+            ((_elm_config->finger_size / 2) *
+             (_elm_config->finger_size / 2)))
+          {
+             ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+          }
+     }
+}
+
+static void
+_entry_changed_handle(void *data,
+                      const Eo_Event_Description* event)
+{
+   Evas_Coord minh;
+   const char *text;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   evas_event_freeze(evas_object_evas_get(data));
+   sd->changed = EINA_TRUE;
+   /* Reset the size hints which are no more relevant. Keep the
+    * height, this is a hack, but doesn't really matter cause we'll
+    * re-eval in a moment. */
+   evas_object_size_hint_min_get(data, NULL, &minh);
+   evas_object_size_hint_min_set(data, -1, minh);
+
+   elm_layout_sizing_eval(data);
+   ELM_SAFE_FREE(sd->text, eina_stringshare_del);
+   ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
+   evas_event_thaw(evas_object_evas_get(data));
+   evas_event_thaw_eval(evas_object_evas_get(data));
+   if ((sd->auto_save) && (sd->file))
+     sd->delay_write = ecore_timer_add(EFL_UI_TEXT_DELAY_WRITE_TIME,
+                                       _delay_write, data);
+
+   _return_key_enabled_check(data);
+   text = edje_object_part_text_get(sd->entry_edje, "elm.text");
+   if (text)
+     {
+        if (text[0])
+          _efl_ui_text_guide_update(data, EINA_TRUE);
+        else
+          _efl_ui_text_guide_update(data, EINA_FALSE);
+     }
+   _validate(data);
+
+   /* callback - this could call callbacks that delete the
+    * entry... thus... any access to sd after this could be
+    * invalid */
+   eo_event_callback_call(data, event, NULL);
+}
+
+static void
+_entry_changed_signal_cb(void *data,
+                         Evas_Object *obj EINA_UNUSED,
+                         const char *emission EINA_UNUSED,
+                         const char *source EINA_UNUSED)
+{
+   _entry_changed_handle(data, EFL_UI_TEXT_EVENT_CHANGED);
+}
+
+static void
+_entry_changed_user_signal_cb(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              const char *emission EINA_UNUSED,
+                              const char *source EINA_UNUSED)
+{
+   Elm_Entry_Change_Info info;
+   Edje_Entry_Change_Info *edje_info = (Edje_Entry_Change_Info *)
+     edje_object_signal_callback_extra_data_get();
+
+   if (edje_info)
+     {
+        memcpy(&info, edje_info, sizeof(info));
+        eo_event_callback_call(data, EFL_UI_TEXT_EVENT_CHANGED_USER, &info);
+     }
+   else
+     {
+        eo_event_callback_call(data, EFL_UI_TEXT_EVENT_CHANGED_USER, NULL);
+     }
+   if (_elm_config->atspi_mode)
+     {
+        Elm_Atspi_Text_Change_Info atspi_info;
+        if (edje_info && edje_info->insert)
+          {
+             atspi_info.content = edje_info->change.insert.content;
+             atspi_info.pos = edje_info->change.insert.pos;
+             atspi_info.len = edje_info->change.insert.plain_length;
+             elm_interface_atspi_accessible_event_emit(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info);
+          }
+        else if (edje_info && !edje_info->insert)
+          {
+             atspi_info.content = edje_info->change.del.content;
+             atspi_info.pos = MIN(edje_info->change.del.start, edje_info->change.del.end);
+             atspi_info.len = MAX(edje_info->change.del.start, edje_info->change.del.end) - atspi_info.pos;
+             elm_interface_atspi_accessible_event_emit(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info);
+          }
+     }
+}
+
+static void
+_entry_preedit_changed_signal_cb(void *data,
+                                 Evas_Object *obj EINA_UNUSED,
+                                 const char *emission EINA_UNUSED,
+                                 const char *source EINA_UNUSED)
+{
+   _entry_changed_handle(data, EFL_UI_TEXT_EVENT_PREEDIT_CHANGED);
+}
+
+static void
+_entry_undo_request_signal_cb(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              const char *emission EINA_UNUSED,
+                              const char *source EINA_UNUSED)
+{
+   eo_event_callback_call(data, EFL_UI_TEXT_EVENT_UNDO_REQUEST, NULL);
+}
+
+static void
+_entry_redo_request_signal_cb(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              const char *emission EINA_UNUSED,
+                              const char *source EINA_UNUSED)
+{
+   eo_event_callback_call(data, EFL_UI_TEXT_EVENT_REDO_REQUEST, NULL);
+}
+
+static void
+_entry_selection_start_signal_cb(void *data,
+                                 Evas_Object *obj EINA_UNUSED,
+                                 const char *emission EINA_UNUSED,
+                                 const char *source EINA_UNUSED)
+{
+   const Eina_List *l;
+   Evas_Object *entry;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   EINA_LIST_FOREACH(entries, l, entry)
+     {
+        if (entry != data) _efl_ui_text_select_none(entry, sd);
+     }
+   eo_event_callback_call
+     (data, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_START, NULL);
+
+   elm_object_focus_set(data, EINA_TRUE);
+}
+
+static void
+_entry_selection_all_signal_cb(void *data,
+                               Evas_Object *obj EINA_UNUSED,
+                               const char *emission EINA_UNUSED,
+                               const char *source EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   _efl_ui_text_select_all(data, sd);
+}
+
+static void
+_entry_selection_none_signal_cb(void *data,
+                                Evas_Object *obj EINA_UNUSED,
+                                const char *emission EINA_UNUSED,
+                                const char *source EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   _efl_ui_text_select_none(data, sd);
+}
+
+static void
+_entry_selection_changed_signal_cb(void *data,
+                                   Evas_Object *obj EINA_UNUSED,
+                                   const char *emission EINA_UNUSED,
+                                   const char *source EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->have_selection = EINA_TRUE;
+   eo_event_callback_call
+     (data, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_CHANGED, NULL);
+   _selection_store(ELM_SEL_TYPE_PRIMARY, data);
+   _update_selection_handler(data);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_event_emit(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL);
+}
+
+static void
+_entry_selection_cleared_signal_cb(void *data,
+                                   Evas_Object *obj EINA_UNUSED,
+                                   const char *emission EINA_UNUSED,
+                                   const char *source EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (!sd->have_selection) return;
+
+   sd->have_selection = EINA_FALSE;
+   eo_event_callback_call
+     (data, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_CLEARED, NULL);
+   if (sd->cut_sel)
+     {
+        elm_cnp_selection_set
+           (data, ELM_SEL_TYPE_PRIMARY, ELM_SEL_FORMAT_MARKUP,
+            sd->cut_sel, eina_stringshare_strlen(sd->cut_sel));
+        elm_cnp_selection_loss_callback_set(data, ELM_SEL_TYPE_PRIMARY, _selection_clear, data);
+
+        ELM_SAFE_FREE(sd->cut_sel, eina_stringshare_del);
+     }
+   else
+     {
+        elm_object_cnp_selection_clear(data, ELM_SEL_TYPE_PRIMARY);
+     }
+   _hide_selection_handler(data);
+}
+
+static void
+_entry_paste_request_signal_cb(void *data,
+                               Evas_Object *obj EINA_UNUSED,
+                               const char *emission,
+                               const char *source EINA_UNUSED)
+{
+   Evas_Object *top;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   Elm_Sel_Type type = (emission[sizeof("ntry,paste,request,")] == '1') ?
+     ELM_SEL_TYPE_PRIMARY : ELM_SEL_TYPE_CLIPBOARD;
+
+   if (!sd->editable) return;
+   eo_event_callback_call
+     (data, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_PASTE, NULL);
+
+   top = elm_widget_top_get(data);
+   if ((top) && (elm_win_window_id_get(top)))
+     {
+        Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
+
+        sd->selection_asked = EINA_TRUE;
+
+        if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
+          formats = ELM_SEL_FORMAT_TEXT;
+        else if (sd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
+          formats |= ELM_SEL_FORMAT_IMAGE;
+
+        elm_cnp_selection_get(data, type, formats, _selection_data_cb, NULL);
+     }
+}
+
+static void
+_entry_copy_notify_signal_cb(void *data,
+                             Evas_Object *obj EINA_UNUSED,
+                             const char *emission EINA_UNUSED,
+                             const char *source EINA_UNUSED)
+{
+   _copy_cb(data);
+}
+
+static void
+_entry_cut_notify_signal_cb(void *data,
+                            Evas_Object *obj EINA_UNUSED,
+                            const char *emission EINA_UNUSED,
+                            const char *source EINA_UNUSED)
+{
+   _cut_cb(data);
+}
+
+static void
+_entry_cursor_changed_signal_cb(void *data,
+                                Evas_Object *obj EINA_UNUSED,
+                                const char *emission EINA_UNUSED,
+                                const char *source EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+   sd->cursor_pos = edje_object_part_text_cursor_pos_get
+       (sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN);
+   sd->cur_changed = EINA_TRUE;
+   if (elm_widget_focus_get(data))
+     edje_object_signal_emit(sd->entry_edje, "elm,action,show,cursor", "elm");
+   _cursor_geometry_recalc(data);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_event_emit(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL);
+}
+
+static void
+_entry_cursor_changed_manual_signal_cb(void *data,
+                                       Evas_Object *obj EINA_UNUSED,
+                                       const char *emission EINA_UNUSED,
+                                       const char *source EINA_UNUSED)
+{
+   eo_event_callback_call
+     (data, EFL_UI_TEXT_EVENT_CURSOR_CHANGED_MANUAL, NULL);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_event_emit(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL);
+}
+
+static void
+_signal_anchor_geoms_do_things_with_lol(Efl_Ui_Text_Data *sd,
+                                        Elm_Entry_Anchor_Info *ei)
+{
+   Evas_Textblock_Rectangle *r;
+   const Eina_List *geoms, *l;
+   Evas_Coord px, py, x, y;
+
+   geoms = edje_object_part_text_anchor_geometry_get
+       (sd->entry_edje, "elm.text", ei->name);
+
+   if (!geoms) return;
+
+   evas_object_geometry_get(
+      edje_object_part_object_get(sd->entry_edje, "elm.text"),
+      &x, &y, NULL, NULL);
+   evas_pointer_canvas_xy_get
+     (evas_object_evas_get(sd->entry_edje), &px, &py);
+
+   EINA_LIST_FOREACH(geoms, l, r)
+     {
+        if (((r->x + x) <= px) && ((r->y + y) <= py) &&
+            ((r->x + x + r->w) > px) && ((r->y + y + r->h) > py))
+          {
+             ei->x = r->x + x;
+             ei->y = r->y + y;
+             ei->w = r->w;
+             ei->h = r->h;
+             break;
+          }
+     }
+}
+
+static void
+_entry_anchor_down_signal_cb(void *data,
+                             Evas_Object *obj EINA_UNUSED,
+                             const char *emission EINA_UNUSED,
+                             const char *source EINA_UNUSED)
+{
+   Elm_Entry_Anchor_Info ei;
+   const char *p;
+   char *p2;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   p = emission + sizeof("nchor,mouse,down,");
+   ei.button = strtol(p, &p2, 10);
+   ei.name = p2 + 1;
+   ei.x = ei.y = ei.w = ei.h = 0;
+
+   _signal_anchor_geoms_do_things_with_lol(sd, &ei);
+
+   if (!sd->disabled)
+     eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ANCHOR_DOWN, &ei);
+}
+
+static void
+_entry_anchor_up_signal_cb(void *data,
+                           Evas_Object *obj EINA_UNUSED,
+                           const char *emission EINA_UNUSED,
+                           const char *source EINA_UNUSED)
+{
+   Elm_Entry_Anchor_Info ei;
+   const char *p;
+   char *p2;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   p = emission + sizeof("nchor,mouse,up,");
+   ei.button = strtol(p, &p2, 10);
+   ei.name = p2 + 1;
+   ei.x = ei.y = ei.w = ei.h = 0;
+
+   _signal_anchor_geoms_do_things_with_lol(sd, &ei);
+
+   if (!sd->disabled)
+     eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ANCHOR_UP, &ei);
+}
+
+static void
+_anchor_hover_del_cb(void *data,
+                     Evas *e EINA_UNUSED,
+                     Evas_Object *obj EINA_UNUSED,
+                     void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   ELM_SAFE_FREE(sd->anchor_hover.pop, evas_object_del);
+   evas_object_event_callback_del_full
+     (sd->anchor_hover.hover, EVAS_CALLBACK_DEL, _anchor_hover_del_cb, obj);
+}
+
+static Eina_Bool
+_anchor_hover_clicked_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+   _efl_ui_text_anchor_hover_end(data, sd);
+
+   return EINA_TRUE;
+}
+
+static void
+_entry_hover_anchor_clicked_do(Evas_Object *obj,
+                               Elm_Entry_Anchor_Info *info)
+{
+   Evas_Object *hover_parent;
+   Evas_Coord x, w, y, h, px, py;
+   Elm_Entry_Anchor_Hover_Info ei;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->hoversel) return;
+
+   ei.anchor_info = info;
+
+   sd->anchor_hover.pop = elm_icon_add(obj);
+   evas_object_move(sd->anchor_hover.pop, info->x, info->y);
+   evas_object_resize(sd->anchor_hover.pop, info->w, info->h);
+
+   sd->anchor_hover.hover = elm_hover_add(obj);
+   evas_object_event_callback_add
+     (sd->anchor_hover.hover, EVAS_CALLBACK_DEL, _anchor_hover_del_cb, obj);
+   elm_widget_mirrored_set
+     (sd->anchor_hover.hover, elm_widget_mirrored_get(obj));
+   if (sd->anchor_hover.hover_style)
+     elm_object_style_set
+       (sd->anchor_hover.hover, sd->anchor_hover.hover_style);
+
+   hover_parent = sd->anchor_hover.hover_parent;
+   if (!hover_parent) hover_parent = obj;
+   elm_hover_parent_set(sd->anchor_hover.hover, hover_parent);
+   elm_hover_target_set(sd->anchor_hover.hover, sd->anchor_hover.pop);
+   ei.hover = sd->anchor_hover.hover;
+
+   evas_object_geometry_get(hover_parent, &x, &y, &w, &h);
+   ei.hover_parent.x = x;
+   ei.hover_parent.y = y;
+   ei.hover_parent.w = w;
+   ei.hover_parent.h = h;
+   px = info->x + (info->w / 2);
+   py = info->y + (info->h / 2);
+   ei.hover_left = 1;
+   if (px < (x + (w / 3))) ei.hover_left = 0;
+   ei.hover_right = 1;
+   if (px > (x + ((w * 2) / 3))) ei.hover_right = 0;
+   ei.hover_top = 1;
+   if (py < (y + (h / 3))) ei.hover_top = 0;
+   ei.hover_bottom = 1;
+   if (py > (y + ((h * 2) / 3))) ei.hover_bottom = 0;
+
+   /* Swap right and left because they switch sides in RTL */
+   if (elm_widget_mirrored_get(sd->anchor_hover.hover))
+     {
+        Eina_Bool tmp = ei.hover_left;
+
+        ei.hover_left = ei.hover_right;
+        ei.hover_right = tmp;
+     }
+
+   eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_ANCHOR_HOVER_OPENED, &ei);
+   eo_event_callback_add
+     (sd->anchor_hover.hover, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, _anchor_hover_clicked_cb, obj);
+
+   /* FIXME: Should just check if there's any callback registered to
+    * the smart events instead.  This is used to determine if anyone
+    * cares about the hover or not. */
+   if (!elm_layout_content_get(sd->anchor_hover.hover, "middle") &&
+       !elm_layout_content_get(sd->anchor_hover.hover, "left") &&
+       !elm_layout_content_get(sd->anchor_hover.hover, "right") &&
+       !elm_layout_content_get(sd->anchor_hover.hover, "top") &&
+       !elm_layout_content_get(sd->anchor_hover.hover, "bottom"))
+     {
+        ELM_SAFE_FREE(sd->anchor_hover.hover, evas_object_del);
+     }
+   else
+     evas_object_show(sd->anchor_hover.hover);
+}
+
+static void
+_entry_anchor_clicked_signal_cb(void *data,
+                                Evas_Object *obj EINA_UNUSED,
+                                const char *emission,
+                                const char *source EINA_UNUSED)
+{
+   Elm_Entry_Anchor_Info ei;
+   const char *p;
+   char *p2;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   p = emission + sizeof("nchor,mouse,clicked,");
+   ei.button = strtol(p, &p2, 10);
+   ei.name = p2 + 1;
+   ei.x = ei.y = ei.w = ei.h = 0;
+
+   _signal_anchor_geoms_do_things_with_lol(sd, &ei);
+
+   if (!sd->disabled)
+     {
+        eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ANCHOR_CLICKED, &ei);
+        _entry_hover_anchor_clicked_do(data, &ei);
+     }
+}
+
+static void
+_entry_anchor_move_signal_cb(void *data EINA_UNUSED,
+                             Evas_Object *obj EINA_UNUSED,
+                             const char *emission EINA_UNUSED,
+                             const char *source EINA_UNUSED)
+{
+}
+
+static void
+_entry_anchor_in_signal_cb(void *data,
+                           Evas_Object *obj EINA_UNUSED,
+                           const char *emission EINA_UNUSED,
+                           const char *source EINA_UNUSED)
+{
+   Elm_Entry_Anchor_Info ei;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   ei.name = emission + sizeof("nchor,mouse,in,");
+   ei.button = 0;
+   ei.x = ei.y = ei.w = ei.h = 0;
+
+   _signal_anchor_geoms_do_things_with_lol(sd, &ei);
+
+   if (!sd->disabled)
+     eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ANCHOR_IN, &ei);
+}
+
+static void
+_entry_anchor_out_signal_cb(void *data,
+                            Evas_Object *obj EINA_UNUSED,
+                            const char *emission EINA_UNUSED,
+                            const char *source EINA_UNUSED)
+{
+   Elm_Entry_Anchor_Info ei;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   ei.name = emission + sizeof("nchor,mouse,out,");
+   ei.button = 0;
+   ei.x = ei.y = ei.w = ei.h = 0;
+
+   _signal_anchor_geoms_do_things_with_lol(sd, &ei);
+
+   if (!sd->disabled)
+     eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ANCHOR_OUT, &ei);
+}
+
+static void
+_entry_key_enter_signal_cb(void *data,
+                           Evas_Object *obj EINA_UNUSED,
+                           const char *emission EINA_UNUSED,
+                           const char *source EINA_UNUSED)
+{
+   eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ACTIVATED, NULL);
+}
+
+static void
+_entry_key_escape_signal_cb(void *data,
+                            Evas_Object *obj EINA_UNUSED,
+                            const char *emission EINA_UNUSED,
+                            const char *source EINA_UNUSED)
+{
+   eo_event_callback_call(data, EFL_UI_TEXT_EVENT_ABORTED, NULL);
+}
+
+static void
+_entry_mouse_down_signal_cb(void *data,
+                            Evas_Object *obj EINA_UNUSED,
+                            const char *emission EINA_UNUSED,
+                            const char *source EINA_UNUSED)
+{
+   eo_event_callback_call(data, EFL_UI_TEXT_EVENT_PRESS, NULL);
+}
+
+static void
+_entry_mouse_clicked_signal_cb(void *data,
+                               Evas_Object *obj EINA_UNUSED,
+                               const char *emission EINA_UNUSED,
+                               const char *source EINA_UNUSED)
+{
+   eo_event_callback_call
+     (data, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, NULL);
+}
+
+static void
+_entry_mouse_double_signal_cb(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              const char *emission EINA_UNUSED,
+                              const char *source EINA_UNUSED)
+{
+   eo_event_callback_call
+     (data, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_DOUBLE, NULL);
+}
+
+static void
+_entry_mouse_triple_signal_cb(void *data,
+                              Evas_Object *obj EINA_UNUSED,
+                              const char *emission EINA_UNUSED,
+                              const char *source EINA_UNUSED)
+{
+   eo_event_callback_call
+     (data, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_TRIPLE, NULL);
+}
+
+static Evas_Object *
+_item_get(void *data,
+          Evas_Object *edje EINA_UNUSED,
+          const char *part EINA_UNUSED,
+          const char *item)
+{
+   Eina_List *l;
+   Evas_Object *o;
+   Elm_Entry_Item_Provider *ip;
+   const char *style = elm_widget_style_get(data);
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   EINA_LIST_FOREACH(sd->item_providers, l, ip)
+     {
+        o = ip->func(ip->data, data, item);
+        if (o) return o;
+     }
+   if (item && !strncmp(item, "file://", 7))
+     {
+        const char *fname = item + 7;
+
+        o = evas_object_image_filled_add(evas_object_evas_get(data));
+        evas_object_image_file_set(o, fname, NULL);
+        if (evas_object_image_load_error_get(o) == EVAS_LOAD_ERROR_NONE)
+          {
+             evas_object_show(o);
+          }
+        else
+          {
+             evas_object_del(o);
+             o = edje_object_add(evas_object_evas_get(data));
+             elm_widget_theme_object_set
+               (data, o, "entry/emoticon", "wtf", style);
+          }
+        return o;
+     }
+
+   o = edje_object_add(evas_object_evas_get(data));
+   if (!elm_widget_theme_object_set
+         (data, o, "entry", item, style))
+     elm_widget_theme_object_set
+       (data, o, "entry/emoticon", "wtf", style);
+   return o;
+}
+
+static void
+_markup_filter_cb(void *data,
+                  Evas_Object *edje EINA_UNUSED,
+                  const char *part EINA_UNUSED,
+                  char **text)
+{
+   Eina_List *l;
+   Elm_Entry_Markup_Filter *tf;
+
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   EINA_LIST_FOREACH(sd->markup_filters, l, tf)
+     {
+        tf->func(tf->data, data, text);
+        if (!*text)
+          break;
+     }
+}
+
+/* This function is used to insert text by chunks in jobs */
+static Eina_Bool
+_text_append_idler(void *data)
+{
+   int start;
+   char backup;
+   Evas_Object *obj = (Evas_Object *)data;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   evas_event_freeze(evas_object_evas_get(obj));
+   ELM_SAFE_FREE(sd->text, eina_stringshare_del);
+   sd->changed = EINA_TRUE;
+
+   start = sd->append_text_position;
+   if ((start + EFL_UI_TEXT_CHUNK_SIZE) < sd->append_text_len)
+     {
+        int pos = start;
+        int tag_start, esc_start;
+
+        tag_start = esc_start = -1;
+        /* Find proper markup cut place */
+        while (pos - start < EFL_UI_TEXT_CHUNK_SIZE)
+          {
+             int prev_pos = pos;
+             Eina_Unicode tmp =
+               eina_unicode_utf8_next_get(sd->append_text_left, &pos);
+
+             if (esc_start == -1)
+               {
+                  if (tmp == '<')
+                    tag_start = prev_pos;
+                  else if (tmp == '>')
+                    tag_start = -1;
+               }
+             if (tag_start == -1)
+               {
+                  if (tmp == '&')
+                    esc_start = prev_pos;
+                  else if (tmp == ';')
+                    esc_start = -1;
+               }
+          }
+
+        if (tag_start >= 0)
+          {
+             sd->append_text_position = tag_start;
+          }
+        else if (esc_start >= 0)
+          {
+             sd->append_text_position = esc_start;
+          }
+        else
+          {
+             sd->append_text_position = pos;
+          }
+     }
+   else
+     {
+        sd->append_text_position = sd->append_text_len;
+     }
+
+   backup = sd->append_text_left[sd->append_text_position];
+   sd->append_text_left[sd->append_text_position] = '\0';
+
+   edje_object_part_text_append
+     (sd->entry_edje, "elm.text", sd->append_text_left + start);
+
+   sd->append_text_left[sd->append_text_position] = backup;
+
+   evas_event_thaw(evas_object_evas_get(obj));
+   evas_event_thaw_eval(evas_object_evas_get(obj));
+
+   _efl_ui_text_guide_update(obj, EINA_TRUE);
+
+   /* If there's still more to go, renew the idler, else, cleanup */
+   if (sd->append_text_position < sd->append_text_len)
+     {
+        return ECORE_CALLBACK_RENEW;
+     }
+   else
+     {
+        edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+              EDJE_CURSOR_MAIN, sd->cursor_pos);
+        free(sd->append_text_left);
+        sd->append_text_left = NULL;
+        sd->append_text_idler = NULL;
+        eo_event_callback_call
+          (obj, EFL_UI_TEXT_EVENT_TEXT_SET_DONE, NULL);
+        return ECORE_CALLBACK_CANCEL;
+     }
+}
+
+#if 0
+static void
+_chars_add_till_limit(Evas_Object *obj,
+                      char **text,
+                      int can_add,
+                      Length_Unit unit)
+{
+   int i = 0, current_len = 0;
+   char *new_text;
+
+   if (!*text) return;
+   if (unit >= LENGTH_UNIT_LAST) return;
+   if (strstr(*text, "<preedit")) return;
+
+   new_text = *text;
+   current_len = strlen(*text);
+   while (*new_text)
+     {
+        int idx = 0, unit_size = 0;
+        char *markup, *utfstr;
+
+        if (*new_text == '<')
+          {
+             while (*(new_text + idx) != '>')
+               {
+                  idx++;
+                  if (!*(new_text + idx)) break;
+               }
+          }
+        else if (*new_text == '&')
+          {
+             while (*(new_text + idx) != ';')
+               {
+                  idx++;
+                  if (!*(new_text + idx)) break;
+               }
+          }
+        idx = evas_string_char_next_get(new_text, idx, NULL);
+        markup = malloc(idx + 1);
+        if (markup)
+          {
+             strncpy(markup, new_text, idx);
+             markup[idx] = 0;
+             utfstr = efl_ui_text_markup_to_utf8(markup);
+             if (utfstr)
+               {
+                  if (unit == LENGTH_UNIT_BYTE)
+                    unit_size = strlen(utfstr);
+                  else if (unit == LENGTH_UNIT_CHAR)
+                    unit_size = evas_string_char_len_get(utfstr);
+                  ELM_SAFE_FREE(utfstr, free);
+               }
+             ELM_SAFE_FREE(markup, free);
+          }
+        if (can_add < unit_size)
+          {
+             if (!i)
+               {
+                  eo_event_callback_call
+                    (obj, EFL_UI_TEXT_EVENT_MAXLENGTH_REACHED, NULL);
+                  ELM_SAFE_FREE(*text, free);
+                  return;
+               }
+             can_add = 0;
+             strncpy(new_text, new_text + idx,
+                     current_len - ((new_text + idx) - *text));
+             current_len -= idx;
+             (*text)[current_len] = 0;
+          }
+        else
+          {
+             new_text += idx;
+             can_add -= unit_size;
+          }
+        i++;
+     }
+
+   eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_MAXLENGTH_REACHED, NULL);
+}
+#endif
+
+EOLIAN static void
+_efl_ui_text_elm_layout_signal_emit(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, const char *emission, const char *source)
+{
+   /* always pass to both edje objs */
+   edje_object_signal_emit(sd->entry_edje, emission, source);
+   edje_object_message_signal_process(sd->entry_edje);
+
+   if (sd->scr_edje)
+     {
+        edje_object_signal_emit(sd->scr_edje, emission, source);
+        edje_object_message_signal_process(sd->scr_edje);
+     }
+}
+
+EOLIAN static void
+_efl_ui_text_elm_layout_signal_callback_add (Eo *obj, Efl_Ui_Text_Data *sd, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
+{
+   Evas_Object *ro;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   ro = wd->resize_obj;
+
+   wd->resize_obj = sd->entry_edje;
+
+   elm_obj_layout_signal_callback_add
+     (eo_super(obj, MY_CLASS), emission, source, func_cb, data);
+
+   if (sd->scr_edje)
+     {
+        wd->resize_obj = sd->scr_edje;
+
+        elm_obj_layout_signal_callback_add
+              (eo_super(obj, MY_CLASS), emission, source, func_cb, data);
+     }
+
+   wd->resize_obj = ro;
+}
+
+EOLIAN static void *
+_efl_ui_text_elm_layout_signal_callback_del(Eo *obj, Efl_Ui_Text_Data *sd, const char *emission, const char *source, Edje_Signal_Cb func_cb)
+{
+   Evas_Object *ro;
+   void *data = NULL;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+   ro = wd->resize_obj;
+
+   wd->resize_obj = sd->entry_edje;
+
+   data = elm_obj_layout_signal_callback_del
+         (eo_super(obj, MY_CLASS), emission, source, func_cb);
+
+   if (sd->scr_edje)
+     {
+        wd->resize_obj = sd->scr_edje;
+
+        data = elm_obj_layout_signal_callback_del
+              (eo_super(obj, MY_CLASS), emission, source, func_cb);
+     }
+
+   wd->resize_obj = ro;
+   return data;
+}
+
+#if 0
+static Eina_Bool
+_efl_ui_text_content_set(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content)
+{
+   Eina_Bool int_ret = EINA_FALSE;
+   int_ret = efl_content_set(efl_part(eo_super(obj, MY_CLASS), part), content);
+   if (!int_ret) return EINA_FALSE;
+
+   /* too bad entry does not follow the pattern
+    * "elm,state,{icon,end},visible", we have to repeat ourselves */
+   if (!part || !strcmp(part, "icon") || !strcmp(part, "elm.swallow.icon"))
+     efl_ui_text_icon_visible_set(obj, EINA_TRUE);
+
+   if (!part || !strcmp(part, "end") || !strcmp(part, "elm.swallow.end"))
+     efl_ui_text_end_visible_set(obj, EINA_TRUE);
+
+   return EINA_TRUE;
+}
+
+
+static Evas_Object*
+_efl_ui_text_content_unset(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *part)
+{
+   Evas_Object *ret = NULL;
+   ret = efl_content_unset(efl_part(eo_super(obj, MY_CLASS), part));
+   if (!ret) return NULL;
+
+   /* too bad entry does not follow the pattern
+    * "elm,state,{icon,end},hidden", we have to repeat ourselves */
+   if (!part || !strcmp(part, "icon") || !strcmp(part, "elm.swallow.icon"))
+     efl_ui_text_icon_visible_set(obj, EINA_FALSE);
+
+   if (!part || !strcmp(part, "end") || !strcmp(part, "elm.swallow.end"))
+     efl_ui_text_end_visible_set(obj, EINA_FALSE);
+
+   return ret;
+}
+#endif
+
+static void
+_entry_text_append(Evas_Object* obj, const char* entry, Eina_Bool set)
+{
+   int len = 0;
+   if (!entry) return;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   len = strlen(entry);
+
+   if (sd->append_text_left)
+     {
+        char *tmpbuf;
+
+        tmpbuf = realloc(sd->append_text_left, sd->append_text_len + len + 1);
+        if (!tmpbuf)
+          {
+             /* Do something */
+             return;
+          }
+        sd->append_text_left = tmpbuf;
+        memcpy(sd->append_text_left + sd->append_text_len, entry, len + 1);
+        sd->append_text_len += len;
+     }
+   else
+     {
+        if (len > EFL_UI_TEXT_CHUNK_SIZE)
+          {
+             sd->append_text_left = (char *)malloc(len + 1);
+          }
+
+        if (sd->append_text_left)
+          {
+             memcpy(sd->append_text_left, entry, len + 1);
+             sd->append_text_position = 0;
+             sd->append_text_len = len;
+             sd->append_text_idler = ecore_idler_add(_text_append_idler, obj);
+          }
+        else
+          {
+             if (set)
+               {
+                  edje_object_part_text_set(sd->entry_edje, "elm.text", entry);
+               }
+             else
+               {
+                  edje_object_part_text_append(sd->entry_edje, "elm.text", entry);
+               }
+             edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
+                   EDJE_CURSOR_MAIN, sd->cursor_pos);
+             eo_event_callback_call(obj, EFL_UI_TEXT_EVENT_TEXT_SET_DONE, NULL);
+          }
+     }
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_layout_text_set(Eo *obj, Efl_Ui_Text_Data *sd, const char *part, const char *entry)
+{
+   int len = 0;
+
+   if (!entry) entry = "";
+   if (part)
+     {
+        if (!strcmp(part, "guide"))
+          edje_object_part_text_set(sd->entry_edje, "elm.guide", entry);
+        else
+          edje_object_part_text_set(sd->entry_edje, part, entry);
+
+        return EINA_TRUE;
+     }
+
+   evas_event_freeze(evas_object_evas_get(obj));
+   ELM_SAFE_FREE(sd->text, eina_stringshare_del);
+   sd->changed = EINA_TRUE;
+
+   /* Clear currently pending job if there is one */
+   if (sd->append_text_idler)
+     {
+        ecore_idler_del(sd->append_text_idler);
+        ELM_SAFE_FREE(sd->append_text_left, free);
+        sd->append_text_idler = NULL;
+     }
+
+   len = strlen(entry);
+   if (sd->append_text_left)
+     {
+        free(sd->append_text_left);
+        sd->append_text_left = NULL;
+     }
+
+   /* Need to clear the entry first */
+   edje_object_part_text_set(sd->entry_edje, "elm.text", "");
+   _entry_text_append(obj, entry, EINA_TRUE);
+
+   if (len > 0)
+     _efl_ui_text_guide_update(obj, EINA_TRUE);
+   else
+     _efl_ui_text_guide_update(obj, EINA_FALSE);
+
+   evas_event_thaw(evas_object_evas_get(obj));
+   evas_event_thaw_eval(evas_object_evas_get(obj));
+   return EINA_TRUE;
+}
+
+EOLIAN static const char *
+_efl_ui_text_elm_layout_text_get(Eo *obj, Efl_Ui_Text_Data *sd, const char *item)
+{
+   const char *text;
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   if (item)
+     {
+        if (!strcmp(item, "default")) goto proceed;
+        else if (!strcmp(item, "guide"))
+          {
+             return edje_object_part_text_get(sd->entry_edje, "elm.guide");
+          }
+        else
+          {
+             return edje_object_part_text_get(sd->entry_edje, item);
+          }
+     }
+
+proceed:
+
+   text = efl_text_get(text_obj);
+   if (!text)
+     {
+        ERR("text=NULL for edje %p, part 'elm.text'", sd->entry_edje);
+
+        return NULL;
+     }
+
+   if (sd->append_text_len > 0)
+     {
+        char *tmpbuf;
+        size_t len, tlen;
+
+        tlen = strlen(text);
+        len = tlen + sd->append_text_len - sd->append_text_position;
+        /* FIXME: need that or we do copy uninitialised data */
+        tmpbuf = calloc(1, len + 1);
+        if (!tmpbuf)
+          {
+             ERR("Failed to allocate memory for entry's text %p", obj);
+             return NULL;
+          }
+        memcpy(tmpbuf, text, tlen);
+
+        if (sd->append_text_left)
+          memcpy(tmpbuf + tlen, sd->append_text_left
+                 + sd->append_text_position, sd->append_text_len
+                 - sd->append_text_position);
+        tmpbuf[len] = '\0';
+        eina_stringshare_replace(&sd->text, tmpbuf);
+        free(tmpbuf);
+     }
+   else
+     {
+        eina_stringshare_replace(&sd->text, text);
+     }
+
+   return sd->text;
+}
+
+static char *
+_access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
+{
+#if 0
+   const char *txt;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->password) return NULL;
+
+   txt = elm_widget_access_info_get(obj);
+
+   if (!txt)
+     return _elm_util_mkup_to_text(efl_ui_text_entry_get(obj));
+   else return strdup(txt);
+#else
+   (void) data;
+   (void) obj;
+   return NULL;
+#endif
+}
+
+static char *
+_access_state_cb(void *data EINA_UNUSED, Evas_Object *obj)
+{
+   Eina_Strbuf *buf;
+   char *ret;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   ret = NULL;
+   buf = eina_strbuf_new();
+
+   if (elm_widget_disabled_get(obj))
+     eina_strbuf_append(buf, "State: Disabled");
+
+   if (!sd->editable)
+     {
+        if (!eina_strbuf_length_get(buf))
+          eina_strbuf_append(buf, "State: Not Editable");
+        else eina_strbuf_append(buf, ", Not Editable");
+     }
+
+   if (sd->password)
+     {
+        if (!eina_strbuf_length_get(buf))
+          eina_strbuf_append(buf, "State: Password");
+        else eina_strbuf_append(buf, ", Password");
+     }
+
+   if (!eina_strbuf_length_get(buf)) goto buf_free;
+
+   ret = eina_strbuf_string_steal(buf);
+
+buf_free:
+   eina_strbuf_free(buf);
+   return ret;
+}
+
+static void
+_entry_selection_callbacks_unregister(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "selection,start", "elm.text",
+     _entry_selection_start_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (obj, "selection,changed", "elm.text",
+     _entry_selection_changed_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "entry,selection,all,request",
+     "elm.text", _entry_selection_all_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "entry,selection,none,request",
+     "elm.text", _entry_selection_none_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "selection,cleared", "elm.text",
+     _entry_selection_cleared_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "entry,paste,request,*", "elm.text",
+     _entry_paste_request_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "entry,copy,notify", "elm.text",
+     _entry_copy_notify_signal_cb, obj);
+   edje_object_signal_callback_del_full
+     (sd->entry_edje, "entry,cut,notify", "elm.text",
+     _entry_cut_notify_signal_cb, obj);
+}
+
+static void
+_entry_selection_callbacks_register(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   edje_object_signal_callback_add
+     (sd->entry_edje, "selection,start", "elm.text",
+     _entry_selection_start_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "selection,changed", "elm.text",
+     _entry_selection_changed_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "entry,selection,all,request",
+     "elm.text", _entry_selection_all_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "entry,selection,none,request",
+     "elm.text", _entry_selection_none_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "selection,cleared", "elm.text",
+     _entry_selection_cleared_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "entry,paste,request,*", "elm.text",
+     _entry_paste_request_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "entry,copy,notify", "elm.text",
+     _entry_copy_notify_signal_cb, obj);
+   edje_object_signal_callback_add
+     (sd->entry_edje, "entry,cut,notify", "elm.text",
+     _entry_cut_notify_signal_cb, obj);
+}
+
+static void
+_efl_ui_text_resize_internal(Evas_Object *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (sd->line_wrap)
+     {
+        elm_layout_sizing_eval(obj);
+     }
+   else if (sd->scroll)
+     {
+        Evas_Coord vw = 0, vh = 0;
+
+        elm_interface_scrollable_content_viewport_geometry_get
+              (obj, NULL, NULL, &vw, &vh);
+        if (vw < sd->ent_mw) vw = sd->ent_mw;
+        if (vh < sd->ent_mh) vh = sd->ent_mh;
+        evas_object_resize(sd->entry_edje, vw, vh);
+     }
+
+   if (sd->hoversel) _hoversel_position(obj);
+}
+
+static void
+_resize_cb(void *data,
+           Evas *e EINA_UNUSED,
+           Evas_Object *obj EINA_UNUSED,
+           void *event_info EINA_UNUSED)
+{
+   _efl_ui_text_resize_internal(data);
+}
+
+static void
+_selection_handlers_offset_calc(Evas_Object *obj, Evas_Object *handler, Evas_Coord canvasx, Evas_Coord canvasy)
+{
+   Evas_Coord ex, ey;
+   Evas_Coord cx, cy, cw, ch;
+   Evas_Coord hh;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+   edje_object_part_text_cursor_geometry_get(sd->entry_edje, "elm.text",
+                                                           &cx, &cy, &cw, &ch);
+   edje_object_size_min_calc(handler, NULL, &hh);
+
+   sd->ox = canvasx - (ex + cx + (cw / 2));
+   if (ch > hh)
+     sd->oy = canvasy - (ey + cy + ch);
+   else
+     sd->oy = canvasy - (ey + cy + (ch / 2));
+
+   ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+   sd->long_pressed = EINA_FALSE;
+   if (_elm_config->magnifier_enable)
+     {
+        _magnifier_create(obj);
+        _magnifier_show(obj);
+        _magnifier_move(obj);
+     }
+}
+
+static void
+_start_handler_mouse_down_cb(void *data,
+                             Evas *e EINA_UNUSED,
+                             Evas_Object *obj EINA_UNUSED,
+                             void *event_info)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   Evas_Event_Mouse_Down *ev = event_info;
+   int start_pos, end_pos, pos;
+   Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+   Efl_Canvas_Text_Cursor *main_cur;
+
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   sd->start_handler_down = EINA_TRUE;
+
+   /* Get the cursors */
+   efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+   main_cur = efl_canvas_text_cursor_get(text_obj);
+
+   start_pos = efl_canvas_text_cursor_position_get(sel_start);
+   end_pos = efl_canvas_text_cursor_position_get(sel_end);
+
+   if (start_pos <= end_pos)
+     {
+        pos = start_pos;
+        sd->sel_handler_cursor = sel_start;
+     }
+   else
+     {
+        pos = end_pos;
+        sd->sel_handler_cursor = sel_end;
+     }
+   efl_canvas_text_cursor_position_set(main_cur, pos);
+   _selection_handlers_offset_calc(data, sd->start_handler, ev->canvas.x, ev->canvas.y);
+}
+
+static void
+_start_handler_mouse_up_cb(void *data,
+                           Evas *e EINA_UNUSED,
+                           Evas_Object *obj EINA_UNUSED,
+                           void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->start_handler_down = EINA_FALSE;
+   if (_elm_config->magnifier_enable)
+     _magnifier_hide(data);
+   /* Context menu should not appear, even in case of selector mode, if the
+    * flag is false (disabled) */
+   if ((!_elm_config->context_menu_disabled) &&
+       (!_elm_config->desktop_entry) && (sd->long_pressed))
+     _menu_call(data);
+}
+
+static void
+_start_handler_mouse_move_cb(void *data,
+                             Evas *e EINA_UNUSED,
+                             Evas_Object *obj EINA_UNUSED,
+                             void *event_info)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (!sd->start_handler_down) return;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord ex, ey;
+   Evas_Coord cx, cy;
+   Efl_Canvas_Text_Cursor *main_cur;
+   int pos;
+
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+   main_cur = efl_canvas_text_cursor_get(text_obj);
+
+   evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+   cx = ev->cur.canvas.x - sd->ox - ex;
+   cy = ev->cur.canvas.y - sd->oy - ey;
+   if (cx <= 0) cx = 1;
+
+   efl_canvas_text_cursor_coord_set(sd->sel_handler_cursor, cx, cy);
+   pos = efl_canvas_text_cursor_position_get(sd->sel_handler_cursor);
+
+   /* Set the main cursor. */
+   efl_canvas_text_cursor_position_set(main_cur, pos);
+
+   ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+   sd->long_pressed = EINA_FALSE;
+   if (_elm_config->magnifier_enable)
+     _magnifier_move(data);
+}
+
+static void
+_end_handler_mouse_down_cb(void *data,
+                           Evas *e EINA_UNUSED,
+                           Evas_Object *obj EINA_UNUSED,
+                           void *event_info)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   Evas_Event_Mouse_Down *ev = event_info;
+   Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+   Efl_Canvas_Text_Cursor *main_cur;
+   int pos, start_pos, end_pos;
+
+   sd->end_handler_down = EINA_TRUE;
+
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+   main_cur = efl_canvas_text_cursor_get(text_obj);
+
+   start_pos = efl_canvas_text_cursor_position_get(sel_start);
+   end_pos = efl_canvas_text_cursor_position_get(sel_end);
+
+   if (start_pos < end_pos)
+     {
+        pos = end_pos;
+        sd->sel_handler_cursor = sel_start;
+     }
+   else
+     {
+        pos = start_pos;
+        sd->sel_handler_cursor = sel_end;
+     }
+
+   efl_canvas_text_cursor_position_set(main_cur, pos);
+   _selection_handlers_offset_calc(data, sd->end_handler, ev->canvas.x, ev->canvas.y);
+}
+
+static void
+_end_handler_mouse_up_cb(void *data,
+                         Evas *e EINA_UNUSED,
+                         Evas_Object *obj EINA_UNUSED,
+                         void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->end_handler_down = EINA_FALSE;
+   if (_elm_config->magnifier_enable)
+     _magnifier_hide(data);
+   /* Context menu appear was checked in case of selector start, and hence
+    * the same should be checked at selector end as well */
+   if ((!_elm_config->context_menu_disabled) &&
+       (!_elm_config->desktop_entry) && (sd->long_pressed))
+     _menu_call(data);
+}
+
+static void
+_end_handler_mouse_move_cb(void *data,
+                           Evas *e EINA_UNUSED,
+                           Evas_Object *obj EINA_UNUSED,
+                           void *event_info)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   if (!sd->end_handler_down) return;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord ex, ey;
+   Evas_Coord cx, cy;
+   int pos;
+
+   evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
+   cx = ev->cur.canvas.x - sd->ox - ex;
+   cy = ev->cur.canvas.y - sd->oy - ey;
+   if (cx <= 0) cx = 1;
+
+   efl_canvas_text_cursor_coord_set(sd->sel_handler_cursor, cx, cy);
+   pos = efl_canvas_text_cursor_position_get(sd->sel_handler_cursor);
+   /* Set the main cursor. */
+   efl_canvas_text_cursor_position_set(
+         edje_object_part_swallow_get(sd->entry_edje, "elm.text"),
+         pos);
+   ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
+   sd->long_pressed = EINA_FALSE;
+   if (_elm_config->magnifier_enable)
+     _magnifier_move(data);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_add(Eo *obj, Efl_Ui_Text_Data *priv)
+{
+   Eo *text_obj;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   evas_obj_smart_add(eo_super(obj, MY_CLASS));
+   elm_widget_sub_object_parent_add(obj);
+
+   priv->entry_edje = wd->resize_obj;
+
+   priv->cnp_mode = ELM_CNP_MODE_PLAINTEXT;
+   priv->line_wrap = ELM_WRAP_WORD;
+   priv->context_menu = EINA_TRUE;
+   priv->auto_save = EINA_TRUE;
+   priv->editable = EINA_TRUE;
+   priv->sel_allow = EINA_TRUE;
+
+   priv->drop_format = ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE;
+   elm_drop_target_add(obj, priv->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+
+   if (!elm_layout_theme_set(obj, "efl_ui_text", "base", elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   text_obj = eo_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj);
+   eo_composite_attach(obj, text_obj);
+   edje_object_part_swallow(priv->entry_edje, "elm.text", text_obj);
+   efl_canvas_text_style_set(text_obj, NULL, "DEFAULT='font=Sans font_size=14 color=#fff wrap=word'");
+   eo_event_callback_add(text_obj, EFL_UI_TEXT_INTERACTIVE_EVENT_CHANGED_USER,
+         _efl_ui_text_changed_cb, obj);
+   eo_event_callback_add(text_obj, EFL_UI_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED,
+         _efl_ui_text_selection_changed_cb, obj);
+   eo_event_callback_add(efl_canvas_text_cursor_get(text_obj), EFL_CANVAS_TEXT_CURSOR_EVENT_CHANGED,
+         _efl_ui_text_cursor_changed_cb, obj);
+   evas_object_event_callback_add(priv->entry_edje, EVAS_CALLBACK_MOVE,
+         _efl_ui_text_move_cb, obj);
+
+
+   priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
+   evas_object_data_set(priv->hit_rect, "_elm_leaveme", obj);
+
+   Evas_Object* clip = evas_object_clip_get(priv->entry_edje);
+   evas_object_clip_set(priv->hit_rect, clip);
+
+   evas_object_smart_member_add(priv->hit_rect, obj);
+   elm_widget_sub_object_add(obj, priv->hit_rect);
+
+   /* common scroller hit rectangle setup */
+   evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
+   evas_object_show(priv->hit_rect);
+   evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
+
+   elm_interface_scrollable_objects_set(obj, priv->entry_edje, priv->hit_rect);
+
+   edje_object_item_provider_set(priv->entry_edje, _item_get, obj);
+
+   edje_object_text_markup_filter_callback_add
+     (priv->entry_edje, "elm.text", _markup_filter_cb, obj);
+
+   evas_object_event_callback_add
+     (priv->entry_edje, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, obj);
+   evas_object_event_callback_add
+     (priv->entry_edje, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, obj);
+   evas_object_event_callback_add
+     (priv->entry_edje, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, obj);
+   evas_object_event_callback_add
+     (priv->entry_edje, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, obj);
+
+   /* this code can't go in smart_resize. sizing gets wrong */
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
+
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,changed", "elm.text",
+     _entry_changed_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,changed,user", "elm.text",
+     _entry_changed_user_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "preedit,changed", "elm.text",
+     _entry_preedit_changed_signal_cb, obj);
+
+   _entry_selection_callbacks_register(obj);
+
+   edje_object_signal_callback_add
+     (priv->entry_edje, "cursor,changed", "elm.text",
+     _entry_cursor_changed_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "cursor,changed,manual", "elm.text",
+     _entry_cursor_changed_manual_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,down,*", "elm.text",
+     _entry_anchor_down_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,up,*", "elm.text",
+     _entry_anchor_up_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,clicked,*", "elm.text",
+     _entry_anchor_clicked_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,move,*", "elm.text",
+     _entry_anchor_move_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,in,*", "elm.text",
+     _entry_anchor_in_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "anchor,mouse,out,*", "elm.text",
+     _entry_anchor_out_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,key,enter", "elm.text",
+     _entry_key_enter_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,key,escape", "elm.text",
+     _entry_key_escape_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "mouse,down,1", "elm.text",
+     _entry_mouse_down_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "mouse,clicked,1", "elm.text",
+     _entry_mouse_clicked_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "mouse,down,1,double", "elm.text",
+     _entry_mouse_double_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "mouse,down,1,triple", "elm.text",
+     _entry_mouse_triple_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,undo,request", "elm.text",
+     _entry_undo_request_signal_cb, obj);
+   edje_object_signal_callback_add
+     (priv->entry_edje, "entry,redo,request", "elm.text",
+     _entry_redo_request_signal_cb, obj);
+
+   elm_layout_text_set(obj, "elm.text", "");
+
+   elm_object_sub_cursor_set
+     (wd->resize_obj, obj, ELM_CURSOR_XTERM);
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+   if (_elm_config->desktop_entry)
+     edje_object_part_text_select_allow_set
+       (priv->entry_edje, "elm.text", EINA_TRUE);
+
+   elm_layout_sizing_eval(obj);
+
+   efl_ui_text_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
+   efl_ui_text_input_panel_enabled_set(obj, EINA_TRUE);
+   efl_ui_text_prediction_allow_set(obj, EINA_TRUE);
+   efl_ui_text_input_hint_set(obj, ELM_INPUT_HINT_AUTO_COMPLETE);
+
+   priv->autocapital_type = (Elm_Autocapital_Type)edje_object_part_text_autocapital_type_get
+       (priv->entry_edje, "elm.text");
+
+   entries = eina_list_prepend(entries, obj);
+
+   // module - find module for entry
+   priv->api = _module_find(obj);
+   // if found - hook in
+   if ((priv->api) && (priv->api->obj_hook)) priv->api->obj_hook(obj);
+
+   _mirrored_set(obj, elm_widget_mirrored_get(obj));
+
+   // access
+   _elm_access_object_register(obj, priv->entry_edje);
+   _elm_access_text_set
+     (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("Entry"));
+   _elm_access_callback_set
+     (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
+   _elm_access_callback_set
+     (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, NULL);
+
+   if (_elm_config->desktop_entry)
+     priv->sel_handler_disabled = EINA_TRUE;
+
+   _create_text_cursors(priv);
+}
+
+static void
+_create_selection_handlers(Evas_Object *obj, Efl_Ui_Text_Data *sd)
+{
+   Evas_Object *handle;
+   const char *style = elm_widget_style_get(obj);
+
+   handle = edje_object_add(evas_object_evas_get(obj));
+   sd->start_handler = handle;
+   _elm_theme_object_set(obj, handle, "entry", "handler/start", style);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _start_handler_mouse_down_cb, obj);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
+                                  _start_handler_mouse_move_cb, obj);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP,
+                                  _start_handler_mouse_up_cb, obj);
+   evas_object_show(handle);
+
+   handle = edje_object_add(evas_object_evas_get(obj));
+   sd->end_handler = handle;
+   _elm_theme_object_set(obj, handle, "entry", "handler/end", style);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _end_handler_mouse_down_cb, obj);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_MOVE,
+                                  _end_handler_mouse_move_cb, obj);
+   evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP,
+                                  _end_handler_mouse_up_cb, obj);
+   evas_object_show(handle);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_del(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   Elm_Entry_Context_Menu_Item *it;
+   Elm_Entry_Item_Provider *ip;
+   Elm_Entry_Markup_Filter *tf;
+
+   if (sd->delay_write)
+     {
+        ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
+        if (sd->auto_save) _save_do(obj);
+     }
+
+   if (sd->scroll)
+     elm_interface_scrollable_content_viewport_resize_cb_set(obj, NULL);
+
+   _efl_ui_text_anchor_hover_end(obj, sd);
+   _efl_ui_text_anchor_hover_parent_set(obj, sd, NULL);
+
+   evas_event_freeze(evas_object_evas_get(obj));
+
+   eina_stringshare_del(sd->file);
+
+   ecore_job_del(sd->hov_deljob);
+   if ((sd->api) && (sd->api->obj_unhook))
+     sd->api->obj_unhook(obj);  // module - unhook
+
+   evas_object_del(sd->mgf_proxy);
+   evas_object_del(sd->mgf_bg);
+   evas_object_del(sd->mgf_clip);
+
+   entries = eina_list_remove(entries, obj);
+   eina_stringshare_del(sd->cut_sel);
+   eina_stringshare_del(sd->text);
+   ecore_job_del(sd->deferred_recalc_job);
+   if (sd->append_text_idler)
+     {
+        ecore_idler_del(sd->append_text_idler);
+        ELM_SAFE_FREE(sd->append_text_left, free);
+        sd->append_text_idler = NULL;
+     }
+   ecore_timer_del(sd->longpress_timer);
+   EINA_LIST_FREE(sd->items, it)
+     {
+        eina_stringshare_del(it->label);
+        eina_stringshare_del(it->icon_file);
+        eina_stringshare_del(it->icon_group);
+        free(it);
+     }
+   EINA_LIST_FREE(sd->item_providers, ip)
+     {
+        free(ip);
+     }
+   EINA_LIST_FREE(sd->markup_filters, tf)
+     {
+        _filter_free(tf);
+     }
+   ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
+   free(sd->input_panel_imdata);
+   eina_stringshare_del(sd->anchor_hover.hover_style);
+
+   evas_event_thaw(evas_object_evas_get(obj));
+   evas_event_thaw_eval(evas_object_evas_get(obj));
+
+   if (sd->start_handler)
+     {
+        evas_object_del(sd->start_handler);
+        evas_object_del(sd->end_handler);
+     }
+
+   evas_obj_smart_del(eo_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_move(Eo *obj, Efl_Ui_Text_Data *sd, Evas_Coord x, Evas_Coord y)
+{
+   evas_obj_smart_move(eo_super(obj, MY_CLASS), x, y);
+
+   evas_object_move(sd->hit_rect, x, y);
+
+   if (sd->hoversel) _hoversel_position(obj);
+
+   if (edje_object_part_text_selection_get(sd->entry_edje, "elm.text"))
+     _update_selection_handler(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_resize(Eo *obj, Efl_Ui_Text_Data *sd, Evas_Coord w, Evas_Coord h)
+{
+   evas_obj_smart_resize(eo_super(obj, MY_CLASS), w, h);
+
+   evas_object_resize(sd->hit_rect, w, h);
+   if (sd->have_selection)
+     _update_selection_handler(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_show(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   evas_obj_smart_show(eo_super(obj, MY_CLASS));
+
+   if (sd->have_selection)
+     _update_selection_handler(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_hide(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   evas_obj_smart_hide(eo_super(obj, MY_CLASS));
+
+   if (sd->have_selection)
+     _hide_selection_handler(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_evas_object_smart_member_add(Eo *obj, Efl_Ui_Text_Data *sd, Evas_Object *member)
+{
+   evas_obj_smart_member_add(eo_super(obj, MY_CLASS), member);
+
+   if (sd->hit_rect)
+     evas_object_raise(sd->hit_rect);
+}
+
+EOLIAN static const Elm_Layout_Part_Alias_Description *
+_efl_ui_text_elm_layout_content_aliases_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd EINA_UNUSED)
+{
+   return _content_aliases;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_layout_theme_enable(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_cb_added(void *data EINA_UNUSED, const Eo_Event *ev)
+{
+   const Eo_Callback_Array_Item *event = ev->info;
+
+   EFL_UI_TEXT_DATA_GET(ev->object, sd);
+   if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE)
+     sd->validators++;
+   return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+_cb_deleted(void *data EINA_UNUSED, const Eo_Event *ev)
+{
+   const Eo_Callback_Array_Item *event = ev->info;
+
+   EFL_UI_TEXT_DATA_GET(ev->object, sd);
+   if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE)
+     sd->validators--;
+   return EO_CALLBACK_CONTINUE;
+
+}
+
+EOLIAN static Eo *
+_efl_ui_text_eo_base_constructor(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   obj = eo_constructor(eo_super(obj, MY_CLASS));
+   evas_obj_type_set(obj, MY_CLASS_NAME_LEGACY);
+   evas_obj_smart_callbacks_descriptions_set(obj, _smart_callbacks);
+   elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_ENTRY);
+   eo_event_callback_add(obj, EO_EVENT_CALLBACK_ADD, _cb_added, NULL);
+   eo_event_callback_add(obj, EO_EVENT_CALLBACK_DEL, _cb_deleted, NULL);
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_text_password_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool password)
+{
+   password = !!password;
+
+   if (sd->password == password) return;
+   sd->password = password;
+
+   elm_drop_target_del(obj, sd->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+   if (password)
+     {
+        sd->single_line = EINA_TRUE;
+        sd->line_wrap = ELM_WRAP_NONE;
+        efl_ui_text_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA));
+        _entry_selection_callbacks_unregister(obj);
+        elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_PASSWORD_TEXT);
+     }
+   else
+     {
+        sd->drop_format = _get_drop_format(obj);
+        elm_drop_target_add(obj, sd->drop_format,
+                            _dnd_enter_cb, NULL,
+                            _dnd_leave_cb, NULL,
+                            _dnd_pos_cb, NULL,
+                            _dnd_drop_cb, NULL);
+
+        efl_ui_text_input_hint_set(obj, ((sd->input_hints | ELM_INPUT_HINT_AUTO_COMPLETE) & ~ELM_INPUT_HINT_SENSITIVE_DATA));
+        _entry_selection_callbacks_register(obj);
+        elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_ENTRY);
+     }
+
+   elm_obj_widget_theme_apply(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_password_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->password;
+}
+
+static Evas_Object*
+_efl_ui_text_textblock_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return (Evas_Object *)edje_object_part_object_get
+        (sd->entry_edje, "elm.text");
+}
+
+static void
+_efl_ui_text_calc_force(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   edje_object_calc_force(sd->entry_edje);
+   sd->changed = EINA_TRUE;
+   elm_layout_sizing_eval(obj);
+}
+
+static const char*
+_efl_ui_text_selection_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   Efl_Canvas_Text_Cursor *start_obj, *end_obj;
+
+   if ((sd->password)) return NULL;
+
+   efl_ui_text_interactive_selection_cursors_get(obj, &start_obj, &end_obj);
+   return efl_canvas_text_range_text_get(obj, start_obj, end_obj);
+}
+
+EOLIAN static void
+_efl_ui_text_selection_handler_disabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool disabled)
+{
+   if (sd->sel_handler_disabled == disabled) return;
+   sd->sel_handler_disabled = disabled;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_selection_handler_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->sel_handler_disabled;
+}
+
+static void
+_efl_ui_text_entry_insert(Eo *obj, Efl_Ui_Text_Data *sd, const char *entry)
+{
+   Efl_Canvas_Text_Cursor *cur_obj = efl_canvas_text_cursor_get(obj);
+   efl_canvas_text_cursor_text_insert(cur_obj, entry);
+   sd->changed = EINA_TRUE;
+   elm_layout_sizing_eval(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_editable_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool editable)
+{
+   if (sd->editable == editable) return;
+   sd->editable = editable;
+   elm_obj_widget_theme_apply(obj);
+
+   elm_drop_target_del(obj, sd->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+   if (editable)
+     {
+        sd->drop_format = _get_drop_format(obj);
+        elm_drop_target_add(obj, sd->drop_format,
+                            _dnd_enter_cb, NULL,
+                            _dnd_leave_cb, NULL,
+                            _dnd_pos_cb, NULL,
+                            _dnd_drop_cb, NULL);
+     }
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_editable_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->editable;
+}
+
+static void
+_efl_ui_text_select_none(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   if ((sd->password)) return;
+   if (sd->sel_mode)
+     {
+        sd->sel_mode = EINA_FALSE;
+        if (!_elm_config->desktop_entry)
+          edje_object_part_text_select_allow_set
+            (sd->entry_edje, "elm.text", EINA_FALSE);
+        edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+     }
+   if (sd->have_selection)
+     eo_event_callback_call
+       (obj, EVAS_SELECTABLE_INTERFACE_EVENT_SELECTION_CLEARED, NULL);
+
+   sd->have_selection = EINA_FALSE;
+   edje_object_part_text_select_none(sd->entry_edje, "elm.text");
+
+   _hide_selection_handler(obj);
+}
+
+static void
+_efl_ui_text_select_all(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   if ((sd->password)) return;
+   if (sd->sel_mode)
+     {
+        sd->sel_mode = EINA_FALSE;
+        if (!_elm_config->desktop_entry)
+          edje_object_part_text_select_allow_set
+            (sd->entry_edje, "elm.text", EINA_FALSE);
+        edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+     }
+   edje_object_part_text_select_all(sd->entry_edje, "elm.text");
+}
+
+static void
+_efl_ui_text_select_region_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, int start, int end)
+{
+   if ((sd->password)) return;
+   if (sd->sel_mode)
+     {
+        sd->sel_mode = EINA_FALSE;
+        if (!_elm_config->desktop_entry)
+          edje_object_part_text_select_allow_set
+            (sd->entry_edje, "elm.text", EINA_FALSE);
+        edje_object_signal_emit(sd->entry_edje, "elm,state,select,off", "elm");
+     }
+
+   /* Set have selection false to not be cleared handler in
+      selection_cleared_signal_cb() since that callback will be called while
+      resetting edje text. */
+   sd->have_selection = EINA_FALSE;
+
+   edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, start);
+   edje_object_part_text_select_begin(sd->entry_edje, "elm.text");
+   edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text", EDJE_CURSOR_MAIN, end);
+   edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
+}
+
+EOLIAN static void
+_efl_ui_text_cursor_selection_end(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   edje_object_part_text_select_extend(sd->entry_edje, "elm.text");
+}
+
+EOLIAN static void
+_efl_ui_text_selection_cut(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   if ((sd->password)) return;
+   _cut_cb(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_selection_copy(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   if ((sd->password)) return;
+   _copy_cb(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_selection_paste(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   if ((sd->password)) return;
+   _paste_cb(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_context_menu_clear(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   Elm_Entry_Context_Menu_Item *it;
+
+   EINA_LIST_FREE(sd->items, it)
+     {
+        eina_stringshare_del(it->label);
+        eina_stringshare_del(it->icon_file);
+        eina_stringshare_del(it->icon_group);
+        free(it);
+     }
+}
+
+EOLIAN static void
+_efl_ui_text_context_menu_item_add(Eo *obj, Efl_Ui_Text_Data *sd, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
+{
+   Elm_Entry_Context_Menu_Item *it;
+
+   it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
+   if (!it) return;
+
+   sd->items = eina_list_append(sd->items, it);
+   it->obj = obj;
+   it->label = eina_stringshare_add(label);
+   it->icon_file = eina_stringshare_add(icon_file);
+   it->icon_type = icon_type;
+   it->func = func;
+   it->data = (void *)data;
+}
+
+EOLIAN static void
+_efl_ui_text_context_menu_disabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool disabled)
+{
+   if (sd->context_menu == !disabled) return;
+   sd->context_menu = !disabled;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_context_menu_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return !sd->context_menu;
+}
+
+EOLIAN static void
+_efl_ui_text_item_provider_append(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
+{
+   Elm_Entry_Item_Provider *ip;
+
+   EINA_SAFETY_ON_NULL_RETURN(func);
+
+   ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
+   if (!ip) return;
+
+   ip->func = func;
+   ip->data = data;
+   sd->item_providers = eina_list_append(sd->item_providers, ip);
+}
+
+EOLIAN static void
+_efl_ui_text_item_provider_prepend(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
+{
+   Elm_Entry_Item_Provider *ip;
+
+   EINA_SAFETY_ON_NULL_RETURN(func);
+
+   ip = calloc(1, sizeof(Elm_Entry_Item_Provider));
+   if (!ip) return;
+
+   ip->func = func;
+   ip->data = data;
+   sd->item_providers = eina_list_prepend(sd->item_providers, ip);
+}
+
+EOLIAN static void
+_efl_ui_text_item_provider_remove(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Entry_Item_Provider_Cb func, void *data)
+{
+   Eina_List *l;
+   Elm_Entry_Item_Provider *ip;
+
+   EINA_SAFETY_ON_NULL_RETURN(func);
+
+   EINA_LIST_FOREACH(sd->item_providers, l, ip)
+     {
+        if ((ip->func == func) && ((!data) || (ip->data == data)))
+          {
+             sd->item_providers = eina_list_remove_list(sd->item_providers, l);
+             free(ip);
+             return;
+          }
+     }
+}
+
+#if 0
+static const char *
+_text_get(const Evas_Object *obj)
+{
+   return elm_object_text_get(obj);
+}
+#endif
+
+EOLIAN static Eina_Bool
+_efl_ui_text_efl_file_file_set(Eo *obj, Efl_Ui_Text_Data *sd, const char *file, const char *group EINA_UNUSED)
+{
+   ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
+   if (sd->auto_save) _save_do(obj);
+   eina_stringshare_replace(&sd->file, file);
+   Eina_Bool int_ret = _load_do(obj);
+   return int_ret;
+}
+
+EOLIAN static void
+_efl_ui_text_efl_file_file_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, const char **file, const char **group)
+{
+   if (file) *file = sd->file;
+   if (group) *group = NULL;
+}
+
+EOLIAN static void
+_efl_ui_text_cnp_mode_set(Eo *obj, Efl_Ui_Text_Data *sd, Elm_Cnp_Mode cnp_mode)
+{
+   Elm_Sel_Format format = ELM_SEL_FORMAT_MARKUP;
+
+
+   if (sd->cnp_mode == cnp_mode) return;
+   sd->cnp_mode = cnp_mode;
+   if (sd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
+     format = ELM_SEL_FORMAT_TEXT;
+   else if (cnp_mode == ELM_CNP_MODE_MARKUP)
+     format |= ELM_SEL_FORMAT_IMAGE;
+
+   elm_drop_target_del(obj, sd->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+   sd->drop_format = format;
+   elm_drop_target_add(obj, sd->drop_format,
+                       _dnd_enter_cb, NULL,
+                       _dnd_leave_cb, NULL,
+                       _dnd_pos_cb, NULL,
+                       _dnd_drop_cb, NULL);
+}
+
+EOLIAN static Elm_Cnp_Mode
+_efl_ui_text_cnp_mode_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->cnp_mode;
+}
+
+static void
+_efl_ui_text_content_viewport_resize_cb(Evas_Object *obj,
+                                      Evas_Coord w EINA_UNUSED, Evas_Coord h EINA_UNUSED)
+{
+   _efl_ui_text_resize_internal(obj);
+}
+
+static void
+_scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   /* here we need to emit the signal that the elm_scroller would have done */
+   eo_event_callback_call
+     (obj, EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, NULL);
+
+   if (sd->have_selection)
+     _update_selection_handler(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_scrollable_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool scroll)
+{
+   scroll = !!scroll;
+   if (sd->scroll == scroll) return;
+   sd->scroll = scroll;
+
+   if (sd->scroll)
+     {
+        /* we now must re-theme ourselves to a scroller decoration
+         * and move the entry looking object to be the content of the
+         * scrollable view */
+        elm_widget_resize_object_set(obj, NULL, EINA_TRUE);
+        elm_widget_sub_object_add(obj, sd->entry_edje);
+
+        if (!sd->scr_edje)
+          {
+             sd->scr_edje = edje_object_add(evas_object_evas_get(obj));
+
+             elm_widget_theme_object_set
+               (obj, sd->scr_edje, "scroller", "entry",
+               elm_widget_style_get(obj));
+
+             evas_object_size_hint_weight_set
+               (sd->scr_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+             evas_object_size_hint_align_set
+               (sd->scr_edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+             evas_object_propagate_events_set(sd->scr_edje, EINA_TRUE);
+          }
+
+        elm_widget_resize_object_set(obj, sd->scr_edje, EINA_TRUE);
+
+        elm_interface_scrollable_objects_set(obj, sd->scr_edje, sd->hit_rect);
+
+        elm_interface_scrollable_scroll_cb_set(obj, _scroll_cb);
+
+        elm_interface_scrollable_bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
+        if (sd->single_line)
+           elm_interface_scrollable_policy_set(obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+        else
+           elm_interface_scrollable_policy_set(obj, sd->policy_h, sd->policy_v);
+        elm_interface_scrollable_content_set(obj, sd->entry_edje);
+        elm_interface_scrollable_content_viewport_resize_cb_set(obj, _efl_ui_text_content_viewport_resize_cb);
+        elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
+     }
+   else
+     {
+        if (sd->scr_edje)
+          {
+             elm_interface_scrollable_content_set(obj, NULL);
+             evas_object_hide(sd->scr_edje);
+          }
+        elm_widget_resize_object_set(obj, sd->entry_edje, EINA_TRUE);
+
+        if (sd->scr_edje)
+          elm_widget_sub_object_add(obj, sd->scr_edje);
+
+        elm_interface_scrollable_objects_set(obj, sd->entry_edje, sd->hit_rect);
+
+        elm_widget_on_show_region_hook_set(obj, NULL, NULL);
+     }
+   sd->last_w = -1;
+   _update_decorations(obj);
+   elm_obj_widget_theme_apply(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_scrollable_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->scroll;
+}
+
+EOLIAN static void
+_efl_ui_text_elm_interface_scrollable_policy_set(Eo *obj, Efl_Ui_Text_Data *sd, Elm_Scroller_Policy h, Elm_Scroller_Policy v)
+{
+   sd->policy_h = h;
+   sd->policy_v = v;
+   elm_interface_scrollable_policy_set(eo_super(obj, MY_CLASS), sd->policy_h, sd->policy_v);
+}
+
+EOLIAN static void
+_efl_ui_text_elm_interface_scrollable_bounce_allow_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+   sd->h_bounce = h_bounce;
+   sd->v_bounce = v_bounce;
+   elm_interface_scrollable_bounce_allow_set(eo_super(obj, MY_CLASS), h_bounce, v_bounce);
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_layout_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Input_Panel_Layout layout)
+{
+   sd->input_panel_layout = layout;
+
+   edje_object_part_text_input_panel_layout_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Panel_Layout)layout);
+
+   if (layout == ELM_INPUT_PANEL_LAYOUT_PASSWORD)
+     efl_ui_text_input_hint_set(obj, ((sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE) | ELM_INPUT_HINT_SENSITIVE_DATA));
+   else if (layout == ELM_INPUT_PANEL_LAYOUT_TERMINAL)
+     efl_ui_text_input_hint_set(obj, (sd->input_hints & ~ELM_INPUT_HINT_AUTO_COMPLETE));
+}
+
+EOLIAN static Elm_Input_Panel_Layout
+_efl_ui_text_input_panel_layout_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_layout;
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_layout_variation_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, int variation)
+{
+   sd->input_panel_layout_variation = variation;
+
+   edje_object_part_text_input_panel_layout_variation_set
+     (sd->entry_edje, "elm.text", variation);
+}
+
+EOLIAN static int
+_efl_ui_text_input_panel_layout_variation_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_layout_variation;
+}
+
+EOLIAN static void
+_efl_ui_text_autocapital_type_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Autocapital_Type autocapital_type)
+{
+   sd->autocapital_type = autocapital_type;
+   edje_object_part_text_autocapital_type_set
+     (sd->entry_edje, "elm.text", (Edje_Text_Autocapital_Type)autocapital_type);
+}
+
+EOLIAN static Elm_Autocapital_Type
+_efl_ui_text_autocapital_type_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->autocapital_type;
+}
+
+EOLIAN static void
+_efl_ui_text_prediction_allow_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool prediction)
+{
+   sd->prediction_allow = prediction;
+   edje_object_part_text_prediction_allow_set
+     (sd->entry_edje, "elm.text", prediction);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_prediction_allow_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->prediction_allow;
+}
+
+EOLIAN static void
+_efl_ui_text_input_hint_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Input_Hints hints)
+{
+   sd->input_hints = hints;
+
+   edje_object_part_text_input_hint_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Hints)hints);
+}
+
+EOLIAN static Elm_Input_Hints
+_efl_ui_text_input_hint_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_hints;
+}
+
+EOLIAN static void
+_efl_ui_text_imf_context_reset(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   edje_object_part_text_imf_context_reset(sd->entry_edje, "elm.text");
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_enabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool enabled)
+{
+   sd->input_panel_enable = enabled;
+   edje_object_part_text_input_panel_enabled_set
+     (sd->entry_edje, "elm.text", enabled);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_input_panel_enabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_enable;
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_show(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   edje_object_part_text_input_panel_show(sd->entry_edje, "elm.text");
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_hide(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+
+   edje_object_part_text_input_panel_hide(sd->entry_edje, "elm.text");
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_language_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Input_Panel_Lang lang)
+{
+   sd->input_panel_lang = lang;
+   edje_object_part_text_input_panel_language_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Panel_Lang)lang);
+}
+
+EOLIAN static Elm_Input_Panel_Lang
+_efl_ui_text_input_panel_language_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_lang;
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_imdata_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, const void *data, int len)
+{
+   free(sd->input_panel_imdata);
+
+   sd->input_panel_imdata = calloc(1, len);
+   sd->input_panel_imdata_len = len;
+   memcpy(sd->input_panel_imdata, data, len);
+
+   edje_object_part_text_input_panel_imdata_set
+     (sd->entry_edje, "elm.text", sd->input_panel_imdata,
+     sd->input_panel_imdata_len);
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_imdata_get(const Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, void *data, int *len)
+{
+   edje_object_part_text_input_panel_imdata_get
+     (sd->entry_edje, "elm.text", data, len);
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_return_key_type_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Elm_Input_Panel_Return_Key_Type return_key_type)
+{
+   sd->input_panel_return_key_type = return_key_type;
+
+   edje_object_part_text_input_panel_return_key_type_set
+     (sd->entry_edje, "elm.text", (Edje_Input_Panel_Return_Key_Type)return_key_type);
+}
+
+EOLIAN static Elm_Input_Panel_Return_Key_Type
+_efl_ui_text_input_panel_return_key_type_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_return_key_type;
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_return_key_disabled_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool disabled)
+{
+   sd->input_panel_return_key_disabled = disabled;
+
+   edje_object_part_text_input_panel_return_key_disabled_set
+     (sd->entry_edje, "elm.text", disabled);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_input_panel_return_key_disabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_return_key_disabled;
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_return_key_autoenabled_set(Eo *obj, Efl_Ui_Text_Data *sd, Eina_Bool enabled)
+{
+   sd->auto_return_key = enabled;
+   _return_key_enabled_check(obj);
+}
+
+EOLIAN static void
+_efl_ui_text_input_panel_show_on_demand_set(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd, Eina_Bool ondemand)
+{
+   sd->input_panel_show_on_demand = ondemand;
+
+   edje_object_part_text_input_panel_show_on_demand_set
+     (sd->entry_edje, "elm.text", ondemand);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_input_panel_show_on_demand_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   return sd->input_panel_show_on_demand;
+}
+
+EOLIAN static void*
+_efl_ui_text_imf_context_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   if (!sd) return NULL;
+
+   return edje_object_part_text_imf_context_get(sd->entry_edje, "elm.text");
+}
+
+/* START - ANCHOR HOVER */
+static void
+_anchor_parent_del_cb(void *data,
+                      Evas *e EINA_UNUSED,
+                      Evas_Object *obj EINA_UNUSED,
+                      void *event_info EINA_UNUSED)
+{
+   EFL_UI_TEXT_DATA_GET(data, sd);
+
+   sd->anchor_hover.hover_parent = NULL;
+}
+
+static void
+_efl_ui_text_anchor_hover_parent_set(Eo *obj, Efl_Ui_Text_Data *sd, Evas_Object *parent)
+{
+   if (sd->anchor_hover.hover_parent)
+     evas_object_event_callback_del_full
+       (sd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL,
+       _anchor_parent_del_cb, obj);
+   sd->anchor_hover.hover_parent = parent;
+   if (sd->anchor_hover.hover_parent)
+     evas_object_event_callback_add
+       (sd->anchor_hover.hover_parent, EVAS_CALLBACK_DEL,
+       _anchor_parent_del_cb, obj);
+}
+
+static void
+_efl_ui_text_anchor_hover_end(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *sd)
+{
+   ELM_SAFE_FREE(sd->anchor_hover.hover, evas_object_del);
+   ELM_SAFE_FREE(sd->anchor_hover.pop, evas_object_del);
+}
+/* END - ANCHOR HOVER */
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_activate(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Elm_Activate act)
+{
+   if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   if (!elm_widget_disabled_get(obj) &&
+       !evas_object_freeze_events_get(obj))
+     {
+        eo_event_callback_call
+          (obj, EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED, NULL);
+        if (sd->editable && sd->input_panel_enable)
+          edje_object_part_text_input_panel_show(sd->entry_edje, "elm.text");
+     }
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   return EINA_FALSE;
+}
+
+static void
+_efl_ui_text_class_constructor(Eo_Class *klass)
+{
+   evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+// ATSPI Accessibility
+
+EOLIAN static Eina_Unicode
+_efl_ui_text_elm_interface_atspi_text_character_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int offset)
+{
+#if 0
+   char *txt;
+   int idx = 0;
+   Eina_Unicode ret = 0;
+   if (offset < 0) return ret;
+
+   txt = _elm_util_mkup_to_text(efl_ui_text_entry_get(obj));
+   if (!txt) return ret;
+
+   ret = eina_unicode_utf8_next_get(txt, &idx);
+   while (offset--) ret = eina_unicode_utf8_next_get(txt, &idx);
+
+   free(txt);
+
+   if (_pd->password)
+     ret = ENTRY_PASSWORD_MASK_CHARACTER;
+
+   return ret;
+#else
+   (void) obj;
+   (void) _pd;
+   (void) offset;
+   return 0;
+#endif
+}
+
+EOLIAN static int
+_efl_ui_text_elm_interface_atspi_text_character_count_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+#if 0
+   char *txt;
+   int ret = -1;
+
+   txt = _elm_util_mkup_to_text(efl_ui_text_entry_get(obj));
+   if (!txt) return ret;
+
+   ret = eina_unicode_utf8_get_len(txt);
+   free(txt);
+
+   return ret;
+#else
+   (void) obj;
+   (void) _pd;
+   return 0;
+#endif
+}
+
+EOLIAN static char*
+_efl_ui_text_elm_interface_atspi_text_string_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Elm_Atspi_Text_Granularity granularity, int *start_offset, int *end_offset)
+{
+   Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
+   Evas_Object *tblk;
+   char *ret = NULL;
+
+   tblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!tblk) goto fail;
+
+   cur = evas_object_textblock_cursor_new(tblk);
+   cur2 = evas_object_textblock_cursor_new(tblk);
+   if (!cur || !cur2) goto fail;
+
+   evas_textblock_cursor_pos_set(cur, *start_offset);
+   if (evas_textblock_cursor_pos_get(cur) != *start_offset) goto fail;
+
+   switch (granularity)
+     {
+      case ELM_ATSPI_TEXT_GRANULARITY_CHAR:
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_WORD:
+         evas_textblock_cursor_word_start(cur);
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE:
+         // TODO - add sentence support in textblock first
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_LINE:
+         evas_textblock_cursor_line_char_first(cur);
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH:
+         evas_textblock_cursor_paragraph_char_first(cur);
+         break;
+     }
+
+   *start_offset = evas_textblock_cursor_pos_get(cur);
+   evas_textblock_cursor_copy(cur, cur2);
+
+   switch (granularity)
+     {
+      case ELM_ATSPI_TEXT_GRANULARITY_CHAR:
+         evas_textblock_cursor_char_next(cur2);
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_WORD:
+         evas_textblock_cursor_word_end(cur2);
+         // since word_end sets cursor position ON (before) last
+         // char of word, we need to manually advance cursor to get
+         // proper string from function range_text_get
+         evas_textblock_cursor_char_next(cur2);
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE:
+         // TODO - add sentence support in textblock first
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_LINE:
+         evas_textblock_cursor_line_char_last(cur2);
+         break;
+      case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH:
+         evas_textblock_cursor_paragraph_char_last(cur2);
+         break;
+     }
+
+   if (end_offset) *end_offset = evas_textblock_cursor_pos_get(cur2);
+
+   ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
+
+   evas_textblock_cursor_free(cur);
+   evas_textblock_cursor_free(cur2);
+
+   if (ret && _pd->password)
+     {
+        int i = 0;
+        while (ret[i] != '\0')
+         ret[i++] = ENTRY_PASSWORD_MASK_CHARACTER;
+     }
+
+   return ret;
+
+fail:
+   if (start_offset) *start_offset = -1;
+   if (end_offset) *end_offset = -1;
+   if (cur) evas_textblock_cursor_free(cur);
+   if (cur2) evas_textblock_cursor_free(cur2);
+   return NULL;
+}
+
+EOLIAN static char*
+_efl_ui_text_elm_interface_atspi_text_text_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
+{
+   Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
+   Evas_Object *tblk;
+   char *ret = NULL;
+
+   tblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!tblk) goto fail;
+
+   cur = evas_object_textblock_cursor_new(tblk);
+   cur2 = evas_object_textblock_cursor_new(tblk);
+   if (!cur || !cur2) goto fail;
+
+   evas_textblock_cursor_pos_set(cur, start_offset);
+   if (evas_textblock_cursor_pos_get(cur) != start_offset) goto fail;
+
+   evas_textblock_cursor_pos_set(cur2, end_offset);
+   if (evas_textblock_cursor_pos_get(cur2) != end_offset) goto fail;
+
+   ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
+
+   evas_textblock_cursor_free(cur);
+   evas_textblock_cursor_free(cur2);
+
+   if (ret && _pd->password)
+     {
+        int i = 0;
+        while (ret[i] != '\0')
+         ret[i++] = ENTRY_PASSWORD_MASK_CHARACTER;
+     }
+
+   return ret;
+
+fail:
+   if (cur) evas_textblock_cursor_free(cur);
+   if (cur2) evas_textblock_cursor_free(cur2);
+   return NULL;
+}
+
+EOLIAN static int
+_efl_ui_text_elm_interface_atspi_text_caret_offset_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   return efl_canvas_text_cursor_position_get(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_caret_offset_set(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int offset)
+{
+   efl_canvas_text_cursor_position_set(obj, offset);
+   return EINA_TRUE;
+}
+
+EOLIAN static int
+_efl_ui_text_elm_interface_atspi_text_selections_count_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   return _efl_ui_text_selection_get(obj, _pd) ? 1 : 0;
+}
+
+EOLIAN static void
+_efl_ui_text_elm_interface_atspi_text_selection_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int selection_number, int *start_offset, int *end_offset)
+{
+   if (selection_number != 0) return;
+
+   elm_obj_entry_select_region_get(obj, start_offset, end_offset);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_selection_set(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int selection_number, int start_offset, int end_offset)
+{
+   if (selection_number != 0) return EINA_FALSE;
+
+   _efl_ui_text_select_region_set(obj, _pd, start_offset, end_offset);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_selection_remove(Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED, int selection_number)
+{
+   if (selection_number != 0) return EINA_FALSE;
+   _efl_ui_text_select_none(obj, pd);
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_selection_add(Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED, int start_offset, int end_offset)
+{
+   _efl_ui_text_select_region_set(obj, pd, start_offset, end_offset);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_List*
+_efl_ui_text_elm_interface_atspi_text_bounded_ranges_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *_pd EINA_UNUSED, Eina_Bool screen_coods EINA_UNUSED, Eina_Rectangle rect EINA_UNUSED, Elm_Atspi_Text_Clip_Type xclip EINA_UNUSED, Elm_Atspi_Text_Clip_Type yclip EINA_UNUSED)
+{
+   return NULL;
+}
+
+EOLIAN static int
+_efl_ui_text_elm_interface_atspi_text_offset_at_point_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int x, int y)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur;
+   int ret;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return -1;
+
+   cur = evas_object_textblock_cursor_new(txtblk);
+   if (!cur) return -1;
+
+   if (screen_coods)
+     {
+        int ee_x, ee_y;
+        Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+        ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
+        x -= ee_x;
+        y -= ee_y;
+     }
+
+   if (!evas_textblock_cursor_char_coord_set(cur, x, y))
+     {
+        evas_textblock_cursor_free(cur);
+        return -1;
+     }
+
+   ret = evas_textblock_cursor_pos_get(cur);
+   evas_textblock_cursor_free(cur);
+
+   return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_character_extents_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int offset, Eina_Bool screen_coods, Eina_Rectangle *rect)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur;
+   int ret;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return EINA_FALSE;
+
+   cur = evas_object_textblock_cursor_new(txtblk);
+   if (!cur) return EINA_FALSE;
+
+   evas_textblock_cursor_pos_set(cur, offset);
+
+   ret = evas_textblock_cursor_char_geometry_get(cur, &rect->x, &rect->y, &rect->w, &rect->h);
+   evas_textblock_cursor_free(cur);
+
+   if (ret == -1) return EINA_FALSE;
+
+   if (screen_coods)
+     {
+        int ee_x, ee_y;
+        Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+        ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
+        rect->x += ee_x;
+        rect->y += ee_y;
+     }
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_range_extents_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int start_offset, int end_offset, Eina_Rectangle *rect)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur1, *cur2;
+   int ret;
+   int x, xx, y, yy;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return EINA_FALSE;
+
+   cur1 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur1) return EINA_FALSE;
+
+   cur2 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur2)
+     {
+        evas_textblock_cursor_free(cur1);
+        return EINA_FALSE;
+     }
+
+   evas_textblock_cursor_pos_set(cur1, start_offset);
+   evas_textblock_cursor_pos_set(cur2, end_offset);
+
+   ret = evas_textblock_cursor_char_geometry_get(cur1, &x, &y, NULL, NULL);
+   ret += evas_textblock_cursor_char_geometry_get(cur2, &xx, &yy, NULL, NULL);
+
+   evas_textblock_cursor_free(cur1);
+   evas_textblock_cursor_free(cur2);
+
+   if (ret != 0) return EINA_FALSE;
+
+   rect->x = x < xx ? x : xx;
+   rect->y = y < yy ? y : yy;
+   rect->w = abs(x - xx);
+   rect->h = abs(y - yy);
+
+   if (screen_coods)
+     {
+        int ee_x, ee_y;
+        Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+        ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
+        rect->x += ee_x;
+        rect->y += ee_y;
+     }
+
+   return EINA_TRUE;
+}
+
+static Elm_Atspi_Text_Attribute*
+_textblock_node_format_to_atspi_text_attr(const Evas_Object_Textblock_Node_Format *format)
+{
+   Elm_Atspi_Text_Attribute *ret = NULL;
+   const char *txt;
+
+   txt = evas_textblock_node_format_text_get(format);
+   if (!txt) return NULL;
+
+   if (txt[0] == '-') return NULL; // skip closing format
+
+   if (!strncmp(txt, "+ ", 2))
+     {
+        const char *tmp = &txt[2];
+
+        while (*tmp != '\0' && *tmp != '=') tmp++;
+        if (*tmp++ != '=') return NULL;
+
+        ret = calloc(1, sizeof(Elm_Atspi_Text_Attribute));
+        if (!ret) return NULL;
+
+        ret->value = eina_stringshare_add(tmp);
+        int size = &txt[2] - tmp + 1;
+        ret->name = eina_stringshare_add_length(&txt[2], size > 0 ? size : -size);
+     }
+
+   return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_attribute_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur1, *cur2;
+   Eina_List *formats, *l;
+   Evas_Object_Textblock_Node_Format *format;
+   Elm_Atspi_Text_Attribute *attr;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return EINA_FALSE;
+
+   cur1 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur1) return EINA_FALSE;
+
+   cur2 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur2)
+     {
+        evas_textblock_cursor_free(cur1);
+        return EINA_FALSE;
+     }
+
+   evas_textblock_cursor_pos_set(cur1, *start_offset);
+   evas_textblock_cursor_pos_set(cur2, *end_offset);
+
+   formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
+
+   evas_textblock_cursor_free(cur1);
+   evas_textblock_cursor_free(cur2);
+
+   if (!formats) return EINA_FALSE;
+
+   EINA_LIST_FOREACH(formats, l , format)
+     {
+        attr = _textblock_node_format_to_atspi_text_attr(format);
+        if (!attr) continue;
+        if (!strcmp(attr->name, attr_name))
+          {
+             *value = attr->value ? strdup(attr->value) : NULL;
+             elm_atspi_text_text_attribute_free(attr);
+             return EINA_TRUE;
+          }
+        elm_atspi_text_text_attribute_free(attr);
+     }
+
+   return EINA_FALSE;
+}
+
+EOLIAN static Eina_List*
+_efl_ui_text_elm_interface_atspi_text_attributes_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int *start_offset, int *end_offset)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur1, *cur2;
+   Eina_List *formats, *ret = NULL, *l;
+   Evas_Object_Textblock_Node_Format *format;
+   Elm_Atspi_Text_Attribute *attr;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return NULL;
+
+   cur1 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur1) return NULL;
+
+   cur2 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur2)
+     {
+        evas_textblock_cursor_free(cur1);
+        return NULL;
+     }
+
+   evas_textblock_cursor_pos_set(cur1, *start_offset);
+   evas_textblock_cursor_pos_set(cur2, *end_offset);
+
+   formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
+
+   evas_textblock_cursor_free(cur1);
+   evas_textblock_cursor_free(cur2);
+
+   if (!formats) return NULL;
+
+   EINA_LIST_FOREACH(formats, l , format)
+     {
+        attr = _textblock_node_format_to_atspi_text_attr(format);
+        if (!attr) continue;
+        ret = eina_list_append(ret, attr);
+     }
+
+   return ret;
+}
+
+EOLIAN static Eina_List*
+_efl_ui_text_elm_interface_atspi_text_default_attributes_get(Eo *obj EINA_UNUSED, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   Evas_Object *txtblk;
+   Eina_List *ret = NULL;
+   const Evas_Object_Textblock_Node_Format *format;
+   Elm_Atspi_Text_Attribute *attr;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return NULL;
+
+   format = evas_textblock_node_format_first_get(txtblk);
+   if (!format) return NULL;
+
+   do
+     {
+        attr = _textblock_node_format_to_atspi_text_attr(format);
+        if (!attr) continue;
+        ret = eina_list_append(ret, attr);
+     }
+   while ((format = evas_textblock_node_format_next_get(format)) != NULL);
+
+   return ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_content_set(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *content)
+{
+#if 0
+   efl_ui_text_entry_set(obj, content);
+   return EINA_TRUE;
+#else
+   (void) obj;
+   (void) _pd;
+   (void) content;
+   return EINA_TRUE;
+#endif
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_insert(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *string, int position)
+{
+   Efl_Canvas_Text_Cursor *cur_obj = efl_canvas_text_cursor_get(obj);
+   efl_canvas_text_cursor_position_set(cur_obj, position);
+   _efl_ui_text_entry_insert(obj, _pd, string);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_copy(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int start, int end)
+{
+   _efl_ui_text_select_region_set(obj, _pd, start, end);
+   efl_ui_text_selection_copy(obj);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_delete(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
+{
+   Evas_Object *txtblk;
+   Evas_Textblock_Cursor *cur1, *cur2;
+
+   txtblk = _efl_ui_text_textblock_get(obj, _pd);
+   if (!txtblk) return EINA_FALSE;
+
+   cur1 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur1) return EINA_FALSE;
+
+   cur2 = evas_object_textblock_cursor_new(txtblk);
+   if (!cur2)
+     {
+        evas_textblock_cursor_free(cur1);
+        return EINA_FALSE;
+     }
+
+   evas_textblock_cursor_pos_set(cur1, start_offset);
+   evas_textblock_cursor_pos_set(cur2, end_offset);
+
+   evas_textblock_cursor_range_delete(cur1, cur2);
+
+   evas_textblock_cursor_free(cur1);
+   evas_textblock_cursor_free(cur2);
+
+   _efl_ui_text_calc_force(obj, _pd);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_paste(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int position)
+{
+   Efl_Canvas_Text_Cursor *cur_obj = efl_canvas_text_cursor_get(obj);
+   efl_canvas_text_cursor_position_set(cur_obj, position);
+   efl_ui_text_selection_paste(obj);
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_text_elm_interface_atspi_text_editable_cut(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, int start, int end)
+{
+   _efl_ui_text_select_region_set(obj, _pd, start, end);
+   efl_ui_text_selection_cut(obj);
+   return EINA_TRUE;
+}
+
+EOLIAN static Elm_Atspi_State_Set
+_efl_ui_text_elm_interface_atspi_accessible_state_set_get(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   ret = elm_interface_atspi_accessible_state_set_get(eo_super(obj, EFL_UI_TEXT_CLASS));
+
+   if (efl_ui_text_editable_get(obj))
+     STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EDITABLE);
+
+   return ret;
+}
+
+EOLIAN static char*
+_efl_ui_text_elm_interface_atspi_accessible_name_get(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+   char *name;
+   name = elm_interface_atspi_accessible_name_get(eo_super(obj, EFL_UI_TEXT_CLASS));
+   if (name && strncmp("", name, 1)) return name;
+   const char *ret = edje_object_part_text_get(sd->entry_edje, "elm.guide");
+   return ret ? strdup(ret) : NULL;
+}
+
+static inline Eo *
+_decoration_create(Efl_Ui_Text_Data *sd, const char *file,
+      const char *source, Eina_Bool above)
+{
+   Eo *ret = eo_add(EDJE_OBJECT_CLASS, sd->entry_edje);
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+   edje_object_file_set(ret, file, source);
+   evas_object_smart_member_add(ret, sd->entry_edje);
+   if (above)
+     {
+        evas_object_stack_above(ret, text_obj);
+     }
+   else
+     {
+        evas_object_stack_below(ret, text_obj);
+     }
+   evas_object_clip_set(ret, evas_object_clip_get(sd->entry_edje));
+   evas_object_pass_events_set(ret, EINA_TRUE);
+   return ret;
+}
+
+/**
+ * Creates the cursors, if not created.
+ */
+
+static void
+_create_text_cursors(Efl_Ui_Text_Data *sd)
+{
+   const char *file;
+   efl_file_get(sd->entry_edje, &file, NULL);
+   sd->cursor = _decoration_create(sd, file, "elm/entry/cursor/default", EINA_TRUE);
+   sd->cursor_bidi = _decoration_create(sd, file, "elm/entry/cursor/default", EINA_TRUE);
+   evas_object_show(sd->cursor);
+   evas_object_show(sd->cursor_bidi);
+   edje_object_signal_emit(sd->cursor, "elm,action,focus", "elm");
+   edje_object_signal_emit(sd->cursor_bidi, "elm,action,focus", "elm");
+}
+
+static void
+_decoration_calc_offset(Efl_Ui_Text_Data *sd, Evas_Coord *_x, Evas_Coord *_y)
+{
+   Evas_Coord x, y;
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   evas_object_geometry_get(text_obj, &x, &y, NULL, NULL);
+
+   if (_x) *_x = x;
+   if (_y) *_y = y;
+}
+
+static void
+_update_text_cursors(Eo *obj)
+{
+   Evas_Coord x, y, w, h, xx, yy, ww, hh;
+   Evas_Coord xx2, yy2;
+   Eina_Bool bidi_cursor;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   x = y = w = h = -1;
+   xx = yy = ww = hh = -1;
+   _decoration_calc_offset(sd, &x, &y);
+   bidi_cursor = efl_canvas_text_cursor_geometry_get(
+         efl_canvas_text_cursor_get(text_obj),
+         EFL_CANVAS_TEXT_CURSOR_TYPE_BEFORE, &xx, &yy, &ww, &hh, &xx2, &yy2,
+         NULL, NULL);
+   if (ww < 1) ww = 1;
+   if (hh < 1) hh = 1;
+   if (sd->cursor)
+     {
+        evas_object_move(sd->cursor, x + xx, y + yy);
+        evas_object_resize(sd->cursor, ww, hh);
+     }
+   if (sd->cursor_bidi)
+     {
+        if (bidi_cursor)
+          {
+             evas_object_image_fill_set(sd->cursor_bidi, 0, 0, ww, hh / 2);
+             evas_object_move(sd->cursor_bidi, x + xx2, y + yy2 + (hh / 2));
+             evas_object_resize(sd->cursor, ww, hh / 2);
+             evas_object_resize(sd->cursor_bidi, ww, hh / 2);
+             evas_object_show(sd->cursor_bidi);
+          }
+        else
+          {
+             evas_object_hide(sd->cursor_bidi);
+          }
+     }
+}
+
+static void
+_update_text_selection(Eo *obj, Eo *text_obj)
+{
+   Evas_Coord x, y;
+   Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+
+   Eina_List *l;
+   Eina_Iterator *range;
+   Efl_Ui_Text_Rectangle *rect;
+   Eina_Rectangle *r;
+   const char *file;
+
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+
+   _decoration_calc_offset(sd, &x, &y);
+
+   efl_file_get(sd->entry_edje, &file, NULL);
+
+   efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+
+   range = efl_canvas_text_range_geometry_get(text_obj,
+         sel_start, sel_end);
+
+   l = sd->rects;
+   EINA_ITERATOR_FOREACH(range, r)
+     {
+        /* Create if there isn't a rectangle to populate. */
+        if (!l)
+          {
+             rect = calloc(1, sizeof(Efl_Ui_Text_Rectangle));
+             sd->rects = eina_list_append(sd->rects, rect);
+
+             rect->obj_bg = _decoration_create(sd, file, "elm/entry/selection/default", EINA_FALSE);
+             evas_object_show(rect->obj_bg);
+          }
+        else
+          {
+             rect = eina_list_data_get(l);
+             l = l->next;
+          }
+        rect->rect = *r;
+
+        if (rect->obj_bg)
+          {
+             evas_object_move(rect->obj_bg, x + r->x, y + r->y);
+             evas_object_resize(rect->obj_bg, r->w, r->h);
+          }
+     }
+   eina_iterator_free(range);
+
+   /* delete redundant rectection rects */
+   while (l)
+     {
+        Eina_List *temp = l->next;
+        rect = eina_list_data_get(l);
+        if (rect)
+          {
+             if (rect->obj_bg) eo_del(rect->obj_bg);
+             free(rect);
+          }
+        sd->rects = eina_list_remove_list(sd->rects, l);
+        l = temp;
+     }
+}
+
+static void
+_update_decorations(Eo *obj)
+{
+   EFL_UI_TEXT_DATA_GET(obj, sd);
+   Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+   _update_text_cursors(obj);
+   _update_text_selection(obj, text_obj);
+}
+
+static Eina_Bool
+_efl_ui_text_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+   _update_decorations(data);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_ui_text_cursor_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+   _update_text_cursors(data);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_ui_text_selection_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+   _update_text_selection(data, event->object);
+   return EINA_TRUE;
+}
+
+static void
+_efl_ui_text_move_cb(void *data, Evas *e EINA_UNUSED,
+      Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   _update_decorations(data);
+}
+
+#if 0
+/* Efl.Part begin */
+
+ELM_PART_OVERRIDE(elm_entry, EFL_UI_TEXT, ELM_LAYOUT, Efl_Ui_Text_Data, Elm_Part_Data)
+ELM_PART_OVERRIDE_CONTENT_SET(elm_entry, EFL_UI_TEXT, ELM_LAYOUT, Efl_Ui_Text_Data, Elm_Part_Data)
+ELM_PART_OVERRIDE_CONTENT_UNSET(elm_entry, EFL_UI_TEXT, ELM_LAYOUT, Efl_Ui_Text_Data, Elm_Part_Data)
+#include "elm_entry_internal_part.eo.c"
+
+/* Efl.Part end */
+#endif
+
+#include "efl_ui_text.eo.c"
+
diff --git a/src/lib/elementary/efl_ui_text.eo b/src/lib/elementary/efl_ui_text.eo
new file mode 100644 (file)
index 0000000..6911abb
--- /dev/null
@@ -0,0 +1,468 @@
+import elm_general;
+import elm_icon;
+import elm_entry;
+
+class Efl.Ui.Text (Elm.Layout, Elm.Interface_Scrollable, Evas.Clickable_Interface,
+                 Elm.Interface.Atspi.Text, Elm.Interface.Atspi.Text.Editable, Efl.File,
+                 Evas.Selectable_Interface, Evas.Scrollable_Interface, Efl.Ui.Text.Interactive)
+{
+   methods {
+      @property scrollable {
+         set {
+            [[Enable or disable scrolling in entry
+
+              Normally the entry is not scrollable unless you enable it with this call.
+            ]]
+         }
+         get {
+            [[Get the scrollable state of the entry
+
+              Normally the entry is not scrollable. This gets the scrollable state
+              of the entry.
+            ]]
+         }
+         values {
+            scroll: bool; [[$true if it is to be scrollable, $false otherwise.]]
+         }
+      }
+      @property input_panel_show_on_demand {
+         set {
+            [[Set the attribute to show the input panel in case of only an user's explicit Mouse Up event.
+              It doesn't request to show the input panel even though it has focus.
+
+              @since 1.9
+            ]]
+         }
+         get {
+            [[Get the attribute to show the input panel in case of only an user's explicit Mouse Up event.
+
+              @since 1.9
+            ]]
+         }
+         values {
+            ondemand: bool; [[If true, the input panel will be shown in case of only Mouse up event.
+            (Focus event will be ignored.)
+            ]]
+         }
+      }
+      @property context_menu_disabled {
+         set {
+            [[This disables the entry's contextual (longpress) menu.]]
+         }
+         get {
+            [[This returns whether the entry's contextual (longpress) menu is
+              disabled.
+            ]]
+         }
+         values {
+            disabled: bool; [[If $true, the menu is disabled.]]
+         }
+      }
+      @property cnp_mode {
+         set {
+            [[Control pasting of text and images for the widget.
+
+              Normally the entry allows both text and images to be pasted.
+              By setting cnp_mode to be #ELM_CNP_MODE_NO_IMAGE, this prevents images from being copy or past.
+              By setting cnp_mode to be #ELM_CNP_MODE_PLAINTEXT, this remove all tags in text .
+
+              Note: This only changes the behaviour of text.
+            ]]
+         }
+         get {
+            [[Getting elm_entry text paste/drop mode.
+
+              Normally the entry allows both text and images to be pasted.
+              This gets the copy & paste mode of the entry.
+            ]]
+         }
+         values {
+            cnp_mode: Elm.Cnp_Mode; [[One of #Elm_Cnp_Mode: #ELM_CNP_MODE_MARKUP, #ELM_CNP_MODE_NO_IMAGE, #ELM_CNP_MODE_PLAINTEXT.]]
+         }
+      }
+      @property input_panel_language {
+         set {
+            [[Set the language mode of the input panel.
+
+              This API can be used if you want to show the alphabet keyboard mode.
+            ]]
+         }
+         get {
+            [[Get the language mode of the input panel.]]
+         }
+         values {
+            lang: Elm.Input.Panel.Lang; [[language to be set to the input panel.]]
+         }
+      }
+      @property selection_handler_disabled {
+         set {
+            [[This disabled the entry's selection handlers.]]
+         }
+         get {
+            [[This returns whether the entry's selection handlers are disabled.]]
+            legacy: null;
+         }
+         values {
+            disabled: bool; [[If $true, the selection handlers are disabled.]]
+         }
+      }
+      @property input_panel_layout_variation {
+         set {
+            [[Set the input panel layout variation of the entry
+
+              @since 1.8
+            ]]
+         }
+         get {
+            [[Get the input panel layout variation of the entry
+
+              @since 1.8
+            ]]
+         }
+         values {
+            variation: int; [[layout variation type.]]
+         }
+      }
+      @property autocapital_type {
+         set {
+            [[Set the autocapitalization type on the immodule.]]
+         }
+         get {
+            [[Get the autocapitalization type on the immodule.]]
+         }
+         values {
+            autocapital_type: Elm.Autocapital.Type; [[The type of autocapitalization.]]
+         }
+      }
+      @property editable {
+         set {
+            [[Sets if the entry is to be editable or not.
+
+              By default, entries are editable and when focused, any text input by the
+              user will be inserted at the current cursor position. But calling this
+              function with $editable as $false will prevent the user from
+              inputting text into the entry.
+
+              The only way to change the text of a non-editable entry is to use
+              \@ref elm_object_text_set, \@ref elm_entry_entry_insert and other related
+              functions.
+            ]]
+         }
+         get {
+            [[Get whether the entry is editable or not.]]
+         }
+         values {
+            editable: bool; [[If $true, user input will be inserted in the entry,
+            if not, the entry is read-only and no user input is allowed.]]
+         }
+      }
+      @property password {
+         set {
+            [[Sets the entry to password mode.
+
+              In password mode, entries are implicitly single line and the display of
+              any text in them is replaced with asterisks (*).
+            ]]
+         }
+         get {
+            [[Get whether the entry is set to password mode.]]
+         }
+         values {
+            password: bool; [[If true, password mode is enabled.]]
+         }
+      }
+      @property input_panel_return_key_disabled {
+         set {
+            [[Set the return key on the input panel to be disabled.]]
+         }
+         get {
+            [[Get whether the return key on the input panel should be disabled or not.]]
+         }
+         values {
+            disabled: bool; [[The state to put in in: $true for
+            disabled, $false for enabled.]]
+         }
+      }
+      @property prediction_allow {
+         set {
+            [[Set whether the entry should allow to use the text prediction.]]
+         }
+         get {
+            [[Get whether the entry should allow to use the text prediction.]]
+         }
+         values {
+            prediction: bool; [[Whether the entry should allow to use the text prediction.]]
+         }
+      }
+      @property input_hint {
+         set {
+            [[Sets the input hint which allows input methods to fine-tune their behavior.]]
+         }
+         get {
+            [[Gets the value of input hint.]]
+         }
+         values {
+            hints: Elm.Input.Hints; [[Input hint.]]
+         }
+      }
+      @property input_panel_layout {
+         set {
+            [[Set the input panel layout of the entry.]]
+         }
+         get {
+            [[Get the input panel layout of the entry.]]
+         }
+         values {
+            layout: Elm.Input.Panel.Layout(Elm.Input.Panel.Layout.invalid); [[layout type.]]
+         }
+      }
+      @property input_panel_return_key_type {
+         set {
+            [[Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel.
+
+              An input panel displays the string or icon associated with this type.
+            ]]
+         }
+         get {
+            [[Get the "return" key type.]]
+         }
+         values {
+            return_key_type: Elm.Input.Panel.Return_Key.Type; [[The type of "return" key on the input panel.]]
+         }
+      }
+      @property input_panel_enabled {
+         set {
+            [[Sets the attribute to show the input panel automatically.]]
+         }
+         get {
+            [[Get the attribute to show the input panel automatically.]]
+         }
+         values {
+            enabled: bool; [[If true, the input panel is appeared when entry is clicked or has a focus.]]
+         }
+      }
+      @property input_panel_return_key_autoenabled {
+         set {
+            [[Set whether the return key on the input panel is disabled automatically when entry has no text.
+
+              If $enabled is $true, The return key on input panel is disabled when the entry has no text.
+              The return key on the input panel is automatically enabled when the entry has text.
+              The default value is $false.
+            ]]
+         }
+         values {
+            enabled: bool; [[If $enabled is true, the return key is automatically disabled when the entry has no text.]]
+         }
+      }
+      @property imf_context {
+         get {
+            [[Returns the input method context of the entry.
+
+              This function exposes the internal input method context.
+
+              IMPORTANT: Many functions may change (i.e delete and create a new one)
+              the internal input method context. Do NOT cache the returned object.
+            ]]
+            return: void_ptr;
+         }
+      }
+      item_provider_prepend {
+         [[This prepends a custom item provider to the list for that entry
+
+           This prepends the given callback.]]
+         params {
+            @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
+            @in data: void_ptr @optional; [[The data passed to $func.]]
+         }
+      }
+      input_panel_show {
+         [[Show the input panel (virtual keyboard) based on the input panel property of entry such as layout, autocapital types, and so on.
+
+           Note that input panel is shown or hidden automatically according to the focus state of entry widget.
+           This API can be used in the case of manually controlling by using @.input_panel_enabled.set(en, $false).
+         ]]
+      }
+      imf_context_reset {
+         [[Reset the input method context of the entry if needed.
+
+           This can be necessary in the case where modifying the buffer would confuse on-going input method behavior.
+           This will typically cause the Input Method Context to clear the preedit state.
+         ]]
+      }
+      selection_copy {
+         [[This executes a "copy" action on the selected text in the entry.]]
+      }
+      item_provider_remove {
+         [[This removes a custom item provider to the list for that entry
+
+           This removes the given callback. See @.item_provider_append for
+           more information
+         ]]
+         params {
+            @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
+            @in data: void_ptr @optional; [[The data passed to $func.]]
+         }
+      }
+      context_menu_clear {
+         [[This clears and frees the items in a entry's contextual (longpress)
+           menu.
+
+           See also @.context_menu_item_add.
+         ]]
+      }
+      input_panel_imdata_set {
+         [[Set the input panel-specific data to deliver to the input panel.
+
+           This API is used by applications to deliver specific data to the input panel.
+           The data format MUST be negotiated by both application and the input panel.
+           The size and format of data are defined by the input panel.
+         ]]
+         params {
+            @in data: const(void_ptr); [[The specific data to be set to the input panel.]]
+            @in len: int; [[The length of data, in bytes, to send to the input panel.]]
+         }
+      }
+      input_panel_imdata_get @const {
+         [[Get the specific data of the current input panel.]]
+         params {
+            @out data: void; [[The specific data to be got from the input panel.]]
+            @out len: int; [[The length of data.]]
+         }
+      }
+      selection_paste {
+         [[This executes a "paste" action in the entry.]]
+      }
+      input_panel_hide {
+         [[Hide the input panel (virtual keyboard).
+
+           Note that input panel is shown or hidden automatically according to the focus state of entry widget.
+           This API can be used in the case of manually controlling by using @.input_panel_enabled.set(en, $false)
+         ]]
+      }
+      cursor_selection_end {
+         [[This ends a selection within the entry as though
+           the user had just released the mouse button while making a selection.]]
+      }
+      selection_cut {
+         [[This executes a "cut" action on the selected text in the entry.]]
+      }
+      item_provider_append {
+         [[This appends a custom item provider to the list for that entry
+
+           This appends the given callback. The list is walked from beginning to end
+           with each function called given the item href string in the text. If the
+           function returns an object handle other than $null (it should create an
+           object to do this), then this object is used to replace that item. If
+           not the next provider is called until one provides an item object, or the
+           default provider in entry does.
+
+           See also \@ref entry-items.
+         ]]
+         params {
+            @in func: Elm_Entry_Item_Provider_Cb; [[The function called to provide the item object.]]
+            @in data: void_ptr @optional; [[The data passed to $func.]]
+         }
+      }
+      context_menu_item_add {
+         [[This adds an item to the entry's contextual menu.
+
+           A longpress on an entry will make the contextual menu show up, if this
+           hasn't been disabled with @.context_menu_disabled.set.
+           By default, this menu provides a few options like enabling selection mode,
+           which is useful on embedded devices that need to be explicit about it,
+           and when a selection exists it also shows the copy and cut actions.
+
+           With this function, developers can add other options to this menu to
+           perform any action they deem necessary.
+         ]]
+         params {
+            @in label: string @optional; [[The item's text label.]]
+            @in icon_file: string @optional; [[The item's icon file.]]
+            @in icon_type: Elm.Icon.Type; [[The item's icon type.]]
+            @in func: Evas_Smart_Cb @optional; [[The callback to execute when the item is clicked.]]
+            @in data: const(void_ptr) @optional; [[The data to associate with the item for related functions.]]
+         }
+      }
+   }
+   implements {
+      class.constructor;
+      Eo.Base.constructor;
+      Evas.Object.Smart.move;
+      Evas.Object.Smart.member_add;
+      Evas.Object.Smart.add;
+      Evas.Object.Smart.resize;
+      Evas.Object.Smart.del;
+      Evas.Object.Smart.show;
+      Evas.Object.Smart.hide;
+      Elm.Widget.activate;
+      Elm.Widget.focus_direction_manager_is;
+      Elm.Widget.theme_apply;
+      Elm.Widget.on_focus;
+      Elm.Widget.on_focus_region;
+      Elm.Widget.disable;
+      Elm.Widget.sub_object_del;
+      Elm.Widget.focus_next_manager_is;
+      Elm.Layout.theme_enable;
+      Elm.Layout.sizing_eval;
+      Elm.Layout.text.get;
+      Elm.Layout.signal_callback_add;
+      Elm.Layout.signal_callback_del;
+      Elm.Layout.signal_emit;
+      Elm.Layout.text.set;
+      Elm.Layout.content_aliases.get;
+      Elm.Interface_Scrollable.policy.set;
+      Elm.Interface_Scrollable.bounce_allow.set;
+      Elm.Interface.Atspi_Accessible.state_set.get;
+      Elm.Interface.Atspi_Accessible.name.get;
+      Elm.Interface.Atspi.Text.text.get;
+      Elm.Interface.Atspi.Text.string.get;
+      Elm.Interface.Atspi.Text.attribute.get;
+      Elm.Interface.Atspi.Text.attributes.get;
+      Elm.Interface.Atspi.Text.default_attributes.get;
+      Elm.Interface.Atspi.Text.caret_offset.get;
+      Elm.Interface.Atspi.Text.caret_offset.set;
+      Elm.Interface.Atspi.Text.character.get;
+      Elm.Interface.Atspi.Text.character_extents.get;
+      Elm.Interface.Atspi.Text.character_count.get;
+      Elm.Interface.Atspi.Text.offset_at_point.get;
+      Elm.Interface.Atspi.Text.bounded_ranges.get;
+      Elm.Interface.Atspi.Text.range_extents.get;
+      Elm.Interface.Atspi.Text.selection.get;
+      Elm.Interface.Atspi.Text.selections_count.get;
+      Elm.Interface.Atspi.Text.selection_add;
+      Elm.Interface.Atspi.Text.selection_remove;
+      Elm.Interface.Atspi.Text.selection.set;
+      Elm.Interface.Atspi.Text.Editable.content.set;
+      Elm.Interface.Atspi.Text.Editable.insert;
+      Elm.Interface.Atspi.Text.Editable.copy;
+      Elm.Interface.Atspi.Text.Editable.cut;
+      Elm.Interface.Atspi.Text.Editable.delete;
+      Elm.Interface.Atspi.Text.Editable.paste;
+      Efl.File.file.set;
+      Efl.File.file.get;
+   }
+   events {
+      activated;
+      changed;
+      changed,user;
+      validate;
+      context,open;
+      anchor,clicked;
+      rejected;
+      maxlength,reached;
+      preedit,changed;
+      press;
+      redo,request;
+      undo,request;
+      text,set,done;
+      aborted;
+      anchor,down;
+      anchor,hover,opened;
+      anchor,in;
+      anchor,out;
+      anchor,up;
+      cursor,changed;
+      cursor,changed,manual;
+   }
+
+}
index 01ececb..b9172c0 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef ELM_ENTRY_COMMON_H_
+#define ELM_ENTRY_COMMON_H_
+
 /**
  * @addtogroup Elm_Entry
  *
@@ -257,3 +260,4 @@ EAPI void                         elm_entry_context_menu_item_icon_get(const Elm
 /**
  * @}
  */
+#endif //ELM_ENTRY_COMMON_H_