addd object dump features
[framework/uifw/elementary.git] / src / lib / elm_entry.c
index 8de344f..1974a67 100644 (file)
@@ -1,6 +1,7 @@
 #include <Elementary.h>
 #include <Elementary_Cursor.h>
 #include "elm_priv.h"
+#include "elm_module_priv.h"
 #include "els_scroller.h"
 
 
@@ -82,6 +83,21 @@ struct _Widget_Data
    Eina_Bool input_panel_return_key_disabled : 1;
    Eina_Bool autoreturnkey : 1;
    Elm_Cnp_Mode cnp_mode : 2;
+//// TIZEN ONLY
+   Evas_Object *mgf_proxy;
+   Evas_Object *mgf_clip;
+   Evas_Object *mgf_bg;
+   Evas_Coord mgf_height;
+   float mgf_scale;
+   int mgf_type;
+   Ecore_Job *region_get_job;
+   Ecore_Job *region_recalc_job;
+   const char *password_text;
+   Evas_Coord cx, cy, cw, ch;
+   Eina_Bool double_clicked : 1;
+   Eina_Bool long_pressed : 1;
+   Eina_Bool magnifier_enabled : 1;
+//
 };
 
 struct _Elm_Entry_Context_Menu_Item
@@ -115,6 +131,9 @@ typedef enum _Length_Unit
 } Length_Unit;
 
 static const char *widtype = NULL;
+// start for cbhm
+static Evas_Object *cnpwidgetdata = NULL;
+// end for cbhm
 
 #ifdef HAVE_ELEMENTARY_X
 static Eina_Bool _drag_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *);
@@ -128,6 +147,7 @@ static void _on_focus_hook(void *data, Evas_Object *obj);
 static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content);
 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
+static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info);
 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
 static const char *_getbase(Evas_Object *obj);
 static void _signal_entry_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
@@ -140,6 +160,20 @@ static void _signal_entry_cut_notify(void *data, Evas_Object *obj, const char *e
 static void _signal_cursor_changed(void *data, Evas_Object *obj, const char *emission, const char *source);
 static void _add_chars_till_limit(Evas_Object *obj, char **text, int can_add, Length_Unit unit);
 static void _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info);
+//// TIZEN ONLY
+static void _signal_selection_end(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_handler_move_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_handler_move_end(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_handler_moving(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _magnifier_create(void *data);
+static void _magnifier_show(void *data);
+static void _magnifier_hide(void *data);
+static void _magnifier_move(void *data);
+static Evas_Coord_Rectangle _layout_region_get(Evas_Object *data);
+static Evas_Coord_Rectangle _viewport_region_get(Evas_Object *data);
+static void _region_get_job(void *data);
+static void _region_recalc_job(void *data);
+//
 
 static const char SIG_CHANGED[] = "changed";
 static const char SIG_CHANGED_USER[] = "changed,user";
@@ -199,6 +233,13 @@ static const Evas_Smart_Cb_Description _signals[] = {
        {NULL, NULL}
 };
 
+typedef enum _Elm_Entry_Magnifier_Type
+{
+   _ENTRY_MAGNIFIER_FIXEDSIZE = 0,
+   _ENTRY_MAGNIFIER_FILLWIDTH,
+   _ENTRY_MAGNIFIER_CIRCULAR,
+} Elm_Entry_Magnifier_Type;
+
 static Eina_List *entries = NULL;
 
 struct _Mod_Api
@@ -206,6 +247,8 @@ struct _Mod_Api
    void (*obj_hook) (Evas_Object *obj);
    void (*obj_unhook) (Evas_Object *obj);
    void (*obj_longpress) (Evas_Object *obj);
+   void (*obj_hidemenu) (Evas_Object *obj);
+   void (*obj_mouseup) (Evas_Object *obj);
 };
 
 static Mod_Api *
@@ -223,6 +266,10 @@ _module(Evas_Object *obj __UNUSED__)
       _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");
+   ((Mod_Api *)(m->api)      )->obj_hidemenu = // called on hide menu
+      _elm_module_symbol_get(m, "obj_hidemenu");
+   ((Mod_Api *)(m->api)      )->obj_mouseup = // called on mouseup
+      _elm_module_symbol_get(m, "obj_mouseup");
 ok: // ok - return api
    return m->api;
 }
@@ -494,7 +541,10 @@ _del_hook(Evas_Object *obj)
 #endif
    if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
    if (wd->text) eina_stringshare_del(wd->text);
+   if (wd->password_text) eina_stringshare_del(wd->password_text);
    if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
+   if (wd->region_get_job) ecore_job_del(wd->region_get_job);
+   if (wd->region_recalc_job) ecore_job_del(wd->region_recalc_job);
    if (wd->append_text_idler)
      {
         ecore_idler_del(wd->append_text_idler);
@@ -502,6 +552,9 @@ _del_hook(Evas_Object *obj)
         wd->append_text_left = NULL;
         wd->append_text_idler = NULL;
      }
+   if (wd->mgf_proxy) evas_object_del(wd->mgf_proxy);
+   if (wd->mgf_bg) evas_object_del(wd->mgf_bg);
+   if (wd->mgf_clip) evas_object_del(wd->mgf_clip);
    if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
    EINA_LIST_FREE(wd->items, it)
      {
@@ -643,7 +696,7 @@ _elm_deferred_recalc_job(void *data)
    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 mininmum doesn't matter. */
+    * the minimum doesn't matter. */
    if (minw <= resw)
      {
         Evas_Coord ominw = -1;
@@ -728,7 +781,7 @@ _sizing_eval(Evas_Object *obj)
              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 mininmum doesn't matter. */
+              * the minimum doesn't matter. */
              if (minw <= vw)
                {
                   Evas_Coord ominw = -1;
@@ -830,23 +883,35 @@ _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *top = elm_widget_top_get(obj);
    if (!wd) return;
-   if (!wd->editable) return;
+
    if (elm_widget_focus_get(obj))
      {
+        printf("[Elm_entry::Focused] obj : %p\n", obj);
         evas_object_focus_set(wd->ent, EINA_TRUE);
         edje_object_signal_emit(wd->ent, "elm,action,focus", "elm");
-        if (top && wd->input_panel_enable)
-          elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
-        evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
-        _check_enable_return_key(obj);
+        wd->mgf_type = _ENTRY_MAGNIFIER_FIXEDSIZE;
+        if (wd->editable)
+          {
+             if (top && wd->input_panel_enable)
+               elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_ON);
+             evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
+             _check_enable_return_key(obj);
+          }
      }
    else
      {
+        printf("[Elm_entry::Unfocused] obj : %p\n", obj);
         edje_object_signal_emit(wd->ent, "elm,action,unfocus", "elm");
         evas_object_focus_set(wd->ent, EINA_FALSE);
-        if (top && wd->input_panel_enable)
-          elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
-        evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
+        if ((wd->api) && (wd->api->obj_hidemenu))
+          wd->api->obj_hidemenu(obj);
+
+        if (wd->editable)
+          {
+             if (top && wd->input_panel_enable)
+               elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
+             evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
+          }
      }
 }
 
@@ -960,6 +1025,18 @@ _translate_hook(Evas_Object *obj)
    evas_object_smart_callback_call(obj, "language,changed", NULL);
 }
 
+static Eina_Bool
+_event_hook(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info)
+{
+   if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
+   Evas_Event_Key_Down *ev = event_info;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
+   if (elm_widget_disabled_get(obj)) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
 static void
 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
 {
@@ -1087,6 +1164,12 @@ _move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_i
    Widget_Data *wd = elm_widget_data_get(data);
 
    if (wd->hoversel) _hoversel_position(data);
+
+   if (!_elm_config->desktop_entry)
+     {
+        if (wd->region_get_job) ecore_job_del(wd->region_get_job);
+        wd->region_get_job = ecore_job_add(_region_get_job, data);
+     }
 }
 
 static void
@@ -1109,6 +1192,12 @@ _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event
         evas_object_resize(wd->ent, vw, vh);
      }
    if (wd->hoversel) _hoversel_position(data);
+
+   if (!_elm_config->desktop_entry)
+     {
+        if (wd->region_get_job) ecore_job_del(wd->region_get_job);
+        wd->region_get_job = ecore_job_add(_region_get_job, data);
+     }
 }
 
 static void
@@ -1146,6 +1235,18 @@ _dismissed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 }
 
 static void
+_selectall(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->selmode = EINA_TRUE;
+   edje_object_part_text_select_none(wd->ent, "elm.text");
+   edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
+   edje_object_part_text_select_all(wd->ent, "elm.text");
+   elm_object_scroll_freeze_pop(data);
+}
+
+static void
 _select(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -1159,7 +1260,8 @@ _select(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
      }
    edje_object_signal_emit(wd->ent, "elm,state,select,on", "elm");
    if (!_elm_config->desktop_entry)
-     elm_widget_scroll_hold_push(data);
+      elm_object_scroll_freeze_pop(data);  // TIZEN ONLY
+      //elm_widget_scroll_hold_push(data);
 }
 
 static char *
@@ -1220,6 +1322,13 @@ _elm_entry_entry_paste(Evas_Object *obj, const char *entry)
 
    edje_object_part_text_user_insert(wd->ent, "elm.text", str);
    if (str != entry) free(str);
+
+   // start for cbhm
+#ifdef HAVE_ELEMENTARY_X
+   if (cnpwidgetdata == obj)
+      ecore_x_selection_secondary_set(elm_win_xwindow_get(obj), "",1);
+#endif
+   // end for cbhm
 }
 
 static void
@@ -1278,10 +1387,10 @@ _copy(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
-   wd->selmode = EINA_FALSE;
+   wd->selmode = EINA_TRUE;   // TIZEN ONLY
    if (!_elm_config->desktop_entry)
      {
-        edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);
+        //edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_FALSE);   // TIZEN ONLY
         edje_object_signal_emit(wd->ent, "elm,state,select,off", "elm");
         elm_widget_scroll_hold_pop(data);
      }
@@ -1303,6 +1412,17 @@ _cancel(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
    edje_object_part_text_select_none(wd->ent, "elm.text");
 }
 
+// start for cbhm
+static void
+_cnpinit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   cnpwidgetdata = data;
+}
+// end for cbhm
+
+
 static void
 _item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
@@ -1394,13 +1514,170 @@ _menu_press(Evas_Object *obj)
      }
 }
 
+static void
+_magnifier_hide(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   evas_object_hide(wd->mgf_bg);
+   evas_object_hide(wd->mgf_clip);
+
+   if (wd->scroll)
+     elm_smart_scroller_freeze_set(wd->scroller, EINA_FALSE);
+}
+
+static void
+_magnifier_show(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   evas_object_show(wd->mgf_bg);
+   evas_object_show(wd->mgf_clip);
+}
+
+static void
+_magnifier_move(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   Evas_Coord x, y, w, h;
+   Evas_Coord cx, cy, cw, ch, ox, oy;
+
+   edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", &cx, &cy, &cw, &ch);
+
+   if (wd->scroll)
+     {
+        evas_object_geometry_get(wd->scroller, &x, &y, &w, &h);
+        elm_smart_scroller_child_pos_get(wd->scroller, &ox, &oy);
+        cx -= ox;
+        cy -= oy;
+     }
+   else
+     evas_object_geometry_get(data, &x, &y, &w, &h);
+
+   ox = oy = 0;
+
+   if ((cy + y) - wd->mgf_height < 0)
+     oy = -1 * ((cy + y) - wd->mgf_height);
+
+   if (wd->mgf_type == _ENTRY_MAGNIFIER_FIXEDSIZE)
+     evas_object_move(wd->mgf_bg, (cx + x + cw/2) + ox, (cy + y) - wd->mgf_height + oy);
+   else if (wd->mgf_type == _ENTRY_MAGNIFIER_FILLWIDTH)
+     evas_object_move(wd->mgf_bg, x, (cy + y) - wd->mgf_height + oy);
+   else
+     return;
+
+   evas_object_move(wd->mgf_proxy, (1 - wd->mgf_scale) * cx + x + ox, (1 - wd->mgf_scale) * cy + y - wd->mgf_height/2 - ch/2 + oy);
+}
+
+static void
+_magnifier_create(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord x, y, w, h, mw, mh;
+   const char* key_data = NULL;
+   double elm_scale;
+
+   if (!wd) return;
+
+   if (wd->mgf_proxy)
+     {
+        evas_object_image_source_unset(wd->mgf_proxy);
+        evas_object_color_set(wd->mgf_proxy, 255, 255, 255, 0);
+        evas_object_hide(wd->mgf_proxy);
+        evas_object_clip_unset(wd->mgf_proxy);
+        evas_object_del(wd->mgf_proxy);
+     }
+   if (wd->mgf_bg) evas_object_del(wd->mgf_bg);
+   if (wd->mgf_clip) evas_object_del(wd->mgf_clip);
+
+   if (wd->scroll)
+     evas_object_geometry_get(wd->scroller, &x, &y, &w, &h);
+   else
+     evas_object_geometry_get(data, &x, &y, &w, &h);
+
+   if ((w <= 0) || (h <= 0))
+     return;
+
+   wd->mgf_bg = edje_object_add(evas_object_evas_get(data));
+
+   if (wd->mgf_type == _ENTRY_MAGNIFIER_FIXEDSIZE)
+     _elm_theme_object_set(data, wd->mgf_bg, "entry", "magnifier", "fixed-size");
+   else if (wd->mgf_type == _ENTRY_MAGNIFIER_FILLWIDTH)
+     _elm_theme_object_set(data, wd->mgf_bg, "entry", "magnifier", "fill-width");
+   else
+     return;
+
+   wd->mgf_clip = evas_object_rectangle_add(evas_object_evas_get(data));
+   evas_object_color_set(wd->mgf_clip, 255, 255, 255, 255);
+   edje_object_part_swallow(wd->mgf_bg, "swallow", wd->mgf_clip);
+
+   key_data = edje_object_data_get(wd->mgf_bg, "height");
+   if (key_data) wd->mgf_height = atoi(key_data);
+   key_data = edje_object_data_get(wd->mgf_bg, "scale");
+   if (key_data) wd->mgf_scale = atof(key_data);
+
+   elm_scale = elm_config_scale_get();
+   wd->mgf_height = (int)((float)wd->mgf_height * elm_scale);
+
+   if (wd->mgf_type == _ENTRY_MAGNIFIER_FILLWIDTH)
+     evas_object_resize(wd->mgf_bg, w, wd->mgf_height);
+
+   if (wd->scroll)
+     {
+        elm_smart_scroller_freeze_set(wd->scroller, EINA_TRUE);
+        wd->mgf_proxy = evas_object_image_add(evas_object_evas_get(wd->scroller));
+        evas_object_image_source_set(wd->mgf_proxy, wd->scroller);
+     }
+   else
+     {
+        wd->mgf_proxy = evas_object_image_add(evas_object_evas_get(data));
+        evas_object_image_source_set(wd->mgf_proxy, data);
+     }
+
+   mw = (Evas_Coord)((float)w * wd->mgf_scale);
+   mh = (Evas_Coord)((float)h * wd->mgf_scale);
+   if ((mw <= 0) || (mh <= 0))
+     return;
+
+   evas_object_resize(wd->mgf_proxy, mw, mh);
+   evas_object_image_fill_set(wd->mgf_proxy, 0, 0, mw, mh);
+   evas_object_color_set(wd->mgf_proxy, 255, 255, 255, 255);
+   evas_object_pass_events_set(wd->mgf_proxy, EINA_TRUE);
+   evas_object_show(wd->mgf_proxy);
+   evas_object_clip_set(wd->mgf_proxy, wd->mgf_clip);
+
+   evas_object_layer_set(wd->mgf_bg, EVAS_LAYER_MAX);
+   evas_object_layer_set(wd->mgf_proxy, EVAS_LAYER_MAX);
+}
+
+static void
+_signal_long_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (!wd) return;
+   wd->long_pressed = EINA_TRUE;
+   _cancel(data, NULL, NULL);
+   if (wd->magnifier_enabled)
+     {
+        _magnifier_create(data);
+        _magnifier_move(data);
+        _magnifier_show(data);
+        elm_object_scroll_freeze_push(data);
+     }
+}
+
 static Eina_Bool
 _long_press(void *data)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return ECORE_CALLBACK_CANCEL;
-   if (!_elm_config->desktop_entry)
-     _menu_press(data);
+   if ((!_elm_config->desktop_entry) && (!wd->magnifier_enabled))
+     _menu_press(data); /////// TIZEN ONLY
    wd->longpress_timer = NULL;
    evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
    return ECORE_CALLBACK_CANCEL;
@@ -1416,6 +1693,7 @@ _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void
    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
    wd->downx = ev->canvas.x;
    wd->downy = ev->canvas.y;
+   wd->long_pressed = EINA_FALSE;
    if (ev->button == 1)
      {
         if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
@@ -1432,6 +1710,17 @@ _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *
    if (wd->disabled) return;
    if (ev->button == 1)
      {
+        if (!wd->double_clicked)
+          {
+             if ((wd->api) && (wd->api->obj_mouseup))
+               wd->api->obj_mouseup(data);
+          }
+        if (wd->magnifier_enabled)
+          {
+             _magnifier_hide(data);
+             elm_object_scroll_freeze_pop(data);
+             if (wd->long_pressed) _menu_press(data);
+          }
         if (wd->longpress_timer)
           {
              ecore_timer_del(wd->longpress_timer);
@@ -1452,6 +1741,15 @@ _mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void
    Evas_Event_Mouse_Move *ev = event_info;
    if (!wd) return;
    if (wd->disabled) return;
+
+   if (ev->buttons == 1)
+     {
+        if ((wd->long_pressed) && (wd->magnifier_enabled))
+          {
+             _magnifier_show(data);
+             _magnifier_move(data);
+          }
+     }
    if (!wd->selmode)
      {
         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
@@ -1566,11 +1864,17 @@ _entry_changed_common_handling(void *data, const char *event)
    _sizing_eval(data);
    if (wd->text) eina_stringshare_del(wd->text);
    wd->text = NULL;
+   if (wd->password_text) eina_stringshare_del(wd->password_text);
+   wd->password_text = NULL;
    if (wd->delay_write)
      {
         ecore_timer_del(wd->delay_write);
         wd->delay_write = NULL;
      }
+
+   if ((wd->api) && (wd->api->obj_hidemenu))
+     wd->api->obj_hidemenu(data);
+
    evas_event_thaw(evas_object_evas_get(data));
    evas_event_thaw_eval(evas_object_evas_get(data));
    if ((wd->autosave) && (wd->file))
@@ -1588,6 +1892,185 @@ _signal_entry_changed(void *data, Evas_Object *obj __UNUSED__, const char *emiss
 }
 
 static void
+_signal_handler_move_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   elm_object_scroll_freeze_push(data);
+
+   if ((wd->api) && (wd->api->obj_hidemenu))
+     wd->api->obj_hidemenu(data);
+
+   if (wd->magnifier_enabled)
+     {
+        _magnifier_create(data);
+        _magnifier_move(data);
+        _magnifier_show(data);
+     }
+}
+
+static void
+_signal_handler_move_end(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   elm_object_scroll_freeze_pop(data);
+
+   if (wd->have_selection)
+     {
+        _magnifier_hide(data);
+        _menu_press(data);
+     }
+}
+
+static void
+_signal_handler_moving(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   if (wd->magnifier_enabled)
+     {
+        _magnifier_move(data);
+        _magnifier_show(data);
+     }
+}
+
+static Evas_Coord_Rectangle
+_intersection_region_get(Evas_Coord_Rectangle rect1, Evas_Coord_Rectangle rect2)
+{
+   Evas_Coord_Rectangle ret_rect;
+   Evas_Coord_Point l1, l2, r1, r2, p1, p2;
+
+   l1.x = rect1.x;
+   l1.y = rect1.y;
+   r1.x = rect1.x + rect1.w;
+   r1.y = rect1.y + rect1.h;
+
+   l2.x = rect2.x;
+   l2.y = rect2.y;
+   r2.x = rect2.x + rect2.w;
+   r2.y = rect2.y + rect2.h;
+
+   p1.x = (l1.x > l2.x) ? l1.x : l2.x;
+   p1.y = (l1.y > l2.y) ? l1.y : l2.y;
+   p2.x = (r1.x < r2.x) ? r1.x : r2.x;
+   p2.y = (r1.y < r2.y) ? r1.y : r2.y;
+
+   ret_rect.x = p1.x;
+   ret_rect.y = p1.y;
+   ret_rect.w = (p2.x > p1.x) ? p2.x - p1.x : -1;
+   ret_rect.h = (p2.y > p1.y) ? p2.y - p1.y : -1;
+
+   return ret_rect;
+}
+
+static Evas_Coord_Rectangle
+_viewport_region_get(Evas_Object *data)
+{
+   Evas_Coord_Rectangle geometry, ret_rect;
+   geometry.x = geometry.y = geometry.w = geometry.h = -1;
+   ret_rect = geometry;
+
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return geometry;
+   if (!data || !strlen(elm_widget_type_get(data))) return geometry;
+
+   if (wd->scroll)
+     {
+        evas_object_geometry_get(wd->scroller, &geometry.x, &geometry.y, &geometry.w, &geometry.h);
+        ret_rect = geometry;
+     }
+
+   Evas_Object *parent_obj = data;
+
+   while ((parent_obj = elm_widget_parent_get(parent_obj)))
+     {
+        if (!strcmp(elm_widget_type_get(parent_obj), "scroller") ||
+            !strcmp(elm_widget_type_get(parent_obj), "genlist"))
+          {
+             evas_object_geometry_get(parent_obj, &geometry.x, &geometry.y, &geometry.w, &geometry.h);
+             if ((ret_rect.w == -1) && (ret_rect.h == -1)) ret_rect = geometry;
+             ret_rect = _intersection_region_get(geometry, ret_rect);
+          }
+     }
+
+   return ret_rect;
+}
+
+static Evas_Coord_Rectangle
+_layout_region_get(Evas_Object *data)
+{
+   Evas_Coord_Rectangle geometry;
+   geometry.x = geometry.y = geometry.w = geometry.h = -1;
+
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return geometry;
+   if (!data || !strlen(elm_widget_type_get(data))) return geometry;
+
+   Evas_Object *child_obj = data;
+   Evas_Object *parent_obj;
+
+   while ((parent_obj = elm_widget_parent_get(child_obj)))
+     {
+        if (!strcmp(elm_widget_type_get(parent_obj), "conformant"))
+          {
+             evas_object_geometry_get(child_obj, &geometry.x, &geometry.y, &geometry.w, &geometry.h);
+             return geometry;
+          }
+        child_obj = parent_obj;
+     }
+
+   return geometry;
+}
+
+static void
+_region_get_job(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   wd->region_get_job = NULL;
+
+   if (!_elm_config->desktop_entry)
+     {
+        if (wd->region_recalc_job) ecore_job_del(wd->region_recalc_job);
+        wd->region_recalc_job = ecore_job_add(_region_recalc_job, data);
+
+        evas_smart_objects_calculate(evas_object_evas_get(data));
+     }
+}
+
+static void
+_region_recalc_job(void *data)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   Evas_Coord_Rectangle ret_rect;
+   if (!wd) return;
+   wd->region_recalc_job = NULL;
+
+   if (!_elm_config->desktop_entry)
+     {
+        ret_rect = _viewport_region_get(data);
+        edje_object_part_text_viewport_region_set(wd->ent, "elm.text", ret_rect.x, ret_rect.y, ret_rect.w, ret_rect.h);
+        ret_rect = _layout_region_get(data);
+        edje_object_part_text_layout_region_set(wd->ent, "elm.text", ret_rect.x, ret_rect.y, ret_rect.w, ret_rect.h);
+     }
+}
+
+static void
+_signal_selection_end(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   if (wd->magnifier_enabled)
+     _magnifier_hide(data);
+   _menu_press(data);
+}
+
+static void
 _signal_entry_changed_user(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
 {
    Elm_Entry_Change_Info info;
@@ -1634,6 +2117,7 @@ _signal_selection_start(void *data, Evas_Object *obj __UNUSED__, const char *emi
         if (entry != data) elm_entry_select_none(entry);
      }
    wd->have_selection = EINA_TRUE;
+   wd->selmode = EINA_TRUE;
    evas_object_smart_callback_call(data, SIG_SELECTION_START, NULL);
 #ifdef HAVE_ELEMENTARY_X
    if (wd->sel_notify_handler)
@@ -1650,6 +2134,26 @@ _signal_selection_start(void *data, Evas_Object *obj __UNUSED__, const char *emi
 }
 
 static void
+_signal_magnifier_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Evas_Coord cx, cy, cw, ch;
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+
+   edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", &cx, &cy, &cw, &ch);
+   if (!wd->deferred_recalc_job)
+     elm_widget_show_region_set(data, cx, cy, cw, ch, EINA_FALSE);
+   else
+     {
+        wd->deferred_cur = EINA_TRUE;
+        wd->cx = cx;
+        wd->cy = cy;
+        wd->cw = cw;
+        wd->ch = ch;
+     }
+}
+
+static void
 _signal_selection_all(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
@@ -1668,11 +2172,27 @@ _signal_selection_none(void *data, Evas_Object *obj __UNUSED__, const char *emis
 static void
 _signal_selection_changed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
 {
+   Evas_Coord cx, cy, cw, ch;
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
    wd->have_selection = EINA_TRUE;
+   wd->selmode = EINA_TRUE;
    evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
    _store_selection(ELM_SEL_TYPE_PRIMARY, data);
+
+// TIZEN ONLY
+   edje_object_part_text_cursor_geometry_get(wd->ent, "elm.text", &cx, &cy, &cw, &ch);
+   if (!wd->deferred_recalc_job)
+     elm_widget_show_region_set(data, cx, cy, cw, ch, EINA_FALSE);
+   else
+     {
+        wd->deferred_cur = EINA_TRUE;
+        wd->cx = cx;
+        wd->cy = cy;
+        wd->cw = cw;
+        wd->ch = ch;
+     }
+//
 }
 
 static void
@@ -1682,6 +2202,7 @@ _signal_selection_cleared(void *data, Evas_Object *obj __UNUSED__, const char *e
    if (!wd) return;
    if (!wd->have_selection) return;
    wd->have_selection = EINA_FALSE;
+   wd->selmode = EINA_FALSE;   /////////////// exist in ours only - necessary ? 
    evas_object_smart_callback_call(data, SIG_SELECTION_CLEARED, NULL);
    if (wd->sel_notify_handler)
      {
@@ -1710,6 +2231,11 @@ _signal_selection_cleared(void *data, Evas_Object *obj __UNUSED__, const char *e
 #endif
           }
      }
+
+   if ((wd->api) && (wd->api->obj_hidemenu))
+     {
+        wd->api->obj_hidemenu(data);
+     }
 }
 
 static void
@@ -1917,7 +2443,11 @@ _signal_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
+   wd->double_clicked = EINA_FALSE;
    evas_object_smart_callback_call(data, SIG_PRESS, NULL);
+
+   if ((wd->api) && (wd->api->obj_hidemenu))
+     wd->api->obj_hidemenu(data);
 }
 
 static void
@@ -1926,6 +2456,9 @@ _signal_mouse_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emiss
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
+
+   if (!_elm_config->desktop_entry && !wd->double_clicked)
+     _cancel(data, NULL, NULL);
 }
 
 static void
@@ -1933,6 +2466,7 @@ _signal_mouse_double(void *data, Evas_Object *obj __UNUSED__, const char *emissi
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
+   wd->double_clicked = EINA_TRUE;
    evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
 }
 
@@ -2005,6 +2539,7 @@ _event_selection_notify(void *data, int type __UNUSED__, void *event)
 static Eina_Bool
 _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
 {
+#if 0
    Widget_Data *wd = elm_widget_data_get(data);
    Ecore_X_Event_Selection_Clear *ev = event;
    if (!wd) return ECORE_CALLBACK_PASS_ON;
@@ -2014,6 +2549,34 @@ _event_selection_clear(void *data __UNUSED__, int type __UNUSED__, void *event _
      {
         elm_entry_select_none(data);
      }
+#else
+
+   // start for cbhm
+   Evas_Object *top = elm_widget_top_get(data);
+   Ecore_X_Event_Selection_Clear *ev = event;
+
+   if (!top)
+      return ECORE_CALLBACK_PASS_ON;
+
+   if (ev->selection != ECORE_X_SELECTION_SECONDARY)
+     {
+        return ECORE_CALLBACK_PASS_ON;
+     }
+
+   if (cnpwidgetdata == data)
+     {
+        Widget_Data *wd = elm_widget_data_get(data);
+        Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
+        evas_object_smart_callback_call(data, SIG_SELECTION_PASTE, NULL);
+        if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
+          formats = ELM_SEL_FORMAT_TEXT;
+        else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
+          formats |= ELM_SEL_FORMAT_IMAGE;
+        elm_cnp_selection_get(data, ELM_SEL_TYPE_SECONDARY, formats, NULL, NULL);
+     }
+
+   // end for cbhm
+#endif
    return ECORE_CALLBACK_PASS_ON;
 }
 
@@ -2118,9 +2681,11 @@ _text_append_idler(void *data)
    char backup;
    Evas_Object *obj = (Evas_Object *) data;
    Widget_Data *wd = elm_widget_data_get(obj);
-   evas_event_freeze(evas_object_evas_get(obj));
    if (wd->text) eina_stringshare_del(wd->text);
    wd->text = NULL;
+   if (wd->password_text) eina_stringshare_del(wd->password_text);
+   wd->password_text = NULL;
+   evas_event_freeze(evas_object_evas_get(obj));
    wd->changed = EINA_TRUE;
 
    start = wd->append_text_position;
@@ -2275,7 +2840,6 @@ _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   evas_event_freeze(evas_object_evas_get(obj));
    if (!entry) entry = "";
    if (item && strcmp(item, "default"))
      {
@@ -2283,8 +2847,11 @@ _elm_entry_text_set(Evas_Object *obj, const char *item, const char *entry)
         return;
      }
 
+   evas_event_freeze(evas_object_evas_get(obj));
    if (wd->text) eina_stringshare_del(wd->text);
    wd->text = NULL;
+   if (wd->password_text) eina_stringshare_del(wd->password_text);
+   wd->password_text = NULL;
    wd->changed = EINA_TRUE;
 
    /* Clear currently pending job if there is one */
@@ -2329,6 +2896,7 @@ _elm_entry_text_get(const Evas_Object *obj, const char *item)
    if (item && strcmp(item, "default")) return NULL;
    const char *text;
    if (!wd) return NULL;
+
    text = edje_object_part_text_get(wd->ent, "elm.text");
    if (!text)
      {
@@ -2358,6 +2926,17 @@ _elm_entry_text_get(const Evas_Object *obj, const char *item)
      {
         eina_stringshare_replace(&wd->text, text);
      }
+   if (wd->password)
+     {
+        char *pw_text;
+        pw_text = elm_entry_markup_to_utf8(wd->text);
+        if (pw_text)
+          {
+             eina_stringshare_replace(&wd->password_text, pw_text);
+             free(pw_text);
+             return wd->password_text;
+          }
+     }
    return wd->text;
 }
 
@@ -2395,6 +2974,7 @@ elm_entry_add(Evas_Object *parent)
    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
    elm_widget_content_get_hook_set(obj, _content_get_hook);
    elm_widget_translate_hook_set(obj, _translate_hook);
+   elm_widget_event_hook_set(obj, _event_hook);
 
    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd);
 
@@ -2406,6 +2986,9 @@ elm_entry_add(Evas_Object *parent)
    wd->cnp_mode     = ELM_CNP_MODE_MARKUP;
    wd->scroll       = EINA_FALSE;
    wd->input_panel_imdata = NULL;
+//TIZEN ONLY
+   wd->magnifier_enabled = EINA_TRUE;
+//
 
    wd->ent = edje_object_add(e);
    edje_object_item_provider_set(wd->ent, _get_item, obj);
@@ -2473,13 +3056,34 @@ elm_entry_add(Evas_Object *parent)
                                    _signal_undo_request, obj);
    edje_object_signal_callback_add(wd->ent, "entry,redo,request", "elm.text",
                                    _signal_redo_request, obj);
+// TIZEN ONLY
+   edje_object_signal_callback_add(wd->ent, "handler,move,start", "elm.text",
+                                   _signal_handler_move_start, obj);
+   edje_object_signal_callback_add(wd->ent, "handler,move,end", "elm.text",
+                                   _signal_handler_move_end, obj);
+   edje_object_signal_callback_add(wd->ent, "handler,moving", "elm.text",
+                                   _signal_handler_moving, obj);
+   edje_object_signal_callback_add(wd->ent, "selection,end", "elm.text",
+                                   _signal_selection_end, obj);
+   edje_object_signal_callback_add(wd->ent, "long,pressed", "elm.text",
+                                   _signal_long_pressed, obj);
+   edje_object_signal_callback_add(wd->ent, "magnifier,changed", "elm.text",
+                                   _signal_magnifier_changed, obj);
+//
    edje_object_part_text_set(wd->ent, "elm.text", "");
    if (_elm_config->desktop_entry)
      edje_object_part_text_select_allow_set(wd->ent, "elm.text", EINA_TRUE);
+   else
+     {
+        edje_object_part_text_copy_paste_disabled_set(wd->ent, "elm.text", EINA_FALSE);
+        edje_object_part_text_viewport_region_set(wd->ent, "elm.text", -1, -1, -1, -1);
+        edje_object_part_text_layout_region_set(wd->ent, "elm.text", -1, -1, -1, -1);
+     }
    elm_widget_resize_object_set(obj, wd->ent);
    _sizing_eval(obj);
 
    elm_entry_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
+
    elm_entry_input_panel_enabled_set(obj, EINA_TRUE);
    elm_entry_prediction_allow_set(obj, EINA_TRUE);
 
@@ -2515,6 +3119,58 @@ elm_entry_add(Evas_Object *parent)
    return obj;
 }
 
+void elm_entry_extension_module_data_get(Evas_Object *obj,Elm_Entry_Extension_data *ext_mod)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   ext_mod->cancel = _cancel;
+   ext_mod->copy = _copy;
+   ext_mod->cut = _cut;
+   ext_mod->paste = _paste;
+   ext_mod->select = _select;
+   ext_mod->selectall = _selectall;
+   ext_mod->ent = wd->ent;
+   ext_mod->items = wd->items;
+   ext_mod->editable = wd->editable;
+   ext_mod->have_selection = wd->have_selection;
+   ext_mod->password = wd->password;
+   ext_mod->selmode = wd->selmode;
+   ext_mod->cnpinit = _cnpinit;
+   ext_mod->context_menu = wd->context_menu;
+   ext_mod->cnp_mode = wd->cnp_mode;
+   ext_mod->viewport_rect = _viewport_region_get(obj);
+}
+
+EAPI void
+elm_entry_text_style_user_push(Evas_Object *obj, const char *style)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_style_user_push(wd->ent, "elm.text", style);
+   _theme_hook(obj);
+}
+
+EAPI void
+elm_entry_text_style_user_pop(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   edje_object_part_text_style_user_pop(wd->ent, "elm.text");
+   _theme_hook(obj);
+}
+
+EAPI const char*
+elm_entry_text_style_user_peek(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return edje_object_part_text_style_user_peek(wd->ent, "elm.text");
+}
+
 EAPI void
 elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
 {
@@ -2529,9 +3185,12 @@ elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
    if (wd->scroller)
      {
         if (wd->single_line)
-          elm_smart_scroller_policy_set(wd->scroller,
-                                        ELM_SMART_SCROLLER_POLICY_OFF,
-                                        ELM_SMART_SCROLLER_POLICY_OFF);
+          {
+             elm_smart_scroller_policy_set(wd->scroller,
+                                           ELM_SMART_SCROLLER_POLICY_OFF,
+                                           ELM_SMART_SCROLLER_POLICY_OFF);
+             elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_FALSE, EINA_FALSE); // TIZEN ONLY
+          }
         else
           {
              const Elm_Scroller_Policy map[3] =
@@ -2543,6 +3202,7 @@ elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
              elm_smart_scroller_policy_set(wd->scroller,
                                            map[wd->policy_h],
                                            map[wd->policy_v]);
+             elm_smart_scroller_bounce_allow_set(wd->scroller, EINA_FALSE, EINA_FALSE); // TIZEN ONLY
           }
         _sizing_eval(obj);
      }
@@ -2677,19 +3337,30 @@ elm_entry_is_empty(const Evas_Object *obj)
    Evas_Textblock_Cursor *cur;
    Eina_Bool ret;
    if (!wd) return EINA_TRUE;
+
+   if (0) {  // TIZEN ONLY
    /* It's a hack until we get the support suggested above.
     * We just create a cursor, point it to the begining, and then
     * try to advance it, if it can advance, the tb is not empty,
     * otherwise it is. */
    tb = edje_object_part_object_get(wd->ent, "elm.text");
    cur = evas_object_textblock_cursor_new((Evas_Object *) tb); /* This is
-                                                                  actually, ok for the time being, thsese hackish stuff will be removed
+                                                                  actually, ok for the time being, these hackish stuff will be removed
                                                                   once evas 1.0 is out*/
    evas_textblock_cursor_pos_set(cur, 0);
    ret = evas_textblock_cursor_char_next(cur);
    evas_textblock_cursor_free(cur);
 
    return !ret;
+   }
+
+   char *str = elm_entry_markup_to_utf8(elm_entry_entry_get(obj));
+   if (!str) return EINA_TRUE;
+
+   ret = (strlen(str) == 0);
+
+   free(str);
+   return ret;
 }
 
 EAPI Evas_Object *
@@ -2731,6 +3402,12 @@ elm_entry_entry_insert(Evas_Object *obj, const char *entry)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    edje_object_part_text_insert(wd->ent, "elm.text", entry);
+   // start for cbhm
+#ifdef HAVE_ELEMENTARY_X
+   if (cnpwidgetdata == obj)
+      ecore_x_selection_secondary_set(elm_win_xwindow_get(obj), "",1);
+#endif
+   // end for cbhm
    wd->changed = EINA_TRUE;
    _sizing_eval(obj);
 }
@@ -3032,6 +3709,9 @@ elm_entry_context_menu_disabled_set(Evas_Object *obj, Eina_Bool disabled)
    if (!wd) return;
    if (wd->context_menu == !disabled) return;
    wd->context_menu = !disabled;
+
+   if (!_elm_config->desktop_entry) // TIZEN ONLY : commit ? 
+     edje_object_part_text_copy_paste_disabled_set(wd->ent, "elm.text", disabled);
 }
 
 EAPI Eina_Bool
@@ -3192,7 +3872,8 @@ elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
    if (lim->max_char_count > 0)
      {
         len = evas_string_char_len_get(current);
-        if (len >= lim->max_char_count)
+        newlen = evas_string_char_len_get(utfstr);
+        if ((len >= lim->max_char_count) && (newlen > 0))
           {
              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
              free(*text);
@@ -3201,14 +3882,14 @@ elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
              free(utfstr);
              return;
           }
-        newlen = evas_string_char_len_get(utfstr);
         if ((len + newlen) > lim->max_char_count)
           _add_chars_till_limit(entry, text, (lim->max_char_count - len), LENGTH_UNIT_CHAR);
      }
    else if (lim->max_byte_count > 0)
      {
         len = strlen(current);
-        if (len >= lim->max_byte_count)
+        newlen = strlen(utfstr);
+        if ((len >= lim->max_byte_count) && (newlen > 0))
           {
              evas_object_smart_callback_call(entry, "maxlength,reached", NULL);
              free(*text);
@@ -3217,7 +3898,6 @@ elm_entry_filter_limit_size(void *data, Evas_Object *entry, char **text)
              free(utfstr);
              return;
           }
-        newlen = strlen(utfstr);
         if ((len + newlen) > lim->max_byte_count)
           _add_chars_till_limit(entry, text, (lim->max_byte_count - len), LENGTH_UNIT_BYTE);
      }
@@ -3768,6 +4448,17 @@ _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *e
    wd->anchor_hover.hover_parent = NULL;
 }
 
+static void
+_anchor_hover_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+   if (!wd) return;
+   if (wd->anchor_hover.pop) evas_object_del(wd->anchor_hover.pop);
+   wd->anchor_hover.pop = NULL;
+   evas_object_event_callback_del_full(wd->anchor_hover.hover, EVAS_CALLBACK_DEL,
+                                       _anchor_hover_del, obj);
+}
+
 EAPI void
 elm_entry_anchor_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
 {
@@ -3844,6 +4535,8 @@ _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
    evas_object_resize(wd->anchor_hover.pop, info->w, info->h);
 
    wd->anchor_hover.hover = elm_hover_add(obj);
+   evas_object_event_callback_add(wd->anchor_hover.hover, EVAS_CALLBACK_DEL,
+                                  _anchor_hover_del, obj);
    elm_widget_mirrored_set(wd->anchor_hover.hover, elm_widget_mirrored_get(obj));
    if (wd->anchor_hover.hover_style)
      elm_object_style_set(wd->anchor_hover.hover, wd->anchor_hover.hover_style);
@@ -3890,10 +4583,39 @@ _entry_hover_anchor_clicked(void *data, Evas_Object *obj, void *event_info)
          !elm_object_part_content_get(wd->anchor_hover.hover, "bottom"))
      {
         evas_object_del(wd->anchor_hover.hover);
+        wd->anchor_hover.hover = NULL;
      }
    else
-     {
-        evas_object_show(wd->anchor_hover.hover);
-     }
+     evas_object_show(wd->anchor_hover.hover);
 }
 /* END - ANCHOR HOVER */
+
+EAPI void
+elm_entry_magnifier_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (wd->magnifier_enabled == !disabled) return;
+   wd->magnifier_enabled = !disabled;
+}
+
+EAPI Eina_Bool
+elm_entry_magnifier_disabled_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return !wd->magnifier_enabled;
+}
+
+EAPI void
+elm_entry_magnifier_type_set(Evas_Object *obj, int type)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   wd->mgf_type = type;
+   _magnifier_create(obj);
+}