tizen 2.4 release
[framework/uifw/elementary.git] / src / lib / elm_access.c
index cd0c986..30f9fad 100644 (file)
@@ -1,34 +1,18 @@
-#include <X11/Xlib.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+#define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
+#define ELM_INTERFACE_ATSPI_ACTION_PROTECTED
+
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "elm_interface_scrollable.h"
-
-static const char ACCESS_SMART_NAME[] = "elm_access";
-
-static const char SIG_HIGHLIGHTED[] = "access,highlighted";
-static const char SIG_UNHIGHLIGHTED[] = "access,unhighlighted";
-static const char SIG_ACTIVATED[] = "access,activated";
-static const char SIG_READ_START[] = "access,read,start";
-static const char SIG_READ_STOP[] = "access,read,stop";
-static const char SIG_READ_CANCEL[] = "access,read,cancel";
-static const char SIG_HIGHLIGHT_ENABLED[] = "access,highlight,enabled";
-static const char SIG_HIGHLIGHT_DISABLED[] = "access,highlight,disabled";
-
-static const Evas_Smart_Cb_Description _smart_callbacks[] = {
-   {SIG_HIGHLIGHTED, ""},
-   {SIG_UNHIGHLIGHTED, ""},
-   {SIG_ACTIVATED, ""},
-   {SIG_READ_START, ""},
-   {SIG_READ_STOP, ""},
-   {SIG_READ_CANCEL, ""},
-   {SIG_HIGHLIGHT_ENABLED, ""},
-   {SIG_HIGHLIGHT_DISABLED, ""},
-   {NULL, NULL}
-};
 
-ELM_INTERNAL_SMART_SUBCLASS_NEW
-  (ACCESS_SMART_NAME, _elm_access, Elm_Widget_Smart_Class,
-  Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks);
+#define MY_CLASS ELM_ACCESS_CLASS
+
+#define MY_CLASS_NAME "Elm_Access"
+#define MY_CLASS_NAME_LEGACY "elm_access"
 
 struct _Func_Data
 {
@@ -46,97 +30,19 @@ struct _Action_Info
 
 typedef struct _Action_Info Action_Info;
 
-static Eina_Bool highlight_read_enable = EINA_FALSE;
-static Eina_Bool access_disable = EINA_TRUE;
 static Eina_Bool mouse_event_enable = EINA_TRUE;
 static Eina_Bool auto_highlight = EINA_FALSE;
-static Eina_Bool reading_cancel = EINA_FALSE;
-static Eina_Bool focus_chain_end = EINA_FALSE;
-static Eina_Bool force_saying = EINA_FALSE;
-static Evas_Coord_Point offset;
-static Evas_Object *scroller = NULL;
-static Evas_Object *clipper = NULL;
-static Evas_Object *h_base_obj; /* highlight base object */
 static Elm_Access_Action_Type action_by = ELM_ACCESS_ACTION_FIRST;
-static Ecore_Timer *highlight_read_timer = NULL;
-static Ecore_Job *clip_job = NULL;
-static Eina_List *s_parents = NULL;
-static char *waiting_text = NULL;
 
 static Evas_Object * _elm_access_add(Evas_Object *parent);
-static void _access_scroll_highlight_next(Evas_Object *obj);
-static Eina_Bool _access_highlight_next_get(Evas_Object *obj, Elm_Access_Action_Type type, Evas_Object **target);
-static Eina_Bool _access_highlight_next(Evas_Object *obj, Elm_Access_Action_Type dir, Eina_Bool delay);
-static void _access_read_obj_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
-
-static void
-_elm_access_smart_add(Evas_Object *obj)
-{
-   EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data);
-   ELM_WIDGET_CLASS(_elm_access_parent_sc)->base.add(obj);
 
-   elm_widget_can_focus_set(obj, EINA_FALSE);
-}
-
-static Eina_Bool
-_elm_access_smart_on_focus(Evas_Object *obj, Elm_Focus_Info *info __UNUSED__)
-{
-   evas_object_focus_set(obj, elm_widget_focus_get(obj));
-
-   return EINA_TRUE;
-}
+static void _access_object_unregister(Evas_Object *obj);
 
-static Eina_Bool
-_access_highlight_end_is(Evas_Object *obj, Elm_Access_Action_Type type)
+EOLIAN static void
+_elm_access_evas_object_smart_add(Eo *obj, void *_pd EINA_UNUSED)
 {
-   Evas_Object *parent, *target = NULL;
-   Elm_Focus_Direction fdir = ELM_FOCUS_NONE;
-   Elm_Highlight_Direction hdir;
-   Eina_Bool ret;
-   Elm_Access_Info *ac;
-
-   fdir = ELM_FOCUS_NONE;
-   hdir = ELM_ACCESS_SOUND_FIRST;
-   ret = EINA_FALSE;
-
-   if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
-     {
-        hdir = ELM_HIGHLIGHT_DIR_NEXT;
-        fdir = ELM_FOCUS_NEXT;
-     }
-   else if (type == ELM_ACCESS_ACTION_HIGHLIGHT_PREV)
-     {
-        hdir = ELM_HIGHLIGHT_DIR_PREVIOUS;
-        fdir = ELM_FOCUS_PREVIOUS;
-     }
-
-   ac = _elm_access_object_get(obj);
-   if (ac && ac->end_dir == hdir)
-     {
-        ret = EINA_TRUE;
-        return ret;
-     }
-
-   parent = obj;
-
-   /* find highlight root */
-   while (parent)
-     {
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->highlight_root)
-          {
-             /* change highlight root */
-             obj = parent;
-             break;
-          }
-        obj = parent;
-        parent = elm_widget_parent_get(parent);
-     }
-
-   /* you don't have to set auto highlight here, it is set by caller */
-   ret = elm_widget_focus_next_get(obj, fdir, &target);
-
-   return !ret;
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
+   elm_widget_sub_object_parent_add(obj);
 }
 
 static Eina_Bool
@@ -151,64 +57,104 @@ _access_action_callback_call(Evas_Object *obj,
    ret = EINA_FALSE;
    a = evas_object_data_get(obj, "_elm_access_action_info");
 
-   if (type == ELM_ACCESS_ACTION_UNHIGHLIGHT) focus_chain_end = EINA_FALSE;
-
    if (!action_info)
      {
         ai = calloc(1, sizeof(Elm_Access_Action_Info));
         action_info = ai;
      }
 
-   if (action_info)
-     {
-        action_info->action_type = type;
+   action_info->action_type = type;
 
-        if ((type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT) ||
-            (type == ELM_ACCESS_ACTION_HIGHLIGHT_PREV))
-          {
-             if (a && (a->fn[type].cb))
-               action_info->highlight_end = _access_highlight_end_is(obj, type);
-          }
-     }
+   if ((type == ELM_ACCESS_ACTION_HIGHLIGHT) &&
+       (action_by != ELM_ACCESS_ACTION_FIRST))
+     action_info->action_by = action_by;
 
    if (a && (a->fn[type].cb))
      ret = a->fn[type].cb(a->fn[type].user_data, obj, action_info);
 
-   if (ai) free(ai);
+   free(ai);
 
    return ret;
 }
 
 static Eina_Bool
-_elm_access_smart_activate(Evas_Object *obj, Elm_Activate act)
+_access_action_callback_have(Evas_Object *obj, Elm_Access_Action_Type type)
 {
-   Elm_Access_Info *ac;
+   Action_Info *a;
+   a = evas_object_data_get(obj, "_elm_access_action_info");
+
+   if (!a) return EINA_FALSE;
+
+   return a->fn[type].cb ? EINA_TRUE : EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_elm_access_elm_widget_activate(Eo *obj, void *_pd EINA_UNUSED, Elm_Activate act)
+{
+   int type = ELM_ACCESS_ACTION_FIRST;
+
+   Action_Info *a;
+   a = evas_object_data_get(obj, "_elm_access_action_info");
+
+   switch (act)
+     {
+      case ELM_ACTIVATE_DEFAULT:
+        type = ELM_ACCESS_ACTION_ACTIVATE;
+        break;
+
+      case ELM_ACTIVATE_UP:
+        type = ELM_ACCESS_ACTION_UP;
+        break;
+
+      case ELM_ACTIVATE_DOWN:
+        type = ELM_ACCESS_ACTION_DOWN;
+        break;
+
+      case ELM_ACTIVATE_RIGHT:
+        break;
+
+      case ELM_ACTIVATE_LEFT:
+        break;
+
+      case ELM_ACTIVATE_BACK:
+        type = ELM_ACCESS_ACTION_BACK;
+        break;
+
+      default:
+        break;
+     }
 
+   if (type == ELM_ACCESS_ACTION_FIRST) return EINA_FALSE;
+
+   /* if an access object has a callback, it would have the intention to do
+      something. so, check here and return EINA_TRUE. */
+   if ((a) && (type > ELM_ACCESS_ACTION_FIRST) &&
+              (type < ELM_ACCESS_ACTION_LAST) &&
+              (a->fn[type].cb))
+     {
+        _access_action_callback_call(obj, type, NULL);
+        return EINA_TRUE;
+     }
+
+   /* TODO: deprecate below? */
    if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
 
-   ac = evas_object_data_get(obj, "_elm_access");
+   Elm_Access_Info *ac = evas_object_data_get(obj, "_elm_access");
    if (!ac) return EINA_FALSE;
 
    if (ac->activate)
      ac->activate(ac->activate_data, ac->part_object,
-                  (Elm_Object_Item *)ac->widget_item);
+                  ac->widget_item->eo_obj);
 
    return EINA_TRUE;
 }
 
-static void
-_elm_access_smart_set_user(Elm_Widget_Smart_Class *sc)
+EOLIAN static Eina_Bool
+_elm_access_elm_widget_on_focus(Eo *obj, void *_pd EINA_UNUSED)
 {
-   sc->base.add = _elm_access_smart_add;
-
-   /* not a 'focus chain manager' */
-   sc->focus_next = NULL;
-   sc->focus_direction_manager_is = NULL;
-   sc->focus_direction = NULL;
-   sc->on_focus = _elm_access_smart_on_focus;
-   sc->activate = _elm_access_smart_activate;
+   evas_object_focus_set(obj, elm_widget_focus_get(obj));
 
-   return;
+   return EINA_TRUE;
 }
 
 typedef struct _Mod_Api Mod_Api;
@@ -219,7 +165,6 @@ struct _Mod_Api
    void (*out_read_done) (void);
    void (*out_cancel) (void);
    void (*out_done_callback_set) (void (*func) (void *data), const void *data);
-   void (*sound_play) (const Elm_Access_Sound_Type type);
 };
 
 static int initted = 0;
@@ -243,8 +188,6 @@ _access_init(void)
       _elm_module_symbol_get(m, "out_cancel");
    ((Mod_Api *)(m->api)      )->out_done_callback_set = // called when last read done
       _elm_module_symbol_get(m, "out_done_callback_set");
-   ((Mod_Api *)(m->api)      )->sound_play = // play sound
-      _elm_module_symbol_get(m, "sound_play");
    mapi = m->api;
 }
 
@@ -259,10 +202,8 @@ _access_shutdown(void)
 
    initted = 0;
 
-   /* FIXME: _elm_module_unload(); could access m->api and try to free(); */
-   free(m->api);
-   m->api = NULL;
-   mapi = NULL;
+   /* _elm_module_unload(); could access m->api and try to free(); */
+   ELM_SAFE_FREE(m->api, free);
 }
 
 static Elm_Access_Item *
@@ -278,7 +219,7 @@ _access_add_set(Elm_Access_Info *ac, int type)
           {
              if (!ai->func)
                {
-                  if (ai->data) eina_stringshare_del(ai->data);
+                  eina_stringshare_del(ai->data);
                }
              ai->func = NULL;
              ai->data = NULL;
@@ -305,149 +246,96 @@ _access_highlight_object_get(Evas_Object *obj)
 }
 
 static void
-_access_intersection_region_get(Evas_Coord *x, Evas_Coord *y,
-                         Evas_Coord *w, Evas_Coord *h,
-                         Evas_Coord sx, Evas_Coord sy,
-                         Evas_Coord sw, Evas_Coord sh)
-{
-   Evas_Coord px = *x;
-   Evas_Coord py = *y;
-   *x = *x > sx ? *x : sx;
-   *y = *y > sy ? *y : sy;
-   *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
-   *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
-}
-
-static void
 _access_highlight_read(Elm_Access_Info *ac, Evas_Object *obj)
 {
    int type;
    char *txt = NULL;
    Eina_Strbuf *strbuf;
 
-   if (!highlight_read_enable) return;
-
    strbuf = eina_strbuf_new();
+
    if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
      {
         if (ac->on_highlight) ac->on_highlight(ac->on_highlight_data);
-        _elm_access_object_hilight(obj);
-
-        // This function is not needed, if there's any side effect, remove this
-        // elm_widget_focus_region_show(obj);
+        _elm_access_object_highlight(obj);
 
         for (type = ELM_ACCESS_INFO_FIRST + 1; type < ELM_ACCESS_INFO_LAST; type++)
           {
              txt = _elm_access_text_get(ac, type, obj);
              if (txt && (strlen(txt) > 0))
                {
-                  int length = eina_strbuf_length_get(strbuf);
-                  const char *pre_txt = eina_strbuf_string_get(strbuf);
-                  char end = pre_txt[length-1];
-                  if (length > 0 && end != '?' && end != '!' && end != '.')
+                  if (eina_strbuf_length_get(strbuf) > 0)
                     eina_strbuf_append_printf(strbuf, ", %s", txt);
                   else
-                    eina_strbuf_append_printf(strbuf, " %s", txt);
+                    eina_strbuf_append(strbuf, txt);
                }
-             if (txt) free(txt);
+             free(txt);
           }
      }
 
    txt = eina_strbuf_string_steal(strbuf);
    eina_strbuf_free(strbuf);
 
-   /* play highlight sound */
-   _access_init();
-   if (mapi && mapi->sound_play) mapi->sound_play(ELM_ACCESS_SOUND_HIGHLIGHT);
-
-   _elm_access_say(obj, txt, EINA_FALSE);
+   _elm_access_say(txt);
    free(txt);
 }
 
 static Eina_Bool
-_highlight_read_timeout_cb(void *data)
+_access_obj_over_timeout_cb(void *data)
 {
    Elm_Access_Info *ac;
+   Evas_Object *ho;
+
+   if (!data) return EINA_FALSE;
 
    ac = evas_object_data_get(data, "_elm_access");
-   if (!ac) goto end;
+   if (!ac) return EINA_FALSE;
 
-   _access_highlight_read(ac, data);
+   ho = _access_highlight_object_get(data);
+   if (ho != data) _access_highlight_read(ac, data);
 
-end:
-   highlight_read_timer = NULL;
-   return ECORE_CALLBACK_CANCEL;
+   ac->delay_timer = NULL;
+   return EINA_FALSE;
 }
 
 static void
-_access_hover_mouse_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+_access_hover_mouse_in_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info  EINA_UNUSED)
 {
    Elm_Access_Info *ac;
-
    if (!mouse_event_enable) return;
-   _elm_access_mouse_event_enabled_set(EINA_FALSE);
 
-   ac = evas_object_data_get(data, "_elm_access");
+    ac = evas_object_data_get(data, "_elm_access");
    if (!ac) return;
 
-   if (_elm_config->access_mode)
-     {
-        if (highlight_read_timer)
-          {
-             ecore_timer_del(highlight_read_timer);
-             highlight_read_timer = NULL;
-          }
+   ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
 
-        /* could not call ecore_timer_add(); here, because the callback for READ
-           action. The callback for READ action should be called even though an
-           object has a highlight. elm_win calls _access_action_callback_call()
-           for READ action. */
-        action_by = ELM_ACCESS_ACTION_HIGHLIGHT;
-        _access_highlight_read(ac, data);
-     }
+   if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
+      ac->delay_timer = ecore_timer_add(0.2, _access_obj_over_timeout_cb, data);
 }
 
 static void
-_access_parent_callback_call(Evas_Object *obj, const char *sig, void *data)
+_access_hover_mouse_out_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
    Elm_Access_Info *ac;
-   ac = evas_object_data_get(obj, "_elm_access");
-   if (ac && ac->parent)
-     evas_object_smart_callback_call(ac->parent, sig, data);
+   if (!mouse_event_enable) return;
+
+   ac = evas_object_data_get(data, "_elm_access");
+   if (!ac) return;
+
+   _elm_access_object_unhighlight(data);
+
+   ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
 }
 
 static void
-_access_read_done(void *data)
+_access_read_done(void *data EINA_UNUSED)
 {
-   Evas_Object *obj = data;
-   if (!obj) goto end;
-
-   if (!reading_cancel)
-     {
-        evas_object_smart_callback_call(obj, SIG_READ_STOP, NULL);
-        _access_parent_callback_call(obj, SIG_READ_STOP, NULL);
-     }
-   else
-     {
-        evas_object_smart_callback_call(obj, SIG_READ_CANCEL, NULL);
-        _access_parent_callback_call(obj, SIG_READ_CANCEL, NULL);
-     }
-   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
-                                       _access_read_obj_del_cb, NULL);
- end:
-   if (force_saying)
-     {
-        force_saying = EINA_FALSE;
-        if (waiting_text)
-          {
-             _elm_access_say(NULL, waiting_text, EINA_FALSE);
-             waiting_text = NULL;
-          }
-     }
+   DBG("read done");
+   // FIXME: produce event here
 }
 
 static void
-_access_2nd_click_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_access_2nd_click_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    Ecore_Timer *t;
 
@@ -471,190 +359,31 @@ _access_2nd_click_timeout_cb(void *data)
 }
 
 static void
-_access_obj_hilight_del_cb(void *data __UNUSED__, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   _elm_access_object_hilight_disable(e);
-   elm_widget_focus_restore(elm_widget_top_get(obj));
-}
-
-static void
-_access_obj_hilight_hide_cb(void *data __UNUSED__, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   _elm_access_object_hilight_disable(e);
-   elm_widget_focus_restore(elm_widget_top_get(obj));
-}
-
-static Eina_List *
-_access_scrollable_parents_get(Evas_Object *obj,
-                               Evas_Coord *x,
-                               Evas_Coord *y,
-                               Evas_Coord *w,
-                               Evas_Coord *h)
-{
-   Evas_Object *sp;
-   Eina_List *l = NULL;
-   Evas_Coord sx, sy, sw, sh;
-
-   if (!obj) return NULL;
-
-   if (x) *x = -49999;
-   if (y) *y = -49999;
-   if (w) *w = 99999;
-   if (h) *h = 99999;
-
-   sp = elm_widget_parent_get(obj);
-   while (sp)
-     {
-        if(!!evas_object_smart_interface_get(sp, ELM_SCROLLABLE_IFACE_NAME))
-          {
-             l = eina_list_append(l, sp);
-             evas_object_geometry_get(sp, &sx, &sy, &sw, &sh);
-             if(x && y && w && h)
-               _access_intersection_region_get(x, y, w, h, sx, sy, sw, sh);
-          }
-        sp = elm_widget_parent_get(sp);
-     }
-   return l;
-}
-
-static Evas_Object *
-_access_scrollable_object_at_xy_get(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
-{
-   Evas *evas;
-   Evas_Object *so, *scr = NULL;
-   Evas_Object *top_obj;
-   Eina_List *l, *top_objects_list = NULL;
-
-   evas = evas_object_evas_get(obj);
-   if (!evas) return NULL;
-
-   top_objects_list = evas_tree_objects_at_xy_get(evas, NULL, x, y);
-
-   EINA_LIST_REVERSE_FOREACH(top_objects_list, l, top_obj)
-     {
-        so = top_obj;
-
-        while (so)
-          {
-             if(elm_object_widget_check(so) &&
-                !!evas_object_smart_interface_get(so, ELM_SCROLLABLE_IFACE_NAME))
-               {
-                  scr = so;
-                  break;
-               }
-             so = evas_object_smart_parent_get(so);
-          }
-        if (scr) break;
-     }
-
-   return scr;
-}
-
-static void
-_clipper_del_cb(void *data __UNUSED__, Evas *e __UNUSED__,
-                 Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
-{
-   clipper = NULL;
-}
-
-static void
-_access_scrollable_parent_clip(void *data)
+_access_obj_hilight_del_cb(void *data EINA_UNUSED, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
-   Evas_Object *obj = data;
-   Evas_Object *o;
-   Eina_List *l;
-   Evas_Coord x = 0, y = 0, w = 0, h = 0;
-
-   clip_job = NULL;
-   o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
-   if (!o) return;
-
-   l = _access_scrollable_parents_get(obj, &x, &y, &w, &h);
-   if (l && w > 0 && h > 0)
-     {
-        if (evas_object_evas_get(obj) != evas_object_evas_get(clipper))
-          {
-             evas_object_del(clipper);
-             clipper = NULL;
-          }
-        if (!clipper)
-          {
-             clipper = evas_object_rectangle_add(evas_object_evas_get(obj));
-             evas_object_event_callback_add(clipper, EVAS_CALLBACK_DEL, _clipper_del_cb, NULL);
-          }
-        evas_object_move(clipper, x, y);
-        evas_object_resize(clipper, w, h);
-        evas_object_show(clipper);
-        evas_object_clip_set(o, clipper);
-     }
-   else
-     {
-        evas_object_clip_set(o, NULL);
-        if (clipper)
-          evas_object_hide(clipper);
-     }
-   eina_list_free(l);
+   _elm_access_object_highlight_disable(e);
 }
 
 static void
-_access_obj_scroll_virtual_value_get(Evas_Object *obj, Evas_Coord *vx, Evas_Coord *vy)
+_access_obj_hilight_hide_cb(void *data EINA_UNUSED, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
-   Eina_Bool lh, lv;
-   Evas_Coord x, y, sx, sy, vw, vh, cx, cy, cw, ch;
-   Evas_Object *sp = NULL;
-   Eina_List *l;
-
-   *vx = 0;
-   *vy = 0;
-
-   l = _access_scrollable_parents_get(obj, NULL, NULL, NULL, NULL);
-   if (l) sp = eina_list_data_get(l);
-   eina_list_free(l);
-
-   if (!sp) return;
-
-   ELM_SCROLLABLE_IFACE_GET(sp, s_iface);
-   s_iface->loop_get(sp, &lh, &lv);
-
-   if (lh || lv)
-     {
-        s_iface->content_pos_get(sp, &cx, &cy);
-        s_iface->content_size_get(sp, &cw, &ch);
-        evas_object_geometry_get(obj, &x, &y, NULL, NULL);
-        evas_object_geometry_get(sp, &sx, &sy, NULL, NULL);
-        s_iface->content_viewport_size_get(sp, &vw, &vh);
-
-        if ((cx > (cw - vw)) && (sx - x) > (cw - vw))
-          *vx = cw;
-        else
-          *vx = 0;
-
-        if ((cy > (ch - vh)) && (sy - y) > (ch - vh))
-          *vy = ch;
-        else
-          *vy = 0;
-     }
+   _elm_access_object_highlight_disable(e);
 }
 
 static void
-_access_obj_hilight_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_access_obj_hilight_move_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
-   Evas_Coord x, y, vx, vy;
+   Evas_Coord x, y;
    Evas_Object *o;
 
    o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
    if (!o) return;
    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
-   _access_obj_scroll_virtual_value_get(obj, &vx, &vy);
-   x += vx;
-   y += vy;
    evas_object_move(o, x, y);
-
-   _access_scrollable_parent_clip(obj);
 }
 
 static void
-_access_obj_hilight_resize_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_access_obj_hilight_resize_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    Evas_Coord w, h;
    Evas_Object *o;
@@ -663,9 +392,6 @@ _access_obj_hilight_resize_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Ob
    if (!o) return;
    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
    evas_object_resize(o, w, h);
-
-   if (clip_job) ecore_job_del(clip_job);
-   clip_job = ecore_job_add(_access_scrollable_parent_clip, obj);
 }
 
 void
@@ -698,18 +424,18 @@ _elm_access_shutdown()
 
 static void
 _access_order_del_cb(void *data,
-                     Evas *e __UNUSED__,
+                     Evas *e EINA_UNUSED,
                      Evas_Object *obj,
-                     void *event_info __UNUSED__)
+                     void *event_info EINA_UNUSED)
 {
-   Elm_Widget_Item *item = data;
+   Elm_Widget_Item_Data *item = data;
 
    item->access_order = eina_list_remove(item->access_order, obj);
 }
 
 void
-_elm_access_widget_item_access_order_set(Elm_Widget_Item *item,
-                                              Eina_List *objs)
+_elm_access_widget_item_access_order_set(Elm_Widget_Item_Data *item,
+                                         Eina_List *objs)
 {
    Eina_List *l;
    Evas_Object *o;
@@ -728,14 +454,14 @@ _elm_access_widget_item_access_order_set(Elm_Widget_Item *item,
 }
 
 const Eina_List *
-_elm_access_widget_item_access_order_get(const Elm_Widget_Item *item)
+_elm_access_widget_item_access_order_get(const Elm_Widget_Item_Data *item)
 {
    if (!item) return NULL;
    return item->access_order;
 }
 
 void
-_elm_access_widget_item_access_order_unset(Elm_Widget_Item *item)
+_elm_access_widget_item_access_order_unset(Elm_Widget_Item_Data *item)
 {
    Eina_List *l, *l_next;
    Evas_Object *o;
@@ -750,864 +476,96 @@ _elm_access_widget_item_access_order_unset(Elm_Widget_Item *item)
      }
 }
 
-static void
-_access_s_parent_del_cb(void *data __UNUSED__, Evas *e __UNUSED__,
-                 Evas_Object *obj, void *event_info __UNUSED__)
+static Eina_Bool
+_access_highlight_next_get(Evas_Object *obj, Elm_Focus_Direction dir)
 {
-   Evas *evas;
-
-   evas = evas_object_evas_get(obj);
-   if (!evas) return;
-
-   evas_event_feed_mouse_move(evas, INT_MIN, INT_MIN, ecore_loop_time_get() * 1000, NULL);
-   evas_event_feed_mouse_up(evas, 1, EVAS_BUTTON_NONE, ecore_loop_time_get() * 1000, NULL);
-
-   s_parents = eina_list_remove(s_parents, obj);
-}
+   int type;
+   Evas_Object *ho, *parent, *target;
+   Eina_Bool ret;
 
-static void
-_scroll_cb(void *data __UNUSED__ , Evas_Object *obj, void *event_info __UNUSED__)
-{
-   _access_scroll_highlight_next(obj);
-}
+   target = NULL;
+   ret = EINA_FALSE;
 
-static void
-_scroll_repeat_events_set(Evas_Object *obj, Eina_Bool repeat_events)
-{
-   ELM_SCROLLABLE_IFACE_GET(obj, s_iface);
-   s_iface->repeat_events_set(obj, repeat_events);
-}
+   if (!elm_widget_is(obj)) return ret;
 
-static Eina_Bool
-_scroll_repeat_events_get(Evas_Object *obj)
-{
-   ELM_SCROLLABLE_IFACE_GET(obj, s_iface);
-   return s_iface->repeat_events_get(obj);
-}
+   ho = _access_highlight_object_get(obj);
+   if (!ho) ho = obj;
 
-static void
-_scroll_anim_stop_cb(void *data __UNUSED__ , Evas_Object *obj, void *event_info __UNUSED__)
-{
-   Eina_List *l = NULL;
-   Evas_Object *sp;
+   parent = ho;
 
-   if (_scroll_repeat_events_get(obj))
+   /* find highlight root */
+   do
      {
-        EINA_LIST_FOREACH(s_parents, l, sp)
+        ELM_WIDGET_DATA_GET_OR_RETURN(parent, wd, ret);
+        if (wd->highlight_root)
           {
-             evas_object_smart_callback_del(sp, "scroll", _scroll_cb);
-             evas_object_smart_callback_del(sp, "scroll,anim,stop", _scroll_anim_stop_cb);
-             _scroll_repeat_events_set(sp, EINA_TRUE);
+             /* change highlight root */
+             obj = parent;
+             break;
           }
+        parent = elm_widget_parent_get(parent);
      }
-}
+   while (parent);
 
-static void
-_access_scroll_highlight_next(Evas_Object *obj)
-{
-   Evas_Object *ho, *cur_ho;
-   static Evas_Object *pre_ho = NULL;
-   Evas_Coord hx, hy, hw, hh, sx, sy, sw, sh, vx, vy;
-   Eina_List *new_s_parents, *l = NULL;
-   Evas_Object *sp, *nsp;
-   Eina_Bool done = EINA_FALSE;
-   int direction = -1;
-   Elm_Focus_Direction dir;
-   int scroll_count_down = 0;
-   int scroll_count_up = 0;
+   _elm_access_auto_highlight_set(EINA_TRUE);
 
-   if (!obj) return;
-   if (!s_parents) return;
+   if (dir == ELM_FOCUS_NEXT)
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+   else
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+
+   /* this value is used in _elm_access_object_highlight();
+      to inform the target object of how to get highlight */
+   action_by = type;
 
-   cur_ho = ho = _access_highlight_object_get(obj);
-   while (!done)
+   if (!_access_action_callback_call(ho, type, NULL))
      {
         if (ho)
           {
-             evas_object_geometry_get(ho, &hx, &hy, &hw, &hh);
-             _access_obj_scroll_virtual_value_get(ho, &vx, &vy);
-             hx += vx;
-             hy += vy;
+             Elm_Access_Info *info = _elm_access_info_get(ho);
+             if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT && info->next)
+               target = info->next;
+             else if (type == ELM_ACCESS_ACTION_HIGHLIGHT_PREV && info->prev)
+               target = info->prev;
+          }
 
-             l = _access_scrollable_parents_get(ho, &sx, &sy, &sw, &sh);
-             if (!l) return;
-             eina_list_free(l);
+        if (target)
+          {
+             _elm_access_highlight_set(target);
+             elm_widget_focus_region_show(target);
+             ret = EINA_TRUE;
+          }
+        else
+          {
+             ret = elm_widget_focus_next_get(obj, dir, &target);
+             if (ret && target)
+               _elm_access_highlight_set(target);
+          }
+     }
 
-             if (hx + (hw / 2) < sx || hy + (hh / 2) < sy)
-               {
-                  if (direction < 0 || direction == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
-                    {
-                       direction = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
-                       done = !_access_highlight_next_get(obj, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, &ho);
-                       if (!done && !ho) ho = _access_highlight_object_get(obj);
-                    }
-                  else
-                    {
-                       done = !_access_highlight_next_get(obj, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, &ho);
-                       if (!done && !ho) ho = _access_highlight_object_get(obj);
-                    }
-                  scroll_count_down++;
-               }
-             else if (hx + (hw / 2) > sx + sw || hy + (hh / 2) > sy + sh)
-               {
-                  if (direction < 0 || direction == ELM_ACCESS_ACTION_HIGHLIGHT_PREV)
-                    {
-                       direction = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
-                       done = !_access_highlight_next_get(obj, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, &ho);
-                       if (!done && !ho) ho = _access_highlight_object_get(obj);
-                    }
-                  else
-                    {
-                       done = !_access_highlight_next_get(obj, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, &ho);
-                       if (!done && !ho) ho = _access_highlight_object_get(obj);
-                    }
-                  scroll_count_up++;
-               }
-             else
-               done = EINA_TRUE;
-
-             //prevent watchdog issue
-             if (scroll_count_down > 50 || scroll_count_up > 50)
-               {
-                  return;
-               }
-
-             _elm_access_object_hilight(ho);
-             /* scrollable parent could be changed when highlight object is
-                changed. FIXME: scrollable parent could be null.. then? */
-             new_s_parents = _access_scrollable_parents_get(ho, NULL, NULL, NULL, NULL);
-
-             sp = eina_list_data_get(s_parents);
-             nsp = eina_list_data_get(new_s_parents);
-             if ((nsp) && (sp != nsp))
-               {
-                  EINA_LIST_FOREACH(s_parents, l, sp)
-                    {
-                       evas_object_event_callback_del(sp, EVAS_CALLBACK_DEL,
-                                                      _access_s_parent_del_cb);
-                       evas_object_smart_callback_del(sp, "scroll", _scroll_cb);
-                       evas_object_smart_callback_del(sp, "scroll,anim,stop", _scroll_anim_stop_cb);
-                    }
-                  EINA_LIST_FOREACH(new_s_parents, l, nsp)
-                    {
-                       evas_object_event_callback_add(nsp, EVAS_CALLBACK_DEL,
-                                                      _access_s_parent_del_cb, NULL);
-                       evas_object_smart_callback_add(nsp, "scroll", _scroll_cb, NULL);
-                       evas_object_smart_callback_add(nsp, "scroll,anim,stop", _scroll_anim_stop_cb, NULL);
-                    }
-                  eina_list_free(s_parents);
-                  s_parents = new_s_parents;
-               }
-
-             if (cur_ho == ho) done = EINA_TRUE;
-          }
-        else
-          done = EINA_TRUE;
-     }
-
-      scroll_count_down = 0;
-      scroll_count_up = 0;
-
-   dir = (direction == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT) ? ELM_FOCUS_NEXT : ELM_FOCUS_PREVIOUS;
-
-   if (!_elm_access_widget_highlight(ho, dir))
-     {
-        if (cur_ho != ho && pre_ho != ho)
-          {
-             pre_ho = ho;
-             _elm_access_highlight_set(ho, EINA_TRUE);
-          }
-     }
-}
-
-void
-_elm_access_highlight_object_scroll(Evas_Object *obj, int type, int x, int y)
-{
-   Evas *evas;
-   Eina_List *l = NULL;
-   Evas_Object *ho, *sp;
-
-   if (!obj) return;
-
-   evas = evas_object_evas_get(obj);
-   if (!evas) return;
-
-   switch (type)
-     {
-      case 0:
-         if (s_parents)
-           {
-              EINA_LIST_FOREACH(s_parents, l, sp)
-                {
-                   evas_object_event_callback_del(sp, EVAS_CALLBACK_DEL,
-                                                  _access_s_parent_del_cb);
-                   evas_object_smart_callback_del(sp, "scroll", _scroll_cb);
-                   evas_object_smart_callback_del(sp, "scroll,anim,stop", _scroll_anim_stop_cb);
-                }
-              eina_list_free(s_parents);
-              s_parents = NULL;
-           }
-
-         ho = _access_highlight_object_get(obj);
-         if (ho)
-           {
-              /* find scrollable parents */
-              s_parents = _access_scrollable_parents_get(ho, NULL, NULL, NULL, NULL);
-
-              if (s_parents)
-                {
-                   EINA_LIST_FOREACH(s_parents, l, sp)
-                     {
-                        evas_object_event_callback_add(sp, EVAS_CALLBACK_DEL,
-                                                       _access_s_parent_del_cb, NULL);
-                        evas_object_smart_callback_add(sp, "scroll", _scroll_cb, NULL);
-                        evas_object_smart_callback_add(sp, "scroll,anim,stop", _scroll_anim_stop_cb, NULL);
-                     }
-                }
-           }
-
-         scroller = _access_scrollable_object_at_xy_get(obj, x, y);
-         if (scroller)
-           {
-              _scroll_repeat_events_set(scroller, EINA_FALSE);
-
-              evas_event_feed_mouse_in(evas, ecore_loop_time_get() * 1000, NULL);
-              evas_event_feed_mouse_move(evas, x, y, ecore_loop_time_get() * 1000, NULL);
-              evas_event_feed_mouse_down(evas, 1, EVAS_BUTTON_NONE, ecore_loop_time_get() * 1000, NULL);
-           }
-         break;
-
-      case 1:
-         if (scroller)
-           evas_event_feed_mouse_move(evas, x, y, ecore_loop_time_get() * 1000, NULL);
-         break;
-
-      case 2:
-         if (scroller)
-           {
-              evas_event_feed_mouse_up(evas, 1, EVAS_BUTTON_NONE, ecore_loop_time_get() * 1000, NULL);
-              _scroll_repeat_events_set(scroller, EINA_TRUE);
-              scroller = NULL;
-           }
-         break;
-
-      default:
-         break;
-     }
-}
-
-static unsigned int
-_elm_access_win_angle_get(Ecore_X_Window win)
-{
-   Ecore_X_Window root;
-
-   if (!win) return 0;
-
-   int ret;
-   int count;
-   int angle = 0;
-   unsigned char *prop_data = NULL;
-
-   root = ecore_x_window_root_get(win);
-   ret = ecore_x_window_prop_property_get(root,
-                                          ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
-                                          ECORE_X_ATOM_CARDINAL,
-                                          32, &prop_data, &count);
-
-   if (ret && prop_data)
-     memcpy(&angle, prop_data, sizeof(int));
-
-   if (prop_data) free(prop_data);
-
-   return angle;
-}
-
-static void
-_elm_access_coordinate_calibrate(Ecore_X_Window win, int *x, int *y)
-{
-   int tx, ty, w, h;
-   unsigned int angle;
-
-   if (!x) return;
-   if (!y) return;
-
-   angle = _elm_access_win_angle_get(win);
-   ecore_x_window_geometry_get(win, NULL, NULL, &w, &h);
-
-   tx = *x;
-   ty = *y;
-
-   switch (angle)
-     {
-      case 90:
-         *x = ty;
-         *y = h - tx;
-         break;
-
-      case 180:
-         *x = w - tx;
-         *y = h - ty;
-         break;
-
-      case 270:
-         *x = w - ty;
-         *y = tx;
-         break;
-
-      default:
-         break;
-     }
-}
-
-static Eina_Bool
-_elm_access_mouse_move_send(Ecore_X_Window win,
-                        int x,
-                        int y)
-{
-   XEvent xev;
-   XWindowAttributes att;
-   Window tw;
-   int rx, ry;
-   Ecore_X_Display *_ecore_x_disp = ecore_x_display_get();
-
-   _elm_access_coordinate_calibrate(win, &x, &y);
-   XGetWindowAttributes(_ecore_x_disp, win, &att);
-   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
-   xev.xmotion.type = MotionNotify;
-   xev.xmotion.window = win;
-   xev.xmotion.root = att.root;
-   xev.xmotion.subwindow = win;
-   xev.xmotion.time = ecore_loop_time_get() * 1000;
-   xev.xmotion.x = x;
-   xev.xmotion.y = y;
-   xev.xmotion.x_root = rx;
-   xev.xmotion.y_root = ry;
-   xev.xmotion.state = 0;
-   xev.xmotion.is_hint = 0;
-   xev.xmotion.same_screen = 1;
-   return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev) ? EINA_TRUE : EINA_FALSE;
-}
-
-static Eina_Bool
-_elm_access_mouse_down_send(Ecore_X_Window win,
-                        int x,
-                        int y,
-                        int b)
-{
-   XEvent xev;
-   XWindowAttributes att;
-   Window tw;
-   int rx, ry;
-   Ecore_X_Display *_ecore_x_disp = ecore_x_display_get();
-
-   _elm_access_coordinate_calibrate(win, &x, &y);
-   XGetWindowAttributes(_ecore_x_disp, win, &att);
-   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
-   xev.xbutton.type = ButtonPress;
-   xev.xbutton.window = win;
-   xev.xbutton.root = att.root;
-   xev.xbutton.subwindow = win;
-   xev.xbutton.time = ecore_loop_time_get() * 1000;
-   xev.xbutton.x = x;
-   xev.xbutton.y = y;
-   xev.xbutton.x_root = rx;
-   xev.xbutton.y_root = ry;
-   xev.xbutton.state = 1 << b;
-   xev.xbutton.button = b;
-   xev.xbutton.same_screen = 1;
-   return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev) ? EINA_TRUE : EINA_FALSE;
-}
-
-static Eina_Bool
-_elm_access_mouse_up_send(Ecore_X_Window win,
-                      int x,
-                      int y,
-                      int b)
-{
-   XEvent xev;
-   XWindowAttributes att;
-   Window tw;
-   int rx, ry;
-   Ecore_X_Display *_ecore_x_disp = ecore_x_display_get();
-
-   _elm_access_coordinate_calibrate(win, &x, &y);
-   XGetWindowAttributes(_ecore_x_disp, win, &att);
-   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
-   xev.xbutton.type = ButtonRelease;
-   xev.xbutton.window = win;
-   xev.xbutton.root = att.root;
-   xev.xbutton.subwindow = win;
-   xev.xbutton.time = ecore_loop_time_get() * 1000;
-   xev.xbutton.x = x;
-   xev.xbutton.y = y;
-   xev.xbutton.x_root = rx;
-   xev.xbutton.y_root = ry;
-   xev.xbutton.state = 0;
-   xev.xbutton.button = b;
-   xev.xbutton.same_screen = 1;
-   return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev) ? EINA_TRUE : EINA_FALSE;
-}
-
-static Eina_Bool
-_elm_access_mouse_in_send(Ecore_X_Window win,
-                      int x,
-                      int y)
-{
-   XEvent xev;
-   XWindowAttributes att;
-   Window tw;
-   int rx, ry;
-   Ecore_X_Display *_ecore_x_disp = ecore_x_display_get();
-
-   _elm_access_coordinate_calibrate(win, &x, &y);
-   XGetWindowAttributes(_ecore_x_disp, win, &att);
-   XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
-   xev.xcrossing.type = EnterNotify;
-   xev.xcrossing.window = win;
-   xev.xcrossing.root = att.root;
-   xev.xcrossing.subwindow = win;
-   xev.xcrossing.time = ecore_loop_time_get() * 1000;
-   xev.xcrossing.x = x;
-   xev.xcrossing.y = y;
-   xev.xcrossing.x_root = rx;
-   xev.xcrossing.y_root = ry;
-   xev.xcrossing.mode = NotifyNormal;
-   xev.xcrossing.detail = NotifyNonlinear;
-   xev.xcrossing.same_screen = 1;
-   xev.xcrossing.focus = 0;
-   xev.xcrossing.state = 0;
-   return XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev) ? EINA_TRUE : EINA_FALSE;
-}
-
-void
-_elm_access_highlight_object_mouse(Evas_Object *obj, int type, int x, int y)
-{
-   Evas *evas;
-   Evas_Object *ho, *win;
-   Evas_Coord_Rectangle ho_area;
-
-#ifdef HAVE_ELEMENTARY_X
-   Ecore_X_Window xwin = 0;
-#endif
-
-   if (!obj) return;
-
-   evas = evas_object_evas_get(obj);
-   if (!evas) return;
-
-   switch (type)
-     {
-      case 0:
-        ho = _access_highlight_object_get(obj);
-        if (!ho)
-          {
-             h_base_obj = NULL;
-             return;
-          }
-        else
-          {
-             h_base_obj = ho;
-             evas_object_geometry_get
-               (ho, &ho_area.x, &ho_area.y, &ho_area.w, &ho_area.h);
-
-             offset.x = x - (ho_area.x + (ho_area.w / 2));
-             offset.y = y - (ho_area.y + (ho_area.h / 2));
-          }
-
-#ifdef HAVE_ELEMENTARY_X
-        win = elm_widget_top_get(ho);
-        xwin = elm_win_xwindow_get(win);
-        if (!xwin) return;
-
-        x = x - offset.x;
-        y = y - offset.y;
-        _elm_access_mouse_in_send(xwin, x, y);
-        _elm_access_mouse_move_send(xwin, x, y);
-        _elm_access_mouse_down_send(xwin, x, y, 1);
-#endif
-        break;
-
-      case 1:
-        if (!h_base_obj) return;
-
-#ifdef HAVE_ELEMENTARY_X
-        win = elm_widget_top_get(h_base_obj);
-        xwin = elm_win_xwindow_get(win);
-        if (!xwin) return;
-
-        _elm_access_mouse_move_send(xwin, x - offset.x, y - offset.y);
-#endif
-        break;
-
-      case 2:
-        if (!h_base_obj) return;
-
-#ifdef HAVE_ELEMENTARY_X
-        win = elm_widget_top_get(h_base_obj);
-        xwin = elm_win_xwindow_get(win);
-        if (!xwin) return;
-
-        _elm_access_mouse_up_send(xwin, x - offset.x, y - offset.y, 1);
-        h_base_obj = NULL;
-#endif
-        break;
-
-      default:
-        break;
-     }
-}
-static void
-_highlight_next_get_internal(const Evas_Object *obj,
-                            Elm_Highlight_Direction dir,
-                            Evas_Object **next)
-{
-   Elm_Access_Info *info;
-   Evas_Object *comming = NULL;
-   *next = NULL;
-
-   info = _elm_access_object_get(obj);
-   if (!info) return;
-
-   if (dir == ELM_HIGHLIGHT_DIR_NEXT)
-     comming = info->next;
-   else
-     comming = info->prev;
-
-   if (!comming) return;
-   else
-     {
-        if (!evas_object_visible_get(comming)
-            || (elm_widget_tree_unfocusable_get(comming)))
-          _highlight_next_get_internal(comming, dir, next);
-        else
-          *next = comming;
-     }
-}
-
-static Eina_Bool
-_access_widget_highlight(Evas_Object *obj, Elm_Focus_Direction dir)
-{
-   Evas_Object *parent, *o;
-
-   if (!obj) return EINA_FALSE;
-
-   parent = obj;
-   while (parent)
-     {
-        o = elm_widget_parent_get(parent);
-        if (!o) break;
-        if (elm_widget_tree_unfocusable_get(o)) return EINA_FALSE;
-        parent = o;
-     }
-
-   parent = obj;
-   while (parent)
-     {
-        /* if an widget works for highlighting by itself, then give a chance to
-           the widget to highlight. the widget should return EINA_TRUE, when it
-           has its own work for highlighting. */
-        if (_elm_access_widget_highlight(parent, dir)) return EINA_TRUE;
-
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->highlight_root) break;
-
-        parent = elm_widget_parent_get(parent);
-     }
-
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_access_highlight_next_get(Evas_Object *obj, Elm_Access_Action_Type type, Evas_Object **target)
-{
-   Evas_Object *ho, *parent;
-   Elm_Focus_Direction dir;
-   Elm_Access_Info *ac;
-   Eina_Bool ret;
-   ret = EINA_FALSE;
-
-   if (!target)
-     return EINA_FALSE;
-
-   *target = NULL;
-   dir = ELM_FOCUS_NEXT;
-
-   ho = _access_highlight_object_get(obj);
-
-   parent = ho;
-
-   /* find highlight root */
-   while (parent)
-     {
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->highlight_root)
-          {
-             /* change highlight root */
-             obj = parent;
-             break;
-          }
-        parent = elm_widget_parent_get(parent);
-     }
-
-   _elm_access_auto_highlight_set(EINA_TRUE);
-
-   action_by = type;
-
-   if (!_access_action_callback_call(ho, type, NULL))
-     {
-        if (ho)
-          {
-             if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
-               _highlight_next_get_internal(ho,
-                                            ELM_HIGHLIGHT_DIR_NEXT,
-                                            target);
-             else
-               _highlight_next_get_internal(ho,
-                                            ELM_HIGHLIGHT_DIR_PREVIOUS,
-                                            target);
-          }
-
-        if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
-          dir = ELM_FOCUS_NEXT;
-        else if (type == ELM_ACCESS_ACTION_HIGHLIGHT_PREV)
-          dir = ELM_FOCUS_PREVIOUS;
-
-        if (*target)
-          {
-             elm_widget_focus_next_get(*target, dir, target);
-             ret = EINA_TRUE;
-          }
-        else
-          {
-             if (_access_widget_highlight(ho, dir))
-               {
-                  /* return EINA_TRUE with *target = NULL */
-                  ret = EINA_TRUE;
-               }
-             else
-               ret = elm_widget_focus_next_get(obj, dir, target);
-          }
-     }
-   else
-     {
-       /* The object does something for highlight next, prev */
-       ac = _elm_access_object_get(ho);
-       if (ac) ac->action_relay = EINA_TRUE;
-     }
+   action_by = ELM_ACCESS_ACTION_FIRST;
 
    _elm_access_auto_highlight_set(EINA_FALSE);
 
    return ret;
 }
 
-static Eina_Bool
-_access_highlight_next(Evas_Object *obj, Elm_Access_Action_Type type, Eina_Bool delay)
-{
-   Evas_Object *target;
-   Eina_Bool ret;
-
-   ret = _access_highlight_next_get(obj, type, &target);
-
-   if (ret && target)
-     {
-        _elm_access_highlight_set(target, delay);
-        elm_widget_focus_region_show(target);
-     }
-   return ret;
-}
-
-void
-_elm_access_highlight_read_enable_set(Evas_Object *obj, Eina_Bool enabled, Eina_Bool access)
-{
-   Evas *evas;
-   Eina_List *l = NULL;
-   Evas_Object *o, *sp;
-   if (!obj) return;
-
-   enabled = !!enabled;
-   access = !!access;
-
-   if (access)
-     {
-        if(!enabled) access_disable = EINA_TRUE;
-        else access_disable = EINA_FALSE;
-     }
-   else if (access_disable) return;
-
-   if (highlight_read_enable == enabled) return;
-   highlight_read_enable = enabled;
-
-   if (highlight_read_enable)
-     {
-        elm_widget_focus_restore(obj);
-        evas_object_smart_callback_call(obj, SIG_HIGHLIGHT_ENABLED, NULL);
-     }
-   else
-     {
-        if (s_parents)
-          {
-             sp = eina_list_data_get(s_parents);
-             _scroll_repeat_events_set(sp, EINA_TRUE);
-
-             EINA_LIST_FOREACH(s_parents, l, sp)
-               {
-                  evas_object_event_callback_del(sp, EVAS_CALLBACK_DEL,
-                                                 _access_s_parent_del_cb);
-                  evas_object_smart_callback_del(sp, "scroll", _scroll_cb);
-                  evas_object_smart_callback_del(sp, "scroll,anim,stop", _scroll_anim_stop_cb);
-               }
-             eina_list_free(s_parents);
-             s_parents = NULL;
-          }
-        evas = evas_object_evas_get(obj);
-        o = evas_object_name_find(evas, "_elm_access_disp");
-        if (o)
-          {
-             if (clip_job)
-               ecore_job_del(clip_job);
-             clip_job = NULL;
-             if (clipper)
-               evas_object_hide(clipper);
-             evas_object_hide(o);
-          }
-        evas_event_feed_mouse_move(evas, INT_MIN, INT_MIN, ecore_loop_time_get() * 1000, NULL);
-        evas_event_feed_mouse_up(evas, 1, EVAS_BUTTON_NONE, ecore_loop_time_get() * 1000, NULL);
-        evas_object_smart_callback_call(obj, SIG_HIGHLIGHT_DISABLED, NULL);
-     }
-}
-
-void
-_elm_access_all_read_stop(void)
-{
-   _access_init();
-   if (mapi)
-     {
-        if (mapi->out_done_callback_set)
-           mapi->out_done_callback_set(NULL, NULL);
-     }
-}
-
-static void
-_access_all_read_done(void *data)
-{
-   Eina_Bool ret;
-   ret = _access_highlight_next(data, ELM_FOCUS_NEXT, EINA_FALSE);
-
-   if (!ret) _elm_access_all_read_stop();
-}
-
-void
-_elm_access_all_read_start(Evas_Object *obj)
-{
-   int type;
-   Evas_Object *ho, *parent, *target;
-   Eina_Bool ret;
-
-   target = NULL;
-   ret = EINA_FALSE;
-
-   ho = _access_highlight_object_get(obj);
-   parent = ho;
-
-   /* find highlight root */
-   while (parent)
-     {
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->highlight_root)
-          {
-             /* change highlight root */
-             obj = parent;
-             break;
-          }
-        parent = elm_widget_parent_get(parent);
-     }
-
-   if (ho) _elm_access_object_unhilight(ho);
-
-   _access_init();
-   if (mapi)
-     {
-        if (mapi->out_done_callback_set)
-           mapi->out_done_callback_set(_access_all_read_done, obj);
-     }
-
-   _elm_access_auto_highlight_set(EINA_TRUE);
-
-   ret = elm_widget_focus_next_get(obj, ELM_FOCUS_NEXT, &target);
-   if (ret && target)
-     {
-        type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
-
-        if (!_access_action_callback_call(ho, type, NULL))
-          {
-             /* this value is used in _elm_access_object_highlight();
-                to inform the target object of how to get highlight */
-             action_by = type;
-
-             _elm_access_highlight_set(target, EINA_FALSE);
-          }
-     }
-
-   _elm_access_auto_highlight_set(EINA_FALSE);
-
-   if (!ret) _elm_access_all_read_stop();
-}
-
-Eina_Bool
-_elm_access_widget_highlight(Evas_Object *obj, Elm_Focus_Direction dir)
-{
-   Elm_Access_Info *ac;
-   Elm_Highlight_Direction hdir;
-
-   ac = evas_object_data_get(obj, "_elm_access");
-   if (!ac) return EINA_FALSE;
-   if (!ac->widget_highlight) return EINA_FALSE;
-
-   if (dir == ELM_FOCUS_PREVIOUS)
-     hdir = ELM_HIGHLIGHT_DIR_PREVIOUS;
-   else if (dir == ELM_FOCUS_NEXT)
-     hdir = ELM_HIGHLIGHT_DIR_NEXT;
-   else
-     return EINA_FALSE;
-
-   return ac->widget_highlight(obj, hdir);
-}
 //-------------------------------------------------------------------------//
 EAPI void
-_elm_access_highlight_set(Evas_Object* obj, Eina_Bool delay)
+_elm_access_highlight_set(Evas_Object* obj)
 {
-   Evas_Object *parent;
    Elm_Access_Info *ac;
+   Evas_Object *ho;
 
-   /* evas_event_feed_mouse_move(); could cause unexpected result. so check
-      whether the access mode is enabled or not. */
-   if (!_elm_config->access_mode) return;
    if (!obj) return;
 
-   /* check tree focus allow (tree unfocusable) */
-   parent = obj;
-   while (parent)
-     {
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->tree_unfocusable) return;
-        parent = elm_widget_parent_get(parent);
-     }
+   ho = _access_highlight_object_get(obj);
+   if (ho == obj) return;
 
    ac = evas_object_data_get(obj, "_elm_access");
    if (!ac) return;
 
-   elm_widget_highlight_steal(obj);
-   if (highlight_read_timer)
-     {
-        ecore_timer_del(highlight_read_timer);
-        highlight_read_timer = NULL;
-     }
-   /* use ecore_timer_add(); here, an object could have a highlight even though
-      its text is not yet translated in case of the naviframe title */
-   if (delay)
-     highlight_read_timer = ecore_timer_add(0.1, _highlight_read_timeout_cb, obj);
-   else
-     _access_highlight_read(ac, obj);
+   _access_highlight_read(ac, obj);
 }
 
 EAPI void
@@ -1616,12 +574,12 @@ _elm_access_clear(Elm_Access_Info *ac)
    Elm_Access_Item *ai;
 
    if (!ac) return;
-
+   ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
    EINA_LIST_FREE(ac->items, ai)
      {
         if (!ai->func)
           {
-             if (ai->data) eina_stringshare_del(ai->data);
+             eina_stringshare_del(ai->data);
           }
         free(ai);
      }
@@ -1668,118 +626,78 @@ _elm_access_activate_callback_set(Elm_Access_Info           *ac,
 EAPI void
 _elm_access_highlight_object_activate(Evas_Object *obj, Elm_Activate act)
 {
-   Evas_Object *ho;
-   Evas_Object* parent_obj;
-
-   ho = _access_highlight_object_get(obj);
-   if (!ho) return;
+   Evas_Object *highlight;
 
-   switch (act)
-     {
-      case ELM_ACTIVATE_DEFAULT:
-        if (!elm_object_focus_get(ho))
-        {
-          if (!elm_widget_can_focus_get(ho))
-            {
-               parent_obj = elm_widget_parent_get(ho);
-               elm_widget_focus_steal(parent_obj);
-            }
-          else
-            {
-               elm_object_focus_set(ho, EINA_TRUE);
-            }
-        }
-
-        // When the access is activated, it reads the infomation again.
-        _elm_access_highlight_set(ho, EINA_TRUE);
-
-        elm_widget_activate(ho, act);
-        evas_object_smart_callback_call(ho, SIG_ACTIVATED, NULL);
-        _access_parent_callback_call(obj, SIG_ACTIVATED, NULL);
-        break;
+   highlight = _access_highlight_object_get(obj);
+   if (!highlight) return;
 
-      case ELM_ACTIVATE_UP:
-      case ELM_ACTIVATE_DOWN:
-      case ELM_ACTIVATE_BACK:
-        elm_widget_activate(ho, act);
-        break;
+   _elm_access_auto_highlight_set(EINA_FALSE);
 
-      default:
-        break;
-     }
+   if (!elm_object_focus_get(highlight))
+     elm_object_focus_set(highlight, EINA_TRUE);
 
+   elm_widget_activate(highlight, act);
    return;
 }
 
 EAPI void
-_elm_access_highlight_cycle(Evas_Object *obj, Elm_Access_Action_Type type)
+_elm_access_highlight_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
 {
-   Evas_Object *ho, *parent, *target = NULL;
-   Elm_Highlight_Direction dir;
-   Eina_Bool ret;
-   Elm_Access_Info *ac;
+   int type;
+   Evas_Object *ho, *parent;
 
    ho = _access_highlight_object_get(obj);
+   if (!ho) return;
 
    parent = ho;
 
-   ac = _elm_access_object_get(ho);
-
-   dir = (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT) ?
-      ELM_HIGHLIGHT_DIR_NEXT : ELM_HIGHLIGHT_DIR_PREVIOUS;
-
    /* find highlight root */
-   while (parent)
-     {
-        ELM_WIDGET_DATA_GET(parent, sd);
-        if (sd->highlight_root)
-          {
-             /* change highlight root */
-             obj = parent;
-             break;
-          }
-        if ((!focus_chain_end ||
-             (sd->highlight_previous && dir == ELM_HIGHLIGHT_DIR_PREVIOUS) ||
-             (sd->highlight_next && dir == ELM_HIGHLIGHT_DIR_NEXT)) &&
-            sd->end_dir == dir)
+   do
+     {
+        ELM_WIDGET_DATA_GET_OR_RETURN(parent, wd);
+        if (wd->highlight_root)
           {
+             /* change highlight root */
              obj = parent;
              break;
           }
         parent = elm_widget_parent_get(parent);
      }
+   while (parent);
 
-   if (ac && ac->end_dir == dir && !focus_chain_end && !ac->action_relay)
-     {
-        target = ho;
-        ret = EINA_FALSE;
-     }
-   else
-     {
-        ret = _access_highlight_next_get(obj, type, &target);
-     }
+   _elm_access_auto_highlight_set(EINA_TRUE);
 
-   if (target)
-     {
-        if (ac && ac->action_relay) ret = EINA_TRUE;
+   if (dir == ELM_FOCUS_NEXT)
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+   else
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
 
-        if (ret)
-          focus_chain_end = !ret;
-        else
-          focus_chain_end = !focus_chain_end;
+   action_by = type;
 
-        if (!focus_chain_end)
+   if (!_access_action_callback_call(ho, type, NULL))
+     {
+        Elm_Access_Info *info = _elm_access_info_get(ho);
+        Evas_Object *comming = NULL;
+        if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
           {
-             _elm_access_highlight_set(target, EINA_TRUE);
-             elm_widget_focus_region_show(target);
+             if ((info) && (info->next)) comming = info->next;
           }
         else
           {
-             /* play highlight sound */
-             _access_init();
-             if (mapi && mapi->sound_play) mapi->sound_play(ELM_ACCESS_SOUND_END);
+             if ((info) && (info->prev)) comming = info->prev;
+          }
+        if (comming)
+          {
+             _elm_access_highlight_set(comming);
+             elm_widget_focus_region_show(comming);
           }
+        else
+          elm_widget_focus_cycle(obj, dir);
      }
+
+   action_by = ELM_ACCESS_ACTION_FIRST;
+
+   _elm_access_auto_highlight_set(EINA_FALSE);
 }
 
 EAPI char *
@@ -1806,13 +724,6 @@ _elm_access_read(Elm_Access_Info *ac, int type, const Evas_Object *obj)
 {
    char *txt = _elm_access_text_get(ac, type, obj);
 
-   if (!txt) return;
-   if (strlen(txt) == 0)/* Tizen only: TTS engine does not work properly */
-     {
-         free(txt);
-         return;
-     }
-
    _access_init();
    if (mapi)
      {
@@ -1824,81 +735,52 @@ _elm_access_read(Elm_Access_Info *ac, int type, const Evas_Object *obj)
           }
         else if (type == ELM_ACCESS_CANCEL)
           {
-             reading_cancel = EINA_TRUE;
              if (mapi->out_cancel) mapi->out_cancel();
-             reading_cancel = EINA_FALSE;
           }
         else
           {
-             if (txt && mapi->out_read) mapi->out_read(txt);
+             if (txt)
+               {
+                  if (mapi->out_read) mapi->out_read(txt);
+                  if (mapi->out_read) mapi->out_read(".\n");
+               }
           }
      }
-   if (txt) free(txt);
-}
-
-static void
-_access_read_obj_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   if (mapi && mapi->out_done_callback_set)
-     mapi->out_done_callback_set(NULL, obj);
+   free(txt);
 }
 
 EAPI void
-_elm_access_say(Evas_Object *obj, const char *txt, Eina_Bool force)
+_elm_access_say(const char *txt)
 {
    if (!_elm_config->access_mode) return;
-   if (!highlight_read_enable && !force) return;
-
-   if (!txt) return; /* Tizen only: TTS engine does not work properly */
-   if (strlen(txt) == 0) return;
-
-   if (!force)
-     {
-        if (highlight_read_timer && !force)
-          {
-             ecore_timer_del(highlight_read_timer);
-             highlight_read_timer = NULL;
-          }
-
-        if (force_saying)
-          {
-             waiting_text = strdup(txt);
-             return;
-          }
-     }
 
    _access_init();
    if (mapi)
      {
-        reading_cancel = EINA_TRUE;
+        if (mapi->out_done_callback_set)
+           mapi->out_done_callback_set(_access_read_done, NULL);
         if (mapi->out_cancel) mapi->out_cancel();
-        reading_cancel = EINA_FALSE;
         if (txt)
           {
-             evas_object_smart_callback_call(obj, SIG_READ_START, NULL);
-             _access_parent_callback_call(obj, SIG_READ_START, NULL);
              if (mapi->out_read) mapi->out_read(txt);
-             //if (mapi->out_read) mapi->out_read(".\n"); /* TIZEN only: Tizen TTS engine performance is not good */
-             evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
-                                            _access_read_obj_del_cb, NULL);
-             if (mapi->out_done_callback_set)
-               mapi->out_done_callback_set(_access_read_done, obj);
-          }
-        else
-          {
-          if (mapi->out_done_callback_set)
-            mapi->out_done_callback_set(NULL, NULL);
+             if (mapi->out_read) mapi->out_read(".\n");
           }
         if (mapi->out_read_done) mapi->out_read_done();
      }
 }
 
 EAPI Elm_Access_Info *
-_elm_access_object_get(const Evas_Object *obj)
+_elm_access_info_get(const Evas_Object *obj)
 {
    return evas_object_data_get(obj, "_elm_access");
 }
 
+EAPI Elm_Access_Info *
+_elm_access_object_get(const Evas_Object *obj)
+{
+   return _elm_access_info_get(obj);
+}
+
 static Evas_Object *
 _elm_access_widget_target_get(Evas_Object *obj)
 {
@@ -1921,31 +803,26 @@ _elm_access_widget_target_get(Evas_Object *obj)
 }
 
 EAPI void
-_elm_access_object_hilight(Evas_Object *obj)
+_elm_access_object_highlight(Evas_Object *obj)
 {
-   Evas_Object *o, *widget, *ptarget = NULL;
-   Evas_Coord x, y, w, h, vx, vy;
-   Elm_Access_Action_Info *a;
+   Evas_Object *o, *widget;
+   Evas_Coord x, y, w, h;
    Eina_Bool in_theme = EINA_FALSE;
-   Elm_Access_Info *ac, *nac;
 
    o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
    if (!o)
      {
-        /* edje_object_add(); calls evas_event_feed_mouse_move();
-           and it calls _access_hover_mouse_in_cb(); again. */
-        _elm_access_mouse_event_enabled_set(EINA_FALSE);
         o = edje_object_add(evas_object_evas_get(obj));
         evas_object_name_set(o, "_elm_access_disp");
         evas_object_layer_set(o, ELM_OBJECT_LAYER_TOOLTIP);
      }
-
-   ptarget = evas_object_data_get(o, "_elm_access_target");
-   if (ptarget != obj)
+   else
      {
+        Evas_Object *ptarget = evas_object_data_get(o, "_elm_access_target");
         if (ptarget)
           {
              evas_object_data_del(o, "_elm_access_target");
+             elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
 
              evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_DEL,
                                                  _access_obj_hilight_del_cb, NULL);
@@ -1955,7 +832,6 @@ _elm_access_object_hilight(Evas_Object *obj)
                                                  _access_obj_hilight_move_cb, NULL);
              evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
                                                  _access_obj_hilight_resize_cb, NULL);
-             _access_action_callback_call(ptarget, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL);
 
              widget = _elm_access_widget_target_get(ptarget);
              if (widget)
@@ -1965,36 +841,26 @@ _elm_access_object_hilight(Evas_Object *obj)
                        elm_widget_signal_emit(widget, "elm,action,access_highlight,hide", "elm");
                     }
                }
-
           }
-        evas_object_data_set(o, "_elm_access_target", obj);
-        elm_widget_highlight_steal(obj);
-
-        elm_widget_theme_object_set(obj, o, "access", "base", "default");
-
-        evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
-                                       _access_obj_hilight_del_cb, NULL);
-        evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
-                                       _access_obj_hilight_hide_cb, NULL);
-        evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
-                                       _access_obj_hilight_move_cb, NULL);
-        evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
-                                       _access_obj_hilight_resize_cb, NULL);
      }
+   evas_object_data_set(o, "_elm_access_target", obj);
+   elm_widget_parent_highlight_set(obj, EINA_TRUE);
+
+   elm_widget_theme_object_set(obj, o, "access", "base", "default");
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+                                  _access_obj_hilight_del_cb, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
+                                  _access_obj_hilight_hide_cb, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
+                                  _access_obj_hilight_move_cb, NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
+                                  _access_obj_hilight_resize_cb, NULL);
    evas_object_raise(o);
    evas_object_geometry_get(obj, &x, &y, &w, &h);
-   _access_obj_scroll_virtual_value_get(obj, &vx, &vy);
-   x += vx;
-   y += vy;
    evas_object_move(o, x, y);
    evas_object_resize(o, w, h);
 
-   _access_scrollable_parent_clip(obj);
-
-   /* use callback, should an access object do below every time when
-    * a window gets a client message ECORE_X_ATOM_E_ILLMUE_ACTION_READ? */
-   a = calloc(1, sizeof(Elm_Access_Action_Info));
-   a->action_by = action_by;
    widget = _elm_access_widget_target_get(obj);
    if (widget)
      {
@@ -2004,37 +870,17 @@ _elm_access_object_hilight(Evas_Object *obj)
              elm_widget_signal_emit(widget, "elm,action,access_highlight,show", "elm");
           }
      }
+   /* use callback, should an access object do below every time when
+    * a window gets a client message ECORE_X_ATOM_E_ILLMUE_ACTION_READ? */
    if (!in_theme &&
-       !_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, a))
+       !_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL))
      evas_object_show(o);
    else
-     {
-        if (clip_job)
-          ecore_job_del(clip_job);
-        clip_job = NULL;
-        if (clipper)
-          evas_object_hide(clipper);
-        evas_object_hide(o);
-     }
-   free(a);
-
-   if (ptarget != obj)
-     {
-        evas_object_smart_callback_call(ptarget, SIG_UNHIGHLIGHTED, NULL);
-        evas_object_smart_callback_call(obj, SIG_HIGHLIGHTED, NULL);
-     }
-
-   ac = evas_object_data_get(ptarget, "_elm_access");
-   nac = evas_object_data_get(obj, "_elm_access");
-   if (ac && nac && ac->parent != nac->parent)
-     {
-        _access_parent_callback_call(ptarget, SIG_UNHIGHLIGHTED, NULL);
-        _access_parent_callback_call(obj, SIG_HIGHLIGHTED, NULL);
-     }
+     evas_object_hide(o);
 }
 
 EAPI void
-_elm_access_object_unhilight(Evas_Object *obj)
+_elm_access_object_unhighlight(Evas_Object *obj)
 {
    Evas_Object *o, *ptarget;
 
@@ -2051,20 +897,14 @@ _elm_access_object_unhilight(Evas_Object *obj)
                                             _access_obj_hilight_move_cb, NULL);
         evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
                                             _access_obj_hilight_resize_cb, NULL);
-        if (clip_job)
-          ecore_job_del(clip_job);
-        clip_job = NULL;
-        if (clipper)
-          evas_object_hide(clipper);
         evas_object_del(o);
         elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
-        _access_action_callback_call(ptarget, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL);
      }
 }
 
 static void
-_content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
-                void *event_info __UNUSED__)
+_content_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
+                void *event_info EINA_UNUSED)
 {
    Evas_Object *accessobj;
    Evas_Coord w, h;
@@ -2077,8 +917,8 @@ _content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
 }
 
 static void
-_content_move(void *data, Evas *e __UNUSED__, Evas_Object *obj,
-              void *event_info __UNUSED__)
+_content_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
+              void *event_info EINA_UNUSED)
 {
    Evas_Object *accessobj;
    Evas_Coord x, y;
@@ -2122,7 +962,6 @@ _access_object_register(Evas_Object *obj, Evas_Object *parent)
    /* set owner part object */
    ac = evas_object_data_get(ao, "_elm_access");
    ac->part_object = obj;
-   ac->parent = parent;
 
    return ao;
 }
@@ -2173,7 +1012,7 @@ _elm_access_edje_object_part_object_register(Evas_Object* obj,
 
 //FIXME: unused obj should be removed from here and each widget.
 EAPI void
-_elm_access_edje_object_part_object_unregister(Evas_Object* obj __UNUSED__,
+_elm_access_edje_object_part_object_unregister(Evas_Object* obj EINA_UNUSED,
                                                const Evas_Object *eobj,
                                                const char* part)
 {
@@ -2186,7 +1025,7 @@ _elm_access_edje_object_part_object_unregister(Evas_Object* obj __UNUSED__,
 }
 
 EAPI void
-_elm_access_object_hilight_disable(Evas *e)
+_elm_access_object_highlight_disable(Evas *e)
 {
    Evas_Object *o, *ptarget;
 
@@ -2203,43 +1042,29 @@ _elm_access_object_hilight_disable(Evas *e)
                                             _access_obj_hilight_move_cb, NULL);
         evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
                                             _access_obj_hilight_resize_cb, NULL);
-        elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
-        if (mapi && mapi->out_done_callback_set)
-           mapi->out_done_callback_set(NULL, ptarget);
-        _access_action_callback_call(ptarget, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL);
      }
-   if (clip_job)
-     ecore_job_del(clip_job);
-   clip_job = NULL;
-   if (clipper)
-     evas_object_hide(clipper);
    evas_object_del(o);
+   elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
 }
 
 static void
-_access_obj_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_access_obj_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
-   Elm_Access_Info *ac;
+
    Ecore_Job *ao_del_job = NULL;
 
    evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _access_obj_del_cb);
 
-   ac = evas_object_data_get(obj, "_elm_access");
-
-   if (ac && ac->hoverobj) /* hover object */
+   if (data) /* hover object */
      {
-        evas_object_event_callback_del_full(ac->hoverobj, EVAS_CALLBACK_RESIZE,
+        evas_object_event_callback_del_full(data, EVAS_CALLBACK_RESIZE,
                                             _content_resize, obj);
-        evas_object_event_callback_del_full(ac->hoverobj, EVAS_CALLBACK_MOVE,
+        evas_object_event_callback_del_full(data, EVAS_CALLBACK_MOVE,
                                             _content_move, obj);
 
-        _elm_access_object_unregister(obj, ac->hoverobj);
+        _elm_access_object_unregister(obj, data);
      }
 
-   if (clip_job)
-     ecore_job_del(clip_job);
-   clip_job = NULL;
-
    ao_del_job = evas_object_data_get(obj, "_access_obj_del_job");
 
    if (ao_del_job)
@@ -2257,15 +1082,11 @@ _access_obj_del_job(void *data)
    evas_object_data_del(data, "_access_obj_del_job");
 
    evas_object_event_callback_del(data, EVAS_CALLBACK_DEL, _access_obj_del_cb);
-
-   if (mapi && mapi->out_done_callback_set)
-     mapi->out_done_callback_set(NULL, data);
-
    evas_object_del(data);
 }
 
 static void
-_access_hover_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_access_hover_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    Ecore_Job *ao_del_job = NULL;
 
@@ -2291,98 +1112,6 @@ _access_hover_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *eve
    evas_object_data_set(data, "_access_obj_del_job", ao_del_job);
 }
 
-static void
-_access_hoverobj_hide_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   Evas_Object *ao;
-
-   ao = evas_object_data_get(obj, "_part_access_obj");
-   if (ao) evas_object_hide(ao);
-}
-
-static void
-_access_hoverobj_show_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   Evas_Object *ao;
-
-   ao = evas_object_data_get(obj, "_part_access_obj");
-   if (ao) evas_object_show(ao);
-}
-
-void
-_elm_access_object_hover_unregister(Evas_Object *ao)
-{
-   Elm_Access_Info * ac;
-   Evas_Object *hoverobj;
-
-   ac = evas_object_data_get(ao, "_elm_access");
-   if (!ac) return;
-
-   hoverobj = ac->hoverobj;
-
-   evas_object_data_del(hoverobj, "_part_access_obj");
-
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_RESIZE,
-                                       _content_resize, ao);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOVE,
-                                       _content_move, ao);
-
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOUSE_IN,
-                                       _access_hover_mouse_in_cb, ao);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_DEL,
-                                       _access_hover_del_cb, ao);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_HIDE,
-                                       _access_hoverobj_hide_cb, ao);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_SHOW,
-                                       _access_hoverobj_show_cb, ao);
-
-   ac->hoverobj = NULL;
-}
-
-void
-_elm_access_object_hover_register(Evas_Object *ao, Evas_Object *hoverobj)
-{
-   Elm_Access_Info * ac;
-
-   evas_object_data_set(hoverobj, "_part_access_obj", ao);
-
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_RESIZE,
-                                  _content_resize, ao);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOVE,
-                                  _content_move, ao);
-
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOUSE_IN,
-                                  _access_hover_mouse_in_cb, ao);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_DEL,
-                                  _access_hover_del_cb, ao);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_HIDE,
-                                  _access_hoverobj_hide_cb, ao);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_SHOW,
-                                  _access_hoverobj_show_cb, ao);
-
-   ac = evas_object_data_get(ao, "_elm_access");
-   if (!ac) return;
-
-   ac->hoverobj = hoverobj;
-}
-
-void
-_elm_access_sound_play(const Elm_Access_Sound_Type type)
-{
-   switch (type)
-     {
-      case ELM_ACCESS_SOUND_HIGHLIGHT:
-      case ELM_ACCESS_SOUND_SCROLL:
-      case ELM_ACCESS_SOUND_END:
-        _access_init();
-        if (mapi && mapi->sound_play) mapi->sound_play(type);
-        break;
-
-      default:
-        break;
-     }
-}
-
 EAPI void
 _elm_access_object_register(Evas_Object *obj, Evas_Object *hoverobj)
 {
@@ -2390,20 +1119,16 @@ _elm_access_object_register(Evas_Object *obj, Evas_Object *hoverobj)
 
    evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOUSE_IN,
                                   _access_hover_mouse_in_cb, obj);
+   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOUSE_OUT,
+                                  _access_hover_mouse_out_cb, obj);
    evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_DEL,
                                   _access_hover_del_cb, obj);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_HIDE,
-                                  _access_hoverobj_hide_cb, obj);
-   evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_SHOW,
-                                  _access_hoverobj_show_cb, obj);
 
    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
-                                  _access_obj_del_cb, NULL);
-
+                                  _access_obj_del_cb, hoverobj);
 
    ac = calloc(1, sizeof(Elm_Access_Info));
    evas_object_data_set(obj, "_elm_access", ac);
-   ac->end_dir = ELM_HIGHLIGHT_DIR_FIRST;
 
    ac->hoverobj = hoverobj;
 }
@@ -2416,12 +1141,10 @@ _elm_access_object_unregister(Evas_Object *obj, Evas_Object *hoverobj)
 
    evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOUSE_IN,
                                        _access_hover_mouse_in_cb, obj);
+   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOUSE_OUT,
+                                       _access_hover_mouse_out_cb, obj);
    evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_DEL,
                                        _access_hover_del_cb, obj);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_HIDE,
-                                       _access_hoverobj_hide_cb, obj);
-   evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_SHOW,
-                                       _access_hoverobj_show_cb, obj);
 
    /* _access_obj_del_cb and _access_hover_del_cb calls this function,
       both do not need _part_access_obj data, so delete the data here. */
@@ -2433,7 +1156,7 @@ _elm_access_object_unregister(Evas_Object *obj, Evas_Object *hoverobj)
    if (ac)
      {
         /* widget could delete VIEW(it) only and register item again,
-           in this case _elm_access_widget_ntem_register could try to delet
+           in this case _elm_access_widget_item_register could try to delete
            access object again in _elm_access_widget_item_unregister */
         if (ac->widget_item) ac->widget_item->access_obj = NULL;
 
@@ -2444,11 +1167,11 @@ _elm_access_object_unregister(Evas_Object *obj, Evas_Object *hoverobj)
    Action_Info *a;
    a = evas_object_data_get(obj, "_elm_access_action_info");
    evas_object_data_del(obj,  "_elm_access_action_info");
-   if (a) free(a);
+   free(a);
 }
 
 EAPI void
-_elm_access_widget_item_register(Elm_Widget_Item *item)
+_elm_access_widget_item_register(Elm_Widget_Item_Data *item)
 {
    Evas_Object *ao, *ho;
    Evas_Coord x, y, w, h;
@@ -2483,11 +1206,10 @@ _elm_access_widget_item_register(Elm_Widget_Item *item)
    /* set owner widget item */
    ac = evas_object_data_get(ao, "_elm_access");
    ac->widget_item = item;
-   ac->parent = item->widget;
 }
 
 EAPI void
-_elm_access_widget_item_unregister(Elm_Widget_Item *item)
+_elm_access_widget_item_unregister(Elm_Widget_Item_Data *item)
 {
    Evas_Object *ao;
 
@@ -2526,23 +1248,19 @@ _elm_access_2nd_click_timeout(Evas_Object *obj)
 static Evas_Object *
 _elm_access_add(Evas_Object *parent)
 {
-   Evas_Object *obj;
-
    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
-
-   obj = elm_widget_add(_elm_access_smart_class_new(), parent);
-   if (!obj) return NULL;
-
-   if (!elm_widget_sub_object_add(parent, obj))
-     ERR("could not add %p as sub object of %p", obj, parent);
-
-   //Tizen Only: This should be removed when eo is applied.
-   ELM_WIDGET_DATA_GET(obj, sd);
-   sd->on_create = EINA_FALSE;
-
+   Evas_Object *obj = eo_add(MY_CLASS, parent);
    return obj;
 }
 
+EOLIAN static void
+_elm_access_eo_base_constructor(Eo *obj, void *_pd EINA_UNUSED)
+{
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+   eo_do(obj,
+         evas_obj_type_set(MY_CLASS_NAME_LEGACY));
+}
+
 EAPI Evas_Object *
 elm_access_object_register(Evas_Object *obj, Evas_Object *parent)
 {
@@ -2564,20 +1282,20 @@ elm_access_object_get(const Evas_Object *obj)
 EAPI void
 elm_access_info_set(Evas_Object *obj, int type, const char *text)
 {
-   _elm_access_text_set(_elm_access_object_get(obj), type, text);
+   _elm_access_text_set(_elm_access_info_get(obj), type, text);
 }
 
 EAPI char *
 elm_access_info_get(const Evas_Object *obj, int type)
 {
-   return _elm_access_text_get(_elm_access_object_get(obj), type, obj);
+   return _elm_access_text_get(_elm_access_info_get(obj), type, obj);
 }
 
 EAPI void
 elm_access_info_cb_set(Evas_Object *obj, int type,
                           Elm_Access_Info_Cb func, const void *data)
 {
-   _elm_access_callback_set(_elm_access_object_get(obj), type, func, data);
+   _elm_access_callback_set(_elm_access_info_get(obj), type, func, data);
 }
 
 EAPI void
@@ -2586,7 +1304,7 @@ elm_access_activate_cb_set(Evas_Object *obj,
 {
    Elm_Access_Info *ac;
 
-   ac = _elm_access_object_get(obj);
+   ac = _elm_access_info_get(obj);
    if (!ac) return;
 
    ac->activate = func;
@@ -2598,55 +1316,21 @@ elm_access_say(const char *text)
 {
    if (!text) return;
 
-   _elm_access_say(NULL, text, EINA_FALSE);
-}
-
-EAPI void
-elm_access_force_say(const char *text)
-{
-   if (!text) return;
-   if (force_saying) return;
-
-   force_saying = EINA_TRUE;
-   _elm_access_say(NULL, text, EINA_TRUE);
+   _elm_access_say(text);
 }
 
 EAPI void
 elm_access_highlight_set(Evas_Object* obj)
 {
-   _elm_access_highlight_set(obj, EINA_FALSE);
-}
-
-EAPI void
-elm_access_item_highlight_set(Elm_Object_Item *item)
-{
-   ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)item);
-   Evas_Object *ao = ((Elm_Widget_Item *)item)->access_obj;
-   if (ao) _elm_access_highlight_set(ao, EINA_FALSE);
+   _elm_access_highlight_set(obj);
 }
 
 EAPI Eina_Bool
-elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *action_info)
+elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, Elm_Access_Action_Info *action_info)
 {
    Evas *evas;
    Evas_Object *ho;
-   Elm_Access_Action_Info *a;
-   Eina_Bool ret = EINA_FALSE;
-   Evas_Object *win;
-
-   win = elm_widget_top_get(obj);
-   if (win)
-     {
-        Elm_Win_Type win_type;
-        win_type = elm_win_type_get(win);
-        if (win_type == ELM_WIN_SOCKET_IMAGE || win_type == ELM_WIN_TIZEN_WIDGET)
-          highlight_read_enable = EINA_TRUE;
-     }
-
-   if (!highlight_read_timer)
-     action_by = ELM_ACCESS_ACTION_FIRST;
-
-   a = (Elm_Access_Action_Info *) action_info;
+   Elm_Access_Action_Info *a = action_info;
 
    switch (type)
      {
@@ -2655,11 +1339,10 @@ elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *act
         evas = evas_object_evas_get(obj);
         if (!evas) return EINA_FALSE;
 
-        evas_event_feed_mouse_in(evas, ecore_loop_time_get() * 1000, NULL);
+        evas_event_feed_mouse_in(evas, 0, NULL);
 
         _elm_access_mouse_event_enabled_set(EINA_TRUE);
-        evas_event_feed_mouse_move(evas, INT_MIN, INT_MIN, ecore_loop_time_get() * 1000, NULL);
-        evas_event_feed_mouse_move(evas, a->x, a->y, ecore_loop_time_get() * 1000, NULL);
+        evas_event_feed_mouse_move(evas, a->x, a->y, 0, NULL);
         _elm_access_mouse_event_enabled_set(EINA_FALSE);
 
         ho = _access_highlight_object_get(obj);
@@ -2667,99 +1350,45 @@ elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *act
           _access_action_callback_call(ho, ELM_ACCESS_ACTION_READ, a);
         break;
 
-      case ELM_ACCESS_ACTION_OVER:
-        evas = evas_object_evas_get(obj);
-        if (!evas) return EINA_FALSE;
-
-        evas_event_feed_mouse_in(evas, ecore_loop_time_get() * 1000, NULL);
-
-        _elm_access_mouse_event_enabled_set(EINA_TRUE);
-        evas_event_feed_mouse_move(evas, a->x, a->y, ecore_loop_time_get() * 1000, NULL);
-        _elm_access_mouse_event_enabled_set(EINA_FALSE);
-
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          _access_action_callback_call(ho, ELM_ACCESS_ACTION_OVER, a);
-        break;
-
-
       case ELM_ACCESS_ACTION_UNHIGHLIGHT:
         evas = evas_object_evas_get(obj);
         if (!evas) return EINA_FALSE;
-        _elm_access_object_hilight_disable(evas);
+        _elm_access_object_highlight_disable(evas);
         break;
 
       case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+        if (a->highlight_cycle)
+          _elm_access_highlight_cycle(obj, ELM_FOCUS_NEXT);
+        else
+          return _access_highlight_next_get(obj, ELM_FOCUS_NEXT);
+        break;
+
       case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
-        if (a && a->highlight_cycle)
-          _elm_access_highlight_cycle(obj, type);
+        if (a->highlight_cycle)
+          _elm_access_highlight_cycle(obj, ELM_FOCUS_PREVIOUS);
         else
-          return _access_highlight_next(obj, type, EINA_TRUE);
+          return _access_highlight_next_get(obj, ELM_FOCUS_PREVIOUS);
         break;
 
       case ELM_ACCESS_ACTION_ACTIVATE:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          ret = _access_action_callback_call(ho, ELM_ACCESS_ACTION_ACTIVATE, a);
-
-        if (!ret)
-          _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DEFAULT);
+        _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DEFAULT);
         break;
 
       case ELM_ACCESS_ACTION_UP:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          ret = _access_action_callback_call(ho, ELM_ACCESS_ACTION_UP, a);
-
-        if (!ret)
-          _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_UP);
+        _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_UP);
         break;
 
       case ELM_ACCESS_ACTION_DOWN:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          ret = _access_action_callback_call(ho, ELM_ACCESS_ACTION_DOWN, a);
-
-        if (!ret)
-          _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DOWN);
+        _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DOWN);
         break;
 
       case ELM_ACCESS_ACTION_SCROLL:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          ret = _access_action_callback_call(ho, ELM_ACCESS_ACTION_SCROLL, a);
-
-        if (!ret)
-          _elm_access_highlight_object_scroll(obj, a->mouse_type, a->x, a->y);
-        break;
-
-      case ELM_ACCESS_ACTION_ZOOM:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          _access_action_callback_call(ho, ELM_ACCESS_ACTION_ZOOM, a);
-        break;
-
-      case ELM_ACCESS_ACTION_MOUSE:
-        ho = _access_highlight_object_get(obj);
-        if (ho)
-          ret = _access_action_callback_call(ho, ELM_ACCESS_ACTION_MOUSE, a);
-
-        if (!ret)
-          _elm_access_highlight_object_mouse(obj, a->mouse_type, a->x, a->y);
+        //TODO: SCROLL HIGHLIGHT OBJECT
         break;
 
       case ELM_ACCESS_ACTION_BACK:
         break;
 
-      case ELM_ACCESS_ACTION_ENABLE:
-        _elm_access_highlight_read_enable_set(obj, EINA_TRUE, EINA_TRUE);
-        break;
-
-      case ELM_ACCESS_ACTION_DISABLE:
-        _elm_access_highlight_read_enable_set(obj, EINA_FALSE, EINA_TRUE);
-        break;
-
-
       default:
         break;
      }
@@ -2783,12 +1412,11 @@ elm_access_action_cb_set(Evas_Object *obj, const Elm_Access_Action_Type type, co
    a->fn[type].cb = cb;
    a->fn[type].user_data = (void *)data;
 }
-
 EAPI void
 elm_access_external_info_set(Evas_Object *obj, const char *text)
 {
    _elm_access_text_set
-     (_elm_access_object_get(obj), ELM_ACCESS_CONTEXT_INFO, text);
+     (_elm_access_info_get(obj), ELM_ACCESS_CONTEXT_INFO, text);
 }
 
 EAPI char *
@@ -2796,52 +1424,120 @@ elm_access_external_info_get(const Evas_Object *obj)
 {
    Elm_Access_Info *ac;
 
-   ac = _elm_access_object_get(obj);
+   ac = _elm_access_info_get(obj);
    return _elm_access_text_get(ac, ELM_ACCESS_CONTEXT_INFO, obj);
 }
 
 EAPI void
 elm_access_highlight_next_set(Evas_Object *obj, Elm_Highlight_Direction dir, Evas_Object *next)
 {
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   EINA_SAFETY_ON_NULL_RETURN(next);
+   EINA_SAFETY_ON_FALSE_RETURN(obj);
+   EINA_SAFETY_ON_FALSE_RETURN(next);
 
-   Elm_Access_Info *info = _elm_access_object_get(obj);
+   Elm_Access_Info *info = _elm_access_info_get(obj);
+   Elm_Access_Info *info_next = _elm_access_info_get(next);
+
+   if (!info || !info_next)
+     {
+        ERR("There is no access information");
+        return;
+     }
 
    if (dir == ELM_HIGHLIGHT_DIR_NEXT)
      {
-        if (info && info->part_object)
-          info->next = next;
-        else
-          {
-             ELM_WIDGET_DATA_GET(obj, sd);
-             sd->highlight_next = next;
-          }
+        info_next->prev = obj;
+        info->next = next;
      }
    else if (dir == ELM_HIGHLIGHT_DIR_PREVIOUS)
      {
-        if (info && info->part_object)
-          info->prev = next;
-        else
-          {
-             ELM_WIDGET_DATA_GET(obj, sd);
-             sd->highlight_previous = next;
-          }
+        info_next->next = obj;
+        info->prev = next;
      }
    else
       ERR("Not supported focus direction for access highlight [%d]", dir);
 }
 
-EAPI void
-elm_access_chain_end_set(Evas_Object *obj, Elm_Highlight_Direction dir)
+EOLIAN static void
+_elm_access_class_constructor(Eo_Class *klass)
+{
+   evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+EOLIAN static char*
+_elm_access_elm_interface_atspi_accessible_name_get(Eo *obj, void *pd EINA_UNUSED)
+{
+   return elm_access_info_get(obj, ELM_ACCESS_INFO);
+}
+
+EOLIAN static const char*
+_elm_access_elm_interface_atspi_accessible_description_get(Eo *obj, void *pd EINA_UNUSED)
+{
+   return elm_access_info_get(obj, ELM_ACCESS_CONTEXT_INFO);
+}
+
+EOLIAN static Eina_Bool
+_elm_access_elm_interface_atspi_component_highlight_grab(Eo *obj, void *pd EINA_UNUSED)
+{
+   if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL))
+     eo_do_super(obj, ELM_ACCESS_CLASS, elm_interface_atspi_component_highlight_grab());
+
+///TIZEN_ONLY(20170717) : expose highlight information on atspi
+   elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
+///
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_elm_access_elm_interface_atspi_component_highlight_clear(Eo *obj, void *pd EINA_UNUSED)
+{
+   if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL))
+     eo_do_super(obj, ELM_ACCESS_CLASS, elm_interface_atspi_component_highlight_clear());
+
+///TIZEN_ONLY(20170717) : expose highlight information on atspi
+   elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
+///
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_elm_access_elm_interface_atspi_action_action_do(Eo *obj, void *pd EINA_UNUSED, int id)
+{
+   if (id != 0)
+     return EINA_FALSE;
+
+   return _access_action_callback_call(obj, ELM_ACCESS_ACTION_ACTIVATE, NULL);
+}
+
+EOLIAN static const char *
+_elm_access_elm_interface_atspi_action_name_get(Eo *obj, void *pd EINA_UNUSED, int id)
 {
-   EINA_SAFETY_ON_NULL_RETURN(obj);
+   if ((id != 0) || !_access_action_callback_have(obj, ELM_ACCESS_ACTION_ACTIVATE))
+     return NULL;
+   return "activate";
+}
+
+EOLIAN static Eina_List*
+_elm_access_elm_interface_atspi_action_actions_get(Eo *obj, void *pd EINA_UNUSED)
+{
+   Eina_List *ret = NULL;
+
+   if (_access_action_callback_have(obj, ELM_ACCESS_ACTION_ACTIVATE))
+      ret = eina_list_append(ret, &("activate"));
 
-   ELM_WIDGET_DATA_GET(obj, sd);
-   Elm_Access_Info *info = _elm_access_object_get(obj);
+   return ret;
+}
 
-   if (info)
-     info->end_dir = dir;
-   else if (sd)
-     sd->end_dir = dir;
+#include "elm_access.eo.c"
+
+/////////////////////////////////////////////////////////////////
+// TIZEN_ONLY(20150112): Add dummy APIs to fix build failure.
+/////////////////////////////////////////////////////////////////
+EAPI void
+elm_access_force_say(const char *text)
+{
+   (void) text;
+   TIZEN_DUMMY_API_LOG;
 }
+/////////////////////////////////////////////////////////////////
+
+