2 # include "elementary_config.h"
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
7 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
9 #include <Elementary.h>
12 #define MY_CLASS ELM_ACCESS_CLASS
14 #define MY_CLASS_NAME "Elm_Access"
15 #define MY_CLASS_NAME_LEGACY "elm_access"
19 void *user_data; /* Holds user data to CB */
20 Elm_Access_Action_Cb cb;
23 typedef struct _Func_Data Func_Data;
28 Func_Data fn[ELM_ACCESS_ACTION_LAST + 1]; /* Callback for specific action */
31 typedef struct _Action_Info Action_Info;
33 static Eina_Bool mouse_event_enable = EINA_TRUE;
34 static Eina_Bool auto_highlight = EINA_FALSE;
35 static Elm_Access_Action_Type action_by = ELM_ACCESS_ACTION_FIRST;
37 static Evas_Object * _elm_access_add(Evas_Object *parent);
39 static void _access_object_unregister(Evas_Object *obj);
41 static const char SIG_ACTIVATED[] = "access,activated";
42 static const Evas_Smart_Cb_Description _smart_callbacks[] =
49 _elm_access_evas_object_smart_add(Eo *obj, void *_pd EINA_UNUSED)
51 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
52 elm_widget_sub_object_parent_add(obj);
56 _access_action_callback_call(Evas_Object *obj,
57 Elm_Access_Action_Type type,
58 Elm_Access_Action_Info *action_info)
60 Elm_Access_Action_Info *ai = NULL;
65 a = evas_object_data_get(obj, "_elm_access_action_info");
69 ai = calloc(1, sizeof(Elm_Access_Action_Info));
73 action_info->action_type = type;
75 if ((type == ELM_ACCESS_ACTION_HIGHLIGHT) &&
76 (action_by != ELM_ACCESS_ACTION_FIRST))
77 action_info->action_by = action_by;
79 if (a && (a->fn[type].cb))
80 ret = a->fn[type].cb(a->fn[type].user_data, obj, action_info);
87 EOLIAN static Eina_Bool
88 _elm_access_elm_widget_activate(Eo *obj, void *_pd EINA_UNUSED, Elm_Activate act)
90 int type = ELM_ACCESS_ACTION_FIRST;
93 a = evas_object_data_get(obj, "_elm_access_action_info");
97 case ELM_ACTIVATE_DEFAULT:
98 type = ELM_ACCESS_ACTION_ACTIVATE;
101 case ELM_ACTIVATE_UP:
102 type = ELM_ACCESS_ACTION_UP;
105 case ELM_ACTIVATE_DOWN:
106 type = ELM_ACCESS_ACTION_DOWN;
109 case ELM_ACTIVATE_RIGHT:
112 case ELM_ACTIVATE_LEFT:
115 case ELM_ACTIVATE_BACK:
116 type = ELM_ACCESS_ACTION_BACK;
123 if (type == ELM_ACCESS_ACTION_FIRST) return EINA_FALSE;
125 /* if an access object has a callback, it would have the intention to do
126 something. so, check here and return EINA_TRUE. */
127 if ((a) && (type > ELM_ACCESS_ACTION_FIRST) &&
128 (type < ELM_ACCESS_ACTION_LAST) &&
131 _access_action_callback_call(obj, type, NULL);
135 /* TODO: deprecate below? */
136 if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
138 Elm_Access_Info *ac = evas_object_data_get(obj, "_elm_access");
139 if (!ac) return EINA_FALSE;
142 ac->activate(ac->activate_data, ac->part_object,
143 ac->widget_item->eo_obj);
148 EOLIAN static Eina_Bool
149 _elm_access_elm_widget_on_focus(Eo *obj, void *_pd EINA_UNUSED, Elm_Object_Item *item EINA_UNUSED)
151 evas_object_focus_set(obj, elm_widget_focus_get(obj));
156 typedef struct _Mod_Api Mod_Api;
160 void (*out_read) (const char *txt);
161 void (*out_read_done) (void);
162 void (*out_cancel) (void);
163 void (*out_done_callback_set) (void (*func) (void *data), const void *data);
166 static int initted = 0;
167 static Mod_Api *mapi = NULL;
174 if (initted > 0) return;
175 if (!(m = _elm_module_find_as("access/api"))) return;
176 if (m->init_func(m) < 0) return;
179 m->api = malloc(sizeof(Mod_Api));
181 ((Mod_Api *)(m->api) )->out_read = // called to read out some text
182 _elm_module_symbol_get(m, "out_read");
183 ((Mod_Api *)(m->api) )->out_read_done = // called to set a done marker so when it is reached the done callback is called
184 _elm_module_symbol_get(m, "out_read_done");
185 ((Mod_Api *)(m->api) )->out_cancel = // called to read out some text
186 _elm_module_symbol_get(m, "out_cancel");
187 ((Mod_Api *)(m->api) )->out_done_callback_set = // called when last read done
188 _elm_module_symbol_get(m, "out_done_callback_set");
193 _access_shutdown(void)
196 if (initted == 0) return;
197 if (!(m = _elm_module_find_as("access/api"))) return;
203 /* _elm_module_unload(); could access m->api and try to free(); */
204 ELM_SAFE_FREE(m->api, free);
208 static Elm_Access_Item *
209 _access_add_set(Elm_Access_Info *ac, int type)
214 if (!ac) return NULL;
215 EINA_LIST_FOREACH(ac->items, l, ai)
217 if (ai->type == type)
221 eina_stringshare_del(ai->data);
228 ai = calloc(1, sizeof(Elm_Access_Item));
230 ac->items = eina_list_prepend(ac->items, ai);
235 _access_highlight_object_get(Evas_Object *obj)
239 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
242 ho = evas_object_data_get(o, "_elm_access_target");
248 _access_highlight_read(Elm_Access_Info *ac, Evas_Object *obj)
254 strbuf = eina_strbuf_new();
256 if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
258 if (ac->on_highlight) ac->on_highlight(ac->on_highlight_data);
259 _elm_access_object_highlight(obj);
261 for (type = ELM_ACCESS_INFO_FIRST + 1; type < ELM_ACCESS_INFO_LAST; type++)
263 txt = _elm_access_text_get(ac, type, obj);
264 if (txt && (strlen(txt) > 0))
266 if (eina_strbuf_length_get(strbuf) > 0)
267 eina_strbuf_append_printf(strbuf, ", %s", txt);
269 eina_strbuf_append(strbuf, txt);
275 txt = eina_strbuf_string_steal(strbuf);
276 eina_strbuf_free(strbuf);
278 _elm_access_say(txt);
283 _access_obj_over_timeout_cb(void *data)
288 if (!data) return EINA_FALSE;
290 ac = evas_object_data_get(data, "_elm_access");
291 if (!ac) return EINA_FALSE;
293 ho = _access_highlight_object_get(data);
294 if (ho != data) _access_highlight_read(ac, data);
296 ac->delay_timer = NULL;
301 _access_hover_mouse_in_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
304 if (!mouse_event_enable) return;
306 ac = evas_object_data_get(data, "_elm_access");
309 ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
311 if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
312 ac->delay_timer = ecore_timer_add(0.2, _access_obj_over_timeout_cb, data);
316 _access_hover_mouse_out_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
319 if (!mouse_event_enable) return;
321 ac = evas_object_data_get(data, "_elm_access");
324 _elm_access_object_unhighlight(data);
326 ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
330 _access_read_done(void *data EINA_UNUSED)
333 // FIXME: produce event here
337 _access_2nd_click_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
341 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
342 _access_2nd_click_del_cb, NULL);
343 t = evas_object_data_get(obj, "_elm_2nd_timeout");
347 evas_object_data_del(obj, "_elm_2nd_timeout");
352 _access_2nd_click_timeout_cb(void *data)
354 evas_object_event_callback_del_full(data, EVAS_CALLBACK_DEL,
355 _access_2nd_click_del_cb, NULL);
356 evas_object_data_del(data, "_elm_2nd_timeout");
361 _access_obj_hilight_del_cb(void *data EINA_UNUSED, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
363 _elm_access_object_highlight_disable(e);
367 _access_obj_hilight_hide_cb(void *data EINA_UNUSED, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
369 _elm_access_object_highlight_disable(e);
373 _access_obj_hilight_move_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
378 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
380 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
381 evas_object_move(o, x, y);
385 _access_obj_hilight_resize_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
390 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
392 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
393 evas_object_resize(o, w, h);
397 _elm_access_mouse_event_enabled_set(Eina_Bool enabled)
400 if (mouse_event_enable == enabled) return;
401 mouse_event_enable = enabled;
405 _elm_access_auto_highlight_set(Eina_Bool enabled)
408 if (auto_highlight == enabled) return;
409 auto_highlight = enabled;
413 _elm_access_auto_highlight_get(void)
415 return auto_highlight;
419 _elm_access_shutdown()
425 _access_order_del_cb(void *data,
428 void *event_info EINA_UNUSED)
430 Elm_Widget_Item_Data *item = data;
432 item->access_order = eina_list_remove(item->access_order, obj);
436 _elm_access_widget_item_access_order_set(Elm_Widget_Item_Data *item,
444 _elm_access_widget_item_access_order_unset(item);
446 EINA_LIST_FOREACH(objs, l, o)
448 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
449 _access_order_del_cb, item);
452 item->access_order = objs;
456 _elm_access_widget_item_access_order_get(const Elm_Widget_Item_Data *item)
458 if (!item) return NULL;
459 return item->access_order;
463 _elm_access_widget_item_access_order_unset(Elm_Widget_Item_Data *item)
465 Eina_List *l, *l_next;
470 EINA_LIST_FOREACH_SAFE(item->access_order, l, l_next, o)
472 evas_object_event_callback_del_full
473 (o, EVAS_CALLBACK_DEL, _access_order_del_cb, item);
474 item->access_order = eina_list_remove_list(item->access_order, l);
479 _access_highlight_next_get(Evas_Object *obj, Elm_Focus_Direction dir)
482 Evas_Object *ho, *parent, *target;
488 if (!elm_widget_is(obj)) return ret;
490 ho = _access_highlight_object_get(obj);
495 /* find highlight root */
498 ELM_WIDGET_DATA_GET_OR_RETURN(parent, wd, ret);
499 if (wd->highlight_root)
501 /* change highlight root */
505 parent = elm_widget_parent_get(parent);
509 _elm_access_auto_highlight_set(EINA_TRUE);
511 if (dir == ELM_FOCUS_NEXT)
512 type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
514 type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
516 /* this value is used in _elm_access_object_highlight();
517 to inform the target object of how to get highlight */
520 if (!_access_action_callback_call(ho, type, NULL))
524 Elm_Access_Info *info = _elm_access_info_get(ho);
525 if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT && info->next)
527 else if (type == ELM_ACCESS_ACTION_HIGHLIGHT_PREV && info->prev)
533 _elm_access_highlight_set(target);
534 elm_widget_focus_region_show(target);
539 ret = elm_widget_focus_next_get(obj, dir, &target, NULL);
541 _elm_access_highlight_set(target);
545 action_by = ELM_ACCESS_ACTION_FIRST;
547 _elm_access_auto_highlight_set(EINA_FALSE);
552 //-------------------------------------------------------------------------//
554 _elm_access_highlight_set(Evas_Object* obj)
561 ho = _access_highlight_object_get(obj);
562 if (ho == obj) return;
564 ac = evas_object_data_get(obj, "_elm_access");
567 _access_highlight_read(ac, obj);
571 _elm_access_clear(Elm_Access_Info *ac)
576 ELM_SAFE_FREE(ac->delay_timer, ecore_timer_del);
577 EINA_LIST_FREE(ac->items, ai)
581 eina_stringshare_del(ai->data);
588 _elm_access_text_set(Elm_Access_Info *ac, int type, const char *text)
590 Elm_Access_Item *ai = _access_add_set(ac, type);
593 ai->data = eina_stringshare_add(text);
597 _elm_access_callback_set(Elm_Access_Info *ac, int type, Elm_Access_Info_Cb func, const void *data)
599 Elm_Access_Item *ai = _access_add_set(ac, type);
606 _elm_access_on_highlight_hook_set(Elm_Access_Info *ac,
607 Elm_Access_On_Highlight_Cb func,
611 ac->on_highlight = func;
612 ac->on_highlight_data = data;
616 _elm_access_activate_callback_set(Elm_Access_Info *ac,
617 Elm_Access_Activate_Cb func,
622 ac->activate_data = data;
626 _elm_access_highlight_object_activate(Evas_Object *obj, Elm_Activate act)
628 Evas_Object *highlight;
630 highlight = _access_highlight_object_get(obj);
631 if (!highlight) return;
633 _elm_access_auto_highlight_set(EINA_FALSE);
635 if (!elm_object_focus_get(highlight))
636 elm_object_focus_set(highlight, EINA_TRUE);
638 elm_widget_activate(highlight, act);
643 _elm_access_highlight_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
646 Evas_Object *ho, *parent;
648 ho = _access_highlight_object_get(obj);
653 /* find highlight root */
656 ELM_WIDGET_DATA_GET_OR_RETURN(parent, wd);
657 if (wd->highlight_root)
659 /* change highlight root */
663 parent = elm_widget_parent_get(parent);
667 _elm_access_auto_highlight_set(EINA_TRUE);
669 if (dir == ELM_FOCUS_NEXT)
670 type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
672 type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
676 if (!_access_action_callback_call(ho, type, NULL))
678 Elm_Access_Info *info = _elm_access_info_get(ho);
679 Evas_Object *comming = NULL;
680 if (type == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT)
682 if ((info) && (info->next)) comming = info->next;
686 if ((info) && (info->prev)) comming = info->prev;
690 _elm_access_highlight_set(comming);
691 elm_widget_focus_region_show(comming);
694 elm_widget_focus_cycle(obj, dir);
697 action_by = ELM_ACCESS_ACTION_FIRST;
699 _elm_access_auto_highlight_set(EINA_FALSE);
703 _elm_access_text_get(const Elm_Access_Info *ac, int type, const Evas_Object *obj)
708 if (!ac) return NULL;
709 EINA_LIST_FOREACH(ac->items, l, ai)
711 if (ai->type == type)
713 if (ai->func) return ai->func((void *)(ai->data), (Evas_Object *)obj);
714 else if (ai->data) return strdup(ai->data);
722 _elm_access_read(Elm_Access_Info *ac, int type, const Evas_Object *obj)
724 char *txt = _elm_access_text_get(ac, type, obj);
729 if (mapi->out_done_callback_set)
730 mapi->out_done_callback_set(_access_read_done, NULL);
731 if (type == ELM_ACCESS_DONE)
733 if (mapi->out_read_done) mapi->out_read_done();
735 else if (type == ELM_ACCESS_CANCEL)
737 if (mapi->out_cancel) mapi->out_cancel();
743 if (mapi->out_read) mapi->out_read(txt);
744 if (mapi->out_read) mapi->out_read(".\n");
752 _elm_access_say(const char *txt)
754 if (!_elm_config->access_mode) return;
759 if (mapi->out_done_callback_set)
760 mapi->out_done_callback_set(_access_read_done, NULL);
761 if (mapi->out_cancel) mapi->out_cancel();
764 if (mapi->out_read) mapi->out_read(txt);
765 if (mapi->out_read) mapi->out_read(".\n");
767 if (mapi->out_read_done) mapi->out_read_done();
771 EAPI Elm_Access_Info *
772 _elm_access_info_get(const Evas_Object *obj)
774 return evas_object_data_get(obj, "_elm_access");
777 EAPI Elm_Access_Info *
778 _elm_access_object_get(const Evas_Object *obj)
780 return _elm_access_info_get(obj);
784 _elm_access_widget_target_get(Evas_Object *obj)
786 Evas_Object *o = obj;
790 if (elm_widget_is(o))
794 o = elm_widget_parent_widget_get(o);
796 o = evas_object_smart_parent_get(o);
805 _elm_access_object_highlight(Evas_Object *obj)
807 Evas_Object *o, *widget;
808 Evas_Coord x, y, w, h;
809 Eina_Bool in_theme = EINA_FALSE;
811 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
814 o = edje_object_add(evas_object_evas_get(obj));
815 evas_object_name_set(o, "_elm_access_disp");
816 evas_object_layer_set(o, ELM_OBJECT_LAYER_TOOLTIP);
820 Evas_Object *ptarget = evas_object_data_get(o, "_elm_access_target");
823 evas_object_data_del(o, "_elm_access_target");
824 elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
826 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_DEL,
827 _access_obj_hilight_del_cb, NULL);
828 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_HIDE,
829 _access_obj_hilight_hide_cb, NULL);
830 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_MOVE,
831 _access_obj_hilight_move_cb, NULL);
832 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
833 _access_obj_hilight_resize_cb, NULL);
835 widget = _elm_access_widget_target_get(ptarget);
838 if (elm_widget_access_highlight_in_theme_get(widget))
840 elm_widget_signal_emit(widget, "elm,action,access_highlight,hide", "elm");
845 evas_object_data_set(o, "_elm_access_target", obj);
846 elm_widget_parent_highlight_set(obj, EINA_TRUE);
848 elm_widget_theme_object_set(obj, o, "access", "base", "default");
850 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
851 _access_obj_hilight_del_cb, NULL);
852 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
853 _access_obj_hilight_hide_cb, NULL);
854 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
855 _access_obj_hilight_move_cb, NULL);
856 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
857 _access_obj_hilight_resize_cb, NULL);
858 evas_object_raise(o);
859 evas_object_geometry_get(obj, &x, &y, &w, &h);
860 evas_object_move(o, x, y);
861 evas_object_resize(o, w, h);
863 widget = _elm_access_widget_target_get(obj);
866 if (elm_widget_access_highlight_in_theme_get(widget))
868 in_theme = EINA_TRUE;
869 elm_widget_signal_emit(widget, "elm,action,access_highlight,show", "elm");
872 /* use callback, should an access object do below every time when
873 * a window gets a client message ECORE_X_ATOM_E_ILLMUE_ACTION_READ? */
875 !_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL))
882 _elm_access_object_unhighlight(Evas_Object *obj)
884 Evas_Object *o, *ptarget;
886 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
888 ptarget = evas_object_data_get(o, "_elm_access_target");
891 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_DEL,
892 _access_obj_hilight_del_cb, NULL);
893 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_HIDE,
894 _access_obj_hilight_hide_cb, NULL);
895 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_MOVE,
896 _access_obj_hilight_move_cb, NULL);
897 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
898 _access_obj_hilight_resize_cb, NULL);
900 elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
905 _content_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
906 void *event_info EINA_UNUSED)
908 Evas_Object *accessobj;
912 if (!accessobj) return;
914 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
915 evas_object_resize(accessobj, w, h);
919 _content_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
920 void *event_info EINA_UNUSED)
922 Evas_Object *accessobj;
926 if (!accessobj) return;
928 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
929 evas_object_move(accessobj, x, y);
933 _access_object_register(Evas_Object *obj, Evas_Object *parent)
937 Evas_Coord x, y, w, h;
939 if (!obj) return NULL;
941 /* check previous access object */
942 ao = evas_object_data_get(obj, "_part_access_obj");
944 _access_object_unregister(obj);
946 /* create access object */
947 ao = _elm_access_add(parent);
948 if (!ao) return NULL;
950 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
951 _content_resize, ao);
952 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
955 evas_object_geometry_get(obj, &x, &y, &w, &h);
956 evas_object_move(ao, x, y);
957 evas_object_resize(ao, w, h);
958 evas_object_show(ao);
960 /* register access object */
961 _elm_access_object_register(ao, obj);
963 /* set access object */
964 evas_object_data_set(obj, "_part_access_obj", ao);
966 /* set owner part object */
967 ac = evas_object_data_get(ao, "_elm_access");
968 ac->part_object = obj;
970 /* set access object layer to max, because the highlight
971 frame could be covered by other object which has higher layer */
972 evas_object_layer_set(ao, EVAS_LAYER_MAX);
978 _access_object_unregister(Evas_Object *obj)
985 ao = evas_object_data_get(obj, "_part_access_obj");
989 /* delete callbacks and unregister access object in _access_obj_del_cb*/
994 /* button, check, label etc. */
995 ac = evas_object_data_get(obj, "_elm_access");
996 if (ac && ac->hoverobj)
997 _elm_access_object_unregister(obj, ac->hoverobj);
1002 _elm_access_edje_object_part_object_register(Evas_Object* obj,
1003 const Evas_Object *eobj,
1006 Evas_Object *ao, *po;
1008 po = (Evas_Object *)edje_object_part_object_get(eobj, part);
1009 if (!obj || !po) return NULL;
1011 /* check previous access object */
1012 ao = evas_object_data_get(po, "_part_access_obj");
1014 _elm_access_edje_object_part_object_unregister(obj, eobj, part);
1016 ao = _access_object_register(po, obj);
1021 //FIXME: unused obj should be removed from here and each widget.
1023 _elm_access_edje_object_part_object_unregister(Evas_Object* obj EINA_UNUSED,
1024 const Evas_Object *eobj,
1029 po = (Evas_Object *)edje_object_part_object_get(eobj, part);
1032 _access_object_unregister(po);
1036 _elm_access_object_highlight_disable(Evas *e)
1038 Evas_Object *o, *ptarget;
1040 o = evas_object_name_find(e, "_elm_access_disp");
1042 ptarget = evas_object_data_get(o, "_elm_access_target");
1045 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_DEL,
1046 _access_obj_hilight_del_cb, NULL);
1047 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_HIDE,
1048 _access_obj_hilight_hide_cb, NULL);
1049 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_MOVE,
1050 _access_obj_hilight_move_cb, NULL);
1051 evas_object_event_callback_del_full(ptarget, EVAS_CALLBACK_RESIZE,
1052 _access_obj_hilight_resize_cb, NULL);
1055 elm_widget_parent_highlight_set(ptarget, EINA_FALSE);
1059 _access_obj_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1062 Ecore_Job *ao_del_job = NULL;
1064 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _access_obj_del_cb);
1066 if (data) /* hover object */
1068 evas_object_event_callback_del_full(data, EVAS_CALLBACK_RESIZE,
1069 _content_resize, obj);
1070 evas_object_event_callback_del_full(data, EVAS_CALLBACK_MOVE,
1071 _content_move, obj);
1073 _elm_access_object_unregister(obj, data);
1076 ao_del_job = evas_object_data_get(obj, "_access_obj_del_job");
1080 ecore_job_del(ao_del_job);
1081 evas_object_data_del(obj, "_access_obj_del_job");
1086 _access_obj_del_job(void *data)
1090 evas_object_data_del(data, "_access_obj_del_job");
1092 evas_object_event_callback_del(data, EVAS_CALLBACK_DEL, _access_obj_del_cb);
1093 evas_object_del(data);
1097 _access_hover_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
1099 Ecore_Job *ao_del_job = NULL;
1101 /* data - access object - could be NULL */
1104 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
1105 _content_resize, data);
1106 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
1107 _content_move, data);
1109 _elm_access_object_unregister(data, obj);
1111 /* delete access object in job */
1112 ao_del_job = evas_object_data_get(data, "_access_obj_del_job");
1115 ecore_job_del(ao_del_job);
1116 evas_object_data_del(data, "_access_obj_del_job");
1119 ao_del_job = ecore_job_add(_access_obj_del_job, data);
1120 evas_object_data_set(data, "_access_obj_del_job", ao_del_job);
1124 _elm_access_object_register(Evas_Object *obj, Evas_Object *hoverobj)
1126 Elm_Access_Info *ac;
1128 evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOUSE_IN,
1129 _access_hover_mouse_in_cb, obj);
1130 evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_MOUSE_OUT,
1131 _access_hover_mouse_out_cb, obj);
1132 evas_object_event_callback_add(hoverobj, EVAS_CALLBACK_DEL,
1133 _access_hover_del_cb, obj);
1135 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
1136 _access_obj_del_cb, hoverobj);
1138 ac = calloc(1, sizeof(Elm_Access_Info));
1139 evas_object_data_set(obj, "_elm_access", ac);
1141 ac->hoverobj = hoverobj;
1145 _elm_access_object_unregister(Evas_Object *obj, Evas_Object *hoverobj)
1147 Elm_Access_Info *ac;
1150 evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOUSE_IN,
1151 _access_hover_mouse_in_cb, obj);
1152 evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_MOUSE_OUT,
1153 _access_hover_mouse_out_cb, obj);
1154 evas_object_event_callback_del_full(hoverobj, EVAS_CALLBACK_DEL,
1155 _access_hover_del_cb, obj);
1157 /* _access_obj_del_cb and _access_hover_del_cb calls this function,
1158 both do not need _part_access_obj data, so delete the data here. */
1159 ao = evas_object_data_get(hoverobj, "_part_access_obj");
1160 if (ao) evas_object_data_del(hoverobj, "_part_access_obj");
1162 ac = evas_object_data_get(obj, "_elm_access");
1163 evas_object_data_del(obj, "_elm_access");
1166 /* widget could delete VIEW(it) only and register item again,
1167 in this case _elm_access_widget_item_register could try to delete
1168 access object again in _elm_access_widget_item_unregister */
1169 if (ac->widget_item) ac->widget_item->access_obj = NULL;
1171 _elm_access_clear(ac);
1176 a = evas_object_data_get(obj, "_elm_access_action_info");
1177 evas_object_data_del(obj, "_elm_access_action_info");
1182 _elm_access_widget_item_register(Elm_Widget_Item_Data *item)
1184 Evas_Object *ao, *ho;
1185 Evas_Coord x, y, w, h;
1186 Elm_Access_Info *ac;
1188 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
1190 /* check previous access object */
1191 if (item->access_obj)
1192 _elm_access_widget_item_unregister(item);
1194 // create access object
1196 ao = _elm_access_add(item->widget);
1199 evas_object_event_callback_add(ho, EVAS_CALLBACK_RESIZE,
1200 _content_resize, ao);
1201 evas_object_event_callback_add(ho, EVAS_CALLBACK_MOVE,
1204 evas_object_geometry_get(ho, &x, &y, &w, &h);
1205 evas_object_move(ao, x, y);
1206 evas_object_resize(ao, w, h);
1207 evas_object_show(ao);
1209 // register access object
1210 _elm_access_object_register(ao, ho);
1212 item->access_obj = ao;
1214 /* set owner widget item */
1215 ac = evas_object_data_get(ao, "_elm_access");
1216 ac->widget_item = item;
1220 _elm_access_widget_item_unregister(Elm_Widget_Item_Data *item)
1224 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
1226 if (!item->access_obj) return;
1228 /* delete callbacks and unregister access object in _access_obj_del_cb*/
1229 ao = item->access_obj;
1230 item->access_obj = NULL;
1232 evas_object_del(ao);
1236 _elm_access_2nd_click_timeout(Evas_Object *obj)
1240 t = evas_object_data_get(obj, "_elm_2nd_timeout");
1244 evas_object_data_del(obj, "_elm_2nd_timeout");
1245 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
1246 _access_2nd_click_del_cb, NULL);
1249 t = ecore_timer_add(0.3, _access_2nd_click_timeout_cb, obj);
1250 evas_object_data_set(obj, "_elm_2nd_timeout", t);
1251 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
1252 _access_2nd_click_del_cb, NULL);
1256 static Evas_Object *
1257 _elm_access_add(Evas_Object *parent)
1259 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1260 Evas_Object *obj = eo_add(MY_CLASS, parent);
1265 _elm_access_eo_base_constructor(Eo *obj, void *_pd EINA_UNUSED)
1267 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
1269 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
1270 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
1276 elm_access_object_register(Evas_Object *obj, Evas_Object *parent)
1278 return _access_object_register(obj, parent);
1282 elm_access_object_unregister(Evas_Object *obj)
1284 _access_object_unregister(obj);
1288 elm_access_object_get(const Evas_Object *obj)
1290 return evas_object_data_get(obj, "_part_access_obj");
1294 elm_access_info_set(Evas_Object *obj, int type, const char *text)
1296 _elm_access_text_set(_elm_access_info_get(obj), type, text);
1300 elm_access_info_get(const Evas_Object *obj, int type)
1302 return _elm_access_text_get(_elm_access_info_get(obj), type, obj);
1306 elm_access_info_cb_set(Evas_Object *obj, int type,
1307 Elm_Access_Info_Cb func, const void *data)
1309 _elm_access_callback_set(_elm_access_info_get(obj), type, func, data);
1313 elm_access_activate_cb_set(Evas_Object *obj,
1314 Elm_Access_Activate_Cb func, void *data)
1316 Elm_Access_Info *ac;
1318 ac = _elm_access_info_get(obj);
1321 ac->activate = func;
1322 ac->activate_data = data;
1326 elm_access_say(const char *text)
1330 _elm_access_say(text);
1334 elm_access_highlight_set(Evas_Object* obj)
1336 _elm_access_highlight_set(obj);
1340 elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, Elm_Access_Action_Info *action_info)
1344 Elm_Access_Action_Info *a = action_info;
1348 case ELM_ACCESS_ACTION_READ:
1349 case ELM_ACCESS_ACTION_HIGHLIGHT:
1350 evas = evas_object_evas_get(obj);
1351 if (!evas) return EINA_FALSE;
1353 evas_event_feed_mouse_in(evas, 0, NULL);
1355 _elm_access_mouse_event_enabled_set(EINA_TRUE);
1356 evas_event_feed_mouse_move(evas, a->x, a->y, 0, NULL);
1357 _elm_access_mouse_event_enabled_set(EINA_FALSE);
1359 ho = _access_highlight_object_get(obj);
1361 _access_action_callback_call(ho, ELM_ACCESS_ACTION_READ, a);
1364 case ELM_ACCESS_ACTION_UNHIGHLIGHT:
1365 evas = evas_object_evas_get(obj);
1366 if (!evas) return EINA_FALSE;
1367 _elm_access_object_highlight_disable(evas);
1370 case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
1371 if (a->highlight_cycle)
1372 _elm_access_highlight_cycle(obj, ELM_FOCUS_NEXT);
1374 return _access_highlight_next_get(obj, ELM_FOCUS_NEXT);
1377 case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
1378 if (a->highlight_cycle)
1379 _elm_access_highlight_cycle(obj, ELM_FOCUS_PREVIOUS);
1381 return _access_highlight_next_get(obj, ELM_FOCUS_PREVIOUS);
1384 case ELM_ACCESS_ACTION_ACTIVATE:
1385 _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DEFAULT);
1388 case ELM_ACCESS_ACTION_UP:
1389 _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_UP);
1392 case ELM_ACCESS_ACTION_DOWN:
1393 _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DOWN);
1396 case ELM_ACCESS_ACTION_SCROLL:
1397 //TODO: SCROLL HIGHLIGHT OBJECT
1400 case ELM_ACCESS_ACTION_BACK:
1411 elm_access_action_cb_set(Evas_Object *obj, const Elm_Access_Action_Type type, const Elm_Access_Action_Cb cb, const void *data)
1414 a = evas_object_data_get(obj, "_elm_access_action_info");
1418 a = calloc(1, sizeof(Action_Info));
1419 evas_object_data_set(obj, "_elm_access_action_info", a);
1423 a->fn[type].cb = cb;
1424 a->fn[type].user_data = (void *)data;
1427 elm_access_external_info_set(Evas_Object *obj, const char *text)
1429 _elm_access_text_set
1430 (_elm_access_info_get(obj), ELM_ACCESS_CONTEXT_INFO, text);
1434 elm_access_external_info_get(const Evas_Object *obj)
1436 Elm_Access_Info *ac;
1438 ac = _elm_access_info_get(obj);
1439 return _elm_access_text_get(ac, ELM_ACCESS_CONTEXT_INFO, obj);
1443 elm_access_highlight_next_set(Evas_Object *obj, Elm_Highlight_Direction dir, Evas_Object *next)
1445 EINA_SAFETY_ON_FALSE_RETURN(obj);
1446 EINA_SAFETY_ON_FALSE_RETURN(next);
1448 Elm_Access_Info *info = _elm_access_info_get(obj);
1449 Elm_Access_Info *info_next = _elm_access_info_get(next);
1451 if (!info || !info_next)
1453 ERR("There is no access information");
1457 if (dir == ELM_HIGHLIGHT_DIR_NEXT)
1459 info_next->prev = obj;
1462 else if (dir == ELM_HIGHLIGHT_DIR_PREVIOUS)
1464 info_next->next = obj;
1468 ERR("Not supported focus direction for access highlight [%d]", dir);
1472 _elm_access_class_constructor(Eo_Class *klass)
1474 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1477 EOLIAN static const char*
1478 _elm_access_elm_interface_atspi_accessible_name_get(Eo *obj, void *pd EINA_UNUSED)
1480 char *accessible_name;
1481 //TIZEN_ONLY(20160919): make access object work with elm_interface_atspi_accessible_name,description_set
1482 const char *ret = NULL;
1483 eo_do_super(obj, ELM_ACCESS_CLASS, ret = elm_interface_atspi_accessible_name_get());
1484 if (ret) return ret;
1487 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1489 accessible_name = elm_access_info_get(obj, ELM_ACCESS_INFO);
1490 eina_stringshare_del(wd->accessible_name);
1491 wd->accessible_name = eina_stringshare_add(accessible_name);
1492 free(accessible_name);
1493 return wd->accessible_name;
1496 EOLIAN static const char*
1497 _elm_access_elm_interface_atspi_accessible_description_get(Eo *obj, void *pd EINA_UNUSED)
1499 //TIZEN_ONLY(20160919): make access object work with elm_interface_atspi_accessible_name,description_set
1500 const char *ret = NULL;
1501 eo_do_super(obj, ELM_ACCESS_CLASS, ret = elm_interface_atspi_accessible_description_get());
1502 if (ret) return ret;
1504 return elm_access_info_get(obj, ELM_ACCESS_CONTEXT_INFO);
1507 EOLIAN static Elm_Atspi_State_Set
1508 _elm_access_elm_interface_atspi_accessible_state_set_get(Eo *obj, void *pd EINA_UNUSED)
1510 Elm_Atspi_State_Set ret;
1511 eo_do_super(obj, ELM_ACCESS_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
1513 Elm_Access_Info *info = _elm_access_info_get(obj);
1514 if (info && !evas_object_visible_get(info->part_object))
1516 STATE_TYPE_UNSET(ret, ELM_ATSPI_STATE_VISIBLE);
1517 STATE_TYPE_UNSET(ret, ELM_ATSPI_STATE_SHOWING);
1523 EOLIAN static Eina_Bool
1524 _elm_access_elm_interface_atspi_component_highlight_grab(Eo *obj, void *pd EINA_UNUSED)
1526 if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL))
1527 eo_do_super(obj, ELM_ACCESS_CLASS, elm_interface_atspi_component_highlight_grab());
1529 // TIZEN_ONLY(20160708) - support elm_access used for embedded toolkit
1530 action_by = ELM_ACCESS_ACTION_FIRST;
1533 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
1534 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
1539 EOLIAN static Eina_Bool
1540 _elm_access_elm_interface_atspi_component_highlight_clear(Eo *obj, void *pd EINA_UNUSED)
1542 if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL))
1543 eo_do_super(obj, ELM_ACCESS_CLASS, elm_interface_atspi_component_highlight_clear());
1545 // TIZEN_ONLY(20160708) - support elm_access used for embedded toolkit
1546 action_by = ELM_ACCESS_ACTION_FIRST;
1549 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
1550 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
1556 _access_atspi_action_do(Evas_Object *obj, const char *params)
1561 if (!strcmp(params, "highlight"))
1562 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL);
1563 else if (!strcmp(params, "unhighlight"))
1564 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_UNHIGHLIGHT, NULL);
1565 // TIZEN_ONLY(20160708) - support elm_access used for embedded toolkit
1566 else if (!strcmp(params, "highlight,first"))
1567 action_by = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
1568 else if (!strcmp(params, "highlight,last"))
1569 action_by = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
1571 else if (!strcmp(params, "highlight,next"))
1572 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, NULL);
1573 else if (!strcmp(params, "highlight,prev"))
1574 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, NULL);
1575 else if (!strcmp(params, "activate"))
1577 evas_object_smart_callback_call(obj, SIG_ACTIVATED, NULL);
1578 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_ACTIVATE, NULL);
1580 else if (!strcmp(params, "value,up"))
1581 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_UP, NULL);
1582 else if (!strcmp(params, "value,down"))
1583 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_DOWN, NULL);
1584 else if (!strcmp(params, "read"))
1585 ret = _access_action_callback_call(obj, ELM_ACCESS_ACTION_READ, NULL);
1590 EOLIAN const Elm_Atspi_Action *
1591 _elm_access_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED)
1593 static Elm_Atspi_Action atspi_actions[] = {
1594 { "highlight", NULL, "highlight", _access_atspi_action_do},
1595 { "unhighlight", NULL, "unhighlight", _access_atspi_action_do},
1596 // TIZEN_ONLY(20160708) - support elm_access used for embedded toolkit
1597 { "highlight,first", NULL, "highlight,first", _access_atspi_action_do},
1598 { "highlight,last", NULL, "highlight,last", _access_atspi_action_do},
1600 { "highlight,next", NULL, "highlight,next", _access_atspi_action_do},
1601 { "highlight,prev", NULL, "highlight,prev", _access_atspi_action_do},
1602 { "activate", NULL, "activate", _access_atspi_action_do},
1603 { "value,up", NULL, "value,up", _access_atspi_action_do},
1604 { "value,down", NULL, "value,down", _access_atspi_action_do},
1605 { "read", NULL, "read", _access_atspi_action_do},
1606 { NULL, NULL, NULL, NULL }
1608 return &atspi_actions[0];
1611 #include "elm_access.eo.c"