ACCESSIBLE_INFO_STATE = 1 << 3
};
+/* The Highlight_Type will be used for access object working for embedded
+toolkit such as Dali does not support at-spi interface. This kind of work
+will make screen-reader be slow. They have to implement the interface */
+typedef enum {
+ HIGHLIGHT_POINT,
+ HIGHLIGHT_FIRST,
+ HIGHLIGHT_LAST,
+ HIGHLIGHT_NEXT,
+ HIGHLIGHT_PREV
+} Highlight_Type;
+
static last_focus_t gesture_start_p = { -1, -1 };
static last_focus_t last_focus = { -1, -1 };
static last_focus_t last_pos = { -1, -1 };
return strdup(ret);
}
-static void _current_highlight_object_set(AtspiAccessible * obj)
+static Eina_Bool _do_action(AtspiAccessible *obj, char *expected_action)
+{
+ AtspiAction *action;
+ GError *err = NULL;
+ gint i = 0;
+ gint number_of_action = 0;
+ gchar *action_name = NULL;
+ Eina_Bool action_found = EINA_FALSE;
+ Eina_Bool ret = EINA_FALSE;
+
+ action = atspi_accessible_get_action_iface(obj);
+ if (action) {
+ number_of_action = atspi_action_get_n_actions(action, &err);
+ GERROR_CHECK(err)
+
+ while (i < number_of_action && !action_found) {
+ action_name = atspi_action_get_name(action, i, &err);
+ GERROR_CHECK(err)
+
+ if (action_name && !strcmp(expected_action, action_name)) {
+ DEBUG("Expected action %s (index: %d) found!", expected_action, i);
+ action_found = EINA_TRUE;
+ } else {
+ i++;
+ }
+ g_free(action_name);
+ }
+
+ if (action_found) {
+ ret = atspi_action_do_action(action, i, &err);
+ GERROR_CHECK(err)
+ }
+ g_object_unref(action);
+ }
+
+ if (!action_found)
+ ERROR("Cannot find expected action %s", expected_action);
+
+ return ret;
+}
+
+/* This function will set highlight information such as how an object gets highlight,
+HIGHLIGHT_FIRST means the highlight moves from previous highlighted object,
+adn HIGHLIGHT_LAST means the highlight moves from next highlighted object. */
+static void _highlight_type_set(AtspiAccessible *obj, Highlight_Type h_type)
+{
+ char *expected_action = NULL;
+
+ /* elm_access must have action 'highlight,first', and 'highlight,last' */
+ switch (h_type) {
+ case HIGHLIGHT_FIRST:
+ expected_action = "highlight,first";
+ break;
+ case HIGHLIGHT_LAST:
+ expected_action = "highlight,last";
+ break;
+ default:
+ ERROR("Not supported highlight type");
+ return;
+ }
+
+ _do_action(obj, expected_action);
+}
+
+static Eina_Bool _highlight_access_object(AtspiAccessible *obj, Highlight_Type h_type)
+{
+ char *expected_action = NULL;
+
+ /* elm_access must have action 'highlight,next', and 'highlight,prev' */
+ switch (h_type) {
+ case HIGHLIGHT_NEXT:
+ expected_action = "highlight,next";
+ break;
+ case HIGHLIGHT_PREV:
+ expected_action = "highlight,prev";
+ break;
+ default:
+ ERROR("Not supported highlight type");
+ return EINA_FALSE;
+ }
+
+ return _do_action(obj, expected_action);
+}
+
+static void _current_highlight_object_set(AtspiAccessible * obj, Highlight_Type h_type)
{
DEBUG("START");
GError *err = NULL;
role = atspi_accessible_get_role(obj, NULL);
if (role != ATSPI_ROLE_PAGE_TAB && role != ATSPI_ROLE_POPUP_MENU) { /* ctxpopup outline does not show highlight frame */
+ if (role == ATSPI_ROLE_UNKNOWN) {
+ /* to support elm_access used for embedded toolkit,
+ probably have to check more such as attribute 'type',
+ because there could be other ATSPI_ROLE_UNKNOWN. */
+ _highlight_type_set(obj, h_type);
+ }
atspi_component_grab_highlight(comp, &err);
}
current_comp = comp;
if (flat_navi_context_current_at_x_y_set(context, info->x_beg, info->y_beg, &obj)) {
last_focus.x = info->x_beg;
last_focus.y = info->y_beg;
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_POINT);
}
DEBUG("END");
obj = flat_navi_context_next(context);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
else
DEBUG("Next widget not found. Abort");
DEBUG("END");
while (obj && !visible);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
else
DEBUG("Next widget not found. Abort");
DEBUG("END");
while (obj && !visible);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_LAST);
else
DEBUG("Previous widget not found. Abort");
}
obj = flat_navi_context_prev(context);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_LAST);
else
DEBUG("Previous widget not found. Abort");
}
s_auto_review.auto_review_on = false;
}
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
DEBUG("END");
}
AtspiAccessible *first = flat_navi_context_first(context);
if (first != obj) {
- _current_highlight_object_set(first);
+ _current_highlight_object_set(first, HIGHLIGHT_FIRST);
} else {
text_to_speak = generate_what_to_read(obj);
DEBUG("Text to speak: %s", text_to_speak);
if (flat_navi_context_current_set(context, obj)) {
DEBUG("current obj set");
}
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
}
g_object_unref(parent);
g_object_unref(current);
if (flat_navi_context_current_set(context, obj)) {
DEBUG("current obj set");
}
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_LAST);
}
g_object_unref(parent);
g_object_unref(current);
}
AtspiAccessible *obj = flat_navi_context_first(context);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
else
DEBUG("First widget not found. Abort");
DEBUG("END");
}
AtspiAccessible *obj = flat_navi_context_last(context);
if (obj)
- _current_highlight_object_set(obj);
+ _current_highlight_object_set(obj, HIGHLIGHT_LAST);
else
DEBUG("Last widget not found. Abort");
DEBUG("END");
atspi_action_do_action(action, action_index, NULL);
}
+static Eina_Bool _check_access_object_internal(Highlight_Type h_type)
+{
+ AtspiRole role;
+ AtspiAccessible *obj;
+ GError *err = NULL;
+
+ if (!context) {
+ ERROR("No navigation context created");
+ return EINA_FALSE;
+ }
+
+ obj = flat_navi_context_current_get(context);
+ if (!obj) return EINA_FALSE;
+
+ role = atspi_accessible_get_role(obj, &err);
+ GERROR_CHECK(err)
+
+ if (role == ATSPI_ROLE_UNKNOWN) {
+ /* to support elm_access used for embedded toolkit,
+ probably have to check more such as attribute 'type',
+ because there could be other ATSPI_ROLE_UNKNOWN. */
+ return _highlight_access_object(obj, h_type);
+ }
+
+ return EINA_FALSE;
+}
+
static void on_gesture_detected(void *data, const Eldbus_Message *msg)
{
#ifdef X11_ENABLED
_widget_scroll(info);
break;
case ONE_FINGER_FLICK_LEFT:
+ if (_check_access_object_internal(HIGHLIGHT_PREV)) break;
_focus_prev();
if (_is_index_item())
_activate_widget();
break;
case ONE_FINGER_FLICK_RIGHT:
+ if (_check_access_object_internal(HIGHLIGHT_NEXT)) break;
_focus_next();
if (_is_index_item())
_activate_widget();
if(role == ATSPI_ROLE_PAGE_TAB || //add more roles...
role == ATSPI_ROLE_PAGE_TAB_LIST)
{
- _current_highlight_object_set(flat_navi_context_current_get(context));
+ _current_highlight_object_set(flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
}
else
{
break;
case ATSPI_ROLE_POPUP_MENU:
case ATSPI_ROLE_DIALOG :
- _current_highlight_object_set(flat_navi_context_current_get(context));
+ _current_highlight_object_set(flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
break;
default :
break;